System freeze issues on LTE

hello.

I’m working on an arduino mkr nb 1500 to monitor sensor data on platform.io.

I modified the code as per your help yesterday and have been testing it for a day or so, but the arduino freezes after about 10-30 minutes.

The code is shown below.
We’ve temporarily removed the blynk-specific #define.

#include <Arduino.h>

#include <Wire.h> // I2C 통신과 관련된 라이브러리

// Blynk 장치 ID

#define DEVICE_ID 2

// Blynk 설정

#define BLYNK_TEMPLATE_ID "="

#define BLYNK_TEMPLATE_NAME "="

const char *BLYNK_AUTH_TOKENS[] = {

    "",

    "=",

    "="};

#define BLYNK_AUTH_TOKEN (BLYNK_AUTH_TOKENS[DEVICE_ID])

#include <MKRNB.h>            // MKR NB 보드와 관련된 라이브러리

#include <BlynkSimpleMKRNB.h> // MKR NB 보드용 Blynk 라이브러리

// MKR NB 초기화

NBClient client;

GPRS gprs;

NB nbAccess;

BlynkTimer timer;

char pin[] = "0000";

/*  GPIO

포트 핀 구성

아두이노 포트 핀 기능: pinMode(), digitalRead() 및 digitalWrite()는 기본적으로 어쨌든 이 작업을 수행합니다.

digitalRead() 및 digitalWrite()에 비해 직접 레지스터 조작을 사용하면 약간의 성능 이점만 있습니다.

포트 핀 입력

특정 포트 핀을 입력으로 설정하려면:

PORT->Group[PORTA].PINCFG[19].bit.INEN = 1;  // Enable PA19 input

PORT->Group[PORTA].PINCFG[19].bit.PULLEN = 0;

PORT->Group[PORTA].DIRCLR.reg = PORT_PA19;

풀업 저항으로 입력을 활성화하려면:

PORT->Group[PORTA].PINCFG[19].bit.INEN = 1;  // Enable PA19 input with a pull-up resistor

PORT->Group[PORTA].PINCFG[19].bit.PULLEN = 1;

PORT->Group[PORTA].DIRCLR.reg = PORT_PA19;

PORT->Group[PORTA].OUTSET.reg = PORT_PA19;

풀다운 저항으로 입력을 활성화하려면:

PORT->Group[PORTA].PINCFG[19].bit.INEN = 1;  // Enable PA19 input with a pull-down resistor

PORT->Group[PORTA].PINCFG[19].bit.PULLEN = 1;

PORT->Group[PORTA].DIRCLR.reg = PORT_PA19;

PORT->Group[PORTA].OUTCLR.reg = PORT_PA19;

입력을 읽으려면:

if (PORT->Group[PORTA].IN.reg & PORT_PA19)  // Read the input pin on PA19

포트 핀 출력

특정 포트 핀을 출력으로 설정하려면:

PORT->Group[PORTA].DIRSET.reg = PORT_PA19;  // Set PA19 to an output

PORT->Group[PORTA].PINCFG[19].bit.INEN = 1;  // Support output read back

출력을 높게 설정하려면:

PORT->Group[PORTA].OUTSET.reg = PORT_PA19;  // Set PA19 output HIGH

출력을 낮게 설정하려면:

PORT->Group[PORTA].OUTCLR.reg = PORT_PA19;  // Set PA19 output LOW

Arduino-포트 핀 매핑

예를 들어 디지털 핀 D12의 경우 Arduino "g_APinDescription" 구조를 사용하여 Arduino 핀 번호에서 포트 핀으로 매핑하는 것도 가능합니다.

PORT->Group[g_APinDescription[12].ulPort].PINCFG[g_APinDescription[12].ulPin].bit.INEN = 1;

*/

void GPIO_init()

