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?