{

  pinMode(17, OUTPUT);

  analogReadResolution(12);

  // analogReference(AR_DEFAULT) = Set the analogue input threshold to 3.3V

  ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;

  ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val;

  // pinMode(A2, OUTPUT);

  PORT->Group[PORTB].DIRSET.reg = PORT_PB03;

  PORT->Group[PORTB].PINCFG[3].bit.INEN = 1;

  // pinMode(D0, INPUT);

  PORT->Group[PORTA].PINCFG[22].bit.INEN = 1;

  PORT->Group[PORTA].PINCFG[22].bit.PULLEN = 0;

  PORT->Group[PORTA].DIRCLR.reg = PORT_PA22;

  // pinMode(D1, OUTPUT);

  PORT->Group[PORTA].DIRSET.reg = PORT_PA23;

  PORT->Group[PORTA].PINCFG[23].bit.INEN = 1;

  // pinMode(D2, INPUT);

  PORT->Group[PORTA].PINCFG[10].bit.INEN = 1;

  PORT->Group[PORTA].PINCFG[10].bit.PULLEN = 0;

  PORT->Group[PORTA].DIRCLR.reg = PORT_PA10;

  // pinMode(D3, OUTPUT);

  PORT->Group[PORTA].DIRSET.reg = PORT_PA11;

  PORT->Group[PORTA].PINCFG[11].bit.INEN = 1;

  // pinMode(D4, INPUT);

  PORT->Group[PORTB].PINCFG[10].bit.INEN = 1;

  PORT->Group[PORTB].PINCFG[10].bit.PULLEN = 0;

  PORT->Group[PORTB].DIRCLR.reg = PORT_PB10;

  // pinMode(D5, OUTPUT);

  PORT->Group[PORTB].DIRSET.reg = PORT_PB11;

  PORT->Group[PORTB].PINCFG[11].bit.INEN = 1;

  // pinMode(D6, INPUT);

  PORT->Group[PORTA].PINCFG[20].bit.INEN = 1;

  PORT->Group[PORTA].PINCFG[20].bit.PULLEN = 0;

  PORT->Group[PORTA].DIRCLR.reg = PORT_PA20;

  // pinMode(D7, OUTPUT);

  PORT->Group[PORTA].DIRSET.reg = PORT_PA21;

  PORT->Group[PORTA].PINCFG[21].bit.INEN = 1;

}

// MPU6050 변수

float Acc_scaleFactor, Gyro_scaleFactor;

const int8_t MPU_ADDR = 0x69;

// mpuData 인덱스 열거형

enum SensorIndex

{

  AcX,

  AcY,

  AcZ,

  Tmp,

  GyX,

  GyY,

  GyZ

};

// MPU6050 레지스터를 설정하는 함수

inline void configureMPURegister(int8_t registerAddr, int8_t value)

{

  Wire.beginTransmission(MPU_ADDR);

  Wire.write(registerAddr);

  Wire.write(value);

  Wire.endTransmission(true);

}

void setupMPU()

{

  // MPU6050 전체(4개) 활성화

  PORT->Group[PORTA].OUTSET.reg = PORT_PA23;

  PORT->Group[PORTA].OUTSET.reg = PORT_PA11;

  PORT->Group[PORTB].OUTSET.reg = PORT_PB11;

  PORT->Group[PORTA].OUTSET.reg = PORT_PA21;

  // MPU6050 초기화 및 리셋

  configureMPURegister(0x6B, 0);    // MPU-6050 활성화

  configureMPURegister(0x6B, 0x03); // 클럭 소스 설정

  /*  가속도계 설정

    AFS_SEL=0, Full Scale Range = +/- 2 [g]

    AFS_SEL=1, Full Scale Range = +/- 4 [g]

    AFS_SEL=2, Full Scale Range = +/- 8 [g]

    AFS_SEL=3, Full Scale Range = +/- 10 [g]

  */

  switch (0)

  {

  case 0:

    configureMPURegister(0x1C, 0x00);

    Acc_scaleFactor = 16384;

    break;

  case 1:

    configureMPURegister(0x1C, 0x08);

    Acc_scaleFactor = 8192;

    break;

  case 2:

    configureMPURegister(0x1C, 0x10);

    Acc_scaleFactor = 4096;

    break;

  default:

    configureMPURegister(0x1C, 0x18);

    Acc_scaleFactor = 3276.8;

    break;

  }

  // 스케일 팩터를 역수로 취함

  Acc_scaleFactor = 1.0 / Acc_scaleFactor;

  /*  자이로스코프 설정

    FS_SEL=0, Full Scale Range = +/- 250 [degree/sec]

    FS_SEL=1, Full Scale Range = +/- 500 [degree/sec]

    FS_SEL=2, Full Scale Range = +/- 1000 [degree/sec]

    FS_SEL=3, Full Scale Range = +/- 2000 [degree/sec]

  */

  switch (0)

  {

  case 0:

    configureMPURegister(0x1B, 0x00);

    Gyro_scaleFactor = 1.0 / 131.0;

    break;

  case 1:

    configureMPURegister(0x1B, 0x08);

    Gyro_scaleFactor = 65.5;

    break;

  case 2:

    configureMPURegister(0x1B, 0x10);

    Gyro_scaleFactor = 32.8;

    break;

  default:

    configureMPURegister(0x1B, 0x18);

    Gyro_scaleFactor = 16.4;

    break;

  }

  // 스케일 팩터를 역수로 취함

  Gyro_scaleFactor = 1.0 / Gyro_scaleFactor;

  /*  DLPF 설정

    Accel BW 260Hz, Delay    0ms / Gyro BW 256Hz, Delay 0.98ms, Fs 8KHz

    Accel BW 184Hz, Delay    2ms / Gyro BW 188Hz, Delay  1.9ms, Fs 1KHz

    Accel BW  94Hz, Delay    3ms / Gyro BW  98Hz, Delay  2.8ms, Fs 1KHz

    Accel BW  44Hz, Delay  4.9ms / Gyro BW  42Hz, Delay  4.8ms, Fs 1KHz

    Accel BW  21Hz, Delay  8.5ms / Gyro BW  20Hz, Delay  8.3ms, Fs 1KHz

    Accel BW  10Hz, Delay 13.8ms / Gyro BW  10Hz, Delay 13.4ms, Fs 1KHz

    Accel BW   5Hz, Delay   19ms / Gyro BW   5Hz, Delay 18.6ms, Fs 1KHz

  */

  configureMPURegister(0x1A, 6);

  // MPU6050 전체(4개) 비활성화

  PORT->Group[PORTA].OUTCLR.reg = PORT_PA23;

  PORT->Group[PORTA].OUTCLR.reg = PORT_PA11;

  PORT->Group[PORTB].OUTCLR.reg = PORT_PB11;

  PORT->Group[PORTA].OUTCLR.reg = PORT_PA21;

}

// 배열 크기 수정요함 (타입, 크기)

int16_t mpuData[4][7];      // [0,1,2,3][AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ] 순으로 저장

int32_t mpuData_prev[4][3]; // [num][data]

const uint8_t MPU_portGroup[4] = {0, 0, 1, 0};

const uint32_t MPU_writePin[4] = {1ul << 23, 1ul << 11, 1ul << 11, 1ul << 21};

const uint32_t MPU_readPin[4] = {1ul << 22, 1ul << 10, 1ul << 10, 1ul << 20};

// MPU6050에서 데이터 읽기

inline void readMPU(uint8_t MPU_num)

{

  // Data Backup

  mpuData_prev[MPU_num][AcX] = mpuData[MPU_num][AcX];

  mpuData_prev[MPU_num][AcY] = mpuData[MPU_num][AcY];

  mpuData_prev[MPU_num][AcZ] = mpuData[MPU_num][AcZ];

  // 해당 핀이 활성화되어 있으면, 무시

  if (PORT->Group[MPU_portGroup[MPU_num]].IN.reg & MPU_readPin[MPU_num])

    return;

  // 해당 핀이 비활성화되어 있으면, MPU 활성화

  else

    PORT->Group[MPU_portGroup[MPU_num]].OUTSET.reg = MPU_writePin[MPU_num];

  // 데이터 읽기

  Wire.beginTransmission(MPU_ADDR);

  Wire.write(0x3B);

  Wire.endTransmission(false);

  // 가속도 데이터만 호출

  Wire.requestFrom(MPU_ADDR, 6, true); // 2byte * 3

  mpuData[MPU_num][AcX] = (Wire.read() << 8 | Wire.read());

  mpuData[MPU_num][AcY] = (Wire.read() << 8 | Wire.read());

  mpuData[MPU_num][AcZ] = (Wire.read() << 8 | Wire.read());

  // MPU 비활성화

  PORT->Group[MPU_portGroup[MPU_num]].OUTCLR.reg = MPU_writePin[MPU_num];

}

double accData[4] = {0.0, 0.0, 0.0, 0.0};

int accData_lengh = sizeof(accData);

uint32_t soundData = 0;

uint32_t axisValue;

double axisValue_double;

inline void Get_measurement()

{

  // 소음 측정

  uint32_t soundValue = analogRead(A0);

  if (soundData < soundValue)

    soundData = soundValue;

  // 진동 측정

  for (int i = 0; i < 4; i++)

  {

    readMPU(i);

    axisValue = abs(mpuData[i][AcX] - mpuData_prev[i][AcX]) + abs(mpuData[i][AcY] - mpuData_prev[i][AcY]) + abs(mpuData[i][AcZ] - mpuData_prev[i][AcZ]);

    axisValue_double = (axisValue)*Acc_scaleFactor;

    if (accData[i] < axisValue_double)

      accData[i] = axisValue_double;

  }

}

/*

  Blynk data type

  Type     MIN             MAX

  Integer  -2,147,483,648  2,147,483,647

  Double   -1.8 x 10^300   4.9 x 10^-324

  String   any value is accepted

*/

uint32_t updateCount = 0;

void Cloud_update()

{

  Blynk.virtualWrite(0, accData[0]);

  Blynk.virtualWrite(1, accData[1]);

  Blynk.virtualWrite(2, accData[2]);

  Blynk.virtualWrite(3, accData[3]);

  Blynk.virtualWrite(4, soundData);

  memset(accData, 0, accData_lengh), soundData = 0;

  Serial.print(F("Updating data - ")), Serial.println(++updateCount);

}

bool led_state = false;

void LED_blink()

{

  digitalWrite(17, led_state);

  if (led_state)

    led_state = false;

  else

    led_state = true;

}

void setup()

{

  GPIO_init();

  digitalWrite(17, HIGH);

  Serial.begin(9600);

  delay(1000);

  Wire.begin(); // I2C 통신 시작

  Wire.setClock(3400000UL);

  setupMPU(); // MPU6050 설정

  readMPU(0), readMPU(1), readMPU(2), readMPU(3);

  readMPU(0), readMPU(1), readMPU(2), readMPU(3);

  Blynk.begin(BLYNK_AUTH_TOKEN, nbAccess, gprs, client, pin, "sgp1.blynk.cloud");

  Blynk.run();

  timer.setInterval(10L, Get_measurement);

  timer.setInterval(500L, LED_blink);

  timer.setInterval(60000L, Cloud_update);

}

void loop()

{

  Blynk.run();

  timer.run();

}

The monitor output looks like this

---- Opened the serial port COM3 ----
Updating data - 2
Updating data - 3
Updating data - 4
Updating data - 5
Updating data - 6
Updating data - 7
Updating data - 8
Updating data - 9
Updating data - 10
Updating data - 11
Updating data - 12
Updating data - 13
Updating data - 14
Updating data - 15
Updating data - 16
Updating data - 17
Updating data - 18
Updating data - 19
Updating data - 20
Updating data - 21
Updating data - 22
Updating data - 23
Updating data - 24
Updating data - 25
Updating data - 26
Updating data - 27
Updating data - 28
Updating data - 29
---- Closed serial port COM3 due to disconnection from the machine ----
---- Reopened serial port COM3 ----
Updating data - 1
Updating data - 2
Updating data - 3
Updating data - 4
Updating data - 5
Updating data - 6
Updating data - 7
---- Closed serial port COM3 due to disconnection from the machine ----
---- Reopened serial port COM3 ----
Updating data - 1
Updating data - 2
Updating data - 3
Updating data - 4
Updating data - 5
Updating data - 6
Updating data - 7
Updating data - 8
Updating data - 9
Updating data - 10
Updating data - 11
Updating data - 12
Updating data - 13
Updating data - 14
Updating data - 15
Updating data - 16
Updating data - 17
Updating data - 18
Updating data - 19
Updating data - 20
Updating data - 21
Updating data - 22
Updating data - 23
Updating data - 24
Updating data - 25
Updating data - 26
Updating data - 27
Updating data - 28
Updating data - 29
---- Closed serial port COM3 due to disconnection from the machine ----
    ---- Reopened serial port COM3 ----
    Updating data - 1
    Updating data - 2
    Updating data - 3
    Updating data - 4
    Updating data - 5
    Updating data - 6
    Updating data - 7
    Updating data - 8
    Updating data - 9
    Updating data - 10
    Updating data - 11
    Updating data - 12
    Updating data - 13
    Updating data - 14
    Updating data - 15
    Updating data - 16
    Updating data - 17
    Updating data - 18
    Updating data - 19
    Updating data - 20
    Updating data - 21
    ---- Closed serial port COM3 due to disconnection from the machine ----

I’ve done some testing and it seems that the blynk.run function gets stuck in an infinite loop.

I’m using lte cat.m1, what could be the problem?

A post was merged into an existing topic: Two issues