diff --git a/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino b/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino index 1605859..aca93dd 100644 --- a/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino +++ b/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino @@ -1,283 +1,284 @@ -// для работы с ESP-32 -// target Arduino UNO -#include "LowPower.h" -#include "Wire.h" -#include "SparkFunLIS3DH.h" -LIS3DH IMU1(I2C_MODE, 0x19); //Default constructor is I2C, addr 0x19. - -//#include -//AsyncStream<16> serial(&Serial, '~'); - -const int ESP_RESET_PIN = 5; // OLD - 2 -const int ESP_READY_PIN = 3; -const int ESP_CFG_PIN = 4; // OLD - 5 -const int LED_4BLINK = 6; -#define ACCSEL_READ_PERIOD 100 // частота опроса акселя в миллисекундах -#define ESP_WAIT_LIMIT 500 // максимальное время ожидания пробуждения ESP32 -#define ESP_READY_DURATION 25 // длительность сигнала "готов" ESP32 -uint32_t sec; -uint32_t steps = 0; -bool blinkmode = false; -void wakeUp() -{ - // Just a handler for the pin interrupt. -} -int int_loops_cnt = 0; -#define LOOPS_CNT_AFTER_INT2 15 - -void setup() { - delay(100); // а то похоже из-за кондёров по 10мкФ на стабилизаторе аксель не успевает запуститьсы до проверки контроллером при первом включении. - Serial.begin(115200); - //Serial.begin(57600); - //Serial.begin(19200); - //Serial.begin(9600); - //Serial.begin(2400); - //Serial.println("LSM6DS3 Basic Reading Code!"); - Wire.begin(); - pinMode(ESP_READY_PIN, INPUT); - pinMode(ESP_RESET_PIN, OUTPUT); - //pinMode(ESP_INFO_PIN, OUTPUT); - pinMode(ESP_CFG_PIN, OUTPUT); - analogReference(INTERNAL); // встроенный источник опорного на 1.1V (для ATmega168 или ATmega328P) и 2.56V (на ATmega8) - digitalWrite(ESP_RESET_PIN, LOW); - - // IMU 1 - LSM6DS3 - IMU1.settings.accelSampleRate = 10; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz - IMU1.settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 - IMU1.settings.xAccelEnabled = 1; - IMU1.settings.yAccelEnabled = 1; - IMU1.settings.zAccelEnabled = 1; - IMU1.settings.adcEnabled = 0; - IMU1.settings.tempEnabled = 0; - //Call .begin() to configure the IMU - //digitalWrite(ESP_CFG_PIN, HIGH); - - - if (IMU1.begin() != IMU_SUCCESS) { - //Serial.println("Not Connected. Please check connections and read the hookup guide."); - blinkmode=true; - pinMode(LED_4BLINK, OUTPUT); - //digitalWrite(ESP_RESET_PIN, LOW); - //delay(50); - //digitalWrite(ESP_RESET_PIN, HIGH); - digitalWrite(ESP_CFG_PIN, HIGH); - delay(50); - }else{ - configIntterupts(); - } - delay(ACCSEL_READ_PERIOD); - sec = millis(); -} - - -#define LOOPS_LIMIT 10 -int16_t accel_buf[LOOPS_LIMIT * 3]; -int loopnum = 0; - -void getAccelData() { - //Serial.println(loopnum); - if (loopnum >= LOOPS_LIMIT) {return;} - accel_buf[loopnum * 3] = IMU1.readRawAccelX(); - accel_buf[loopnum * 3 + 1] = IMU1.readRawAccelY(); - accel_buf[loopnum * 3 + 2] = IMU1.readRawAccelZ(); - loopnum++; - return; -} - -uint32_t tm_esp_fin = 0, esp_wait_time = 0; -void loop() { - if(blinkmode){ - digitalWrite(LED_4BLINK, HIGH); - delay(500); - digitalWrite(LED_4BLINK, LOW); - delay(500); - return; - } - if(int_loops_cnt >= LOOPS_CNT_AFTER_INT2){ - // Allow wake up pin to trigger interrupt on high. - attachInterrupt(0, wakeUp, HIGH); - // Enter power down state with ADC and BOD module disabled. - // Wake up when wake up pin is high. - LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); - // Disable external pin interrupt on wake up pin. - detachInterrupt(0); - int_loops_cnt = 0; - //digitalWrite(LED_4BLINK, HIGH); - sec = millis(); - digitalWrite(ESP_RESET_PIN, HIGH); // это не ресет. Для ESP-32 даём на заданую ногу сигнал пробуждения - delay(10); - digitalWrite(ESP_RESET_PIN, LOW); - } - getAccelData(); - if (loopnum >= LOOPS_LIMIT) { - digitalWrite(LED_4BLINK, HIGH); - // output data - // blink LOW for restert ESP-01 - - digitalWrite(ESP_CFG_PIN, LOW); - //delay(50); - if(esp_wait_time == 0) {esp_wait_time = millis();} - uint32_t tmp_time = millis(); - // wait ESP led ON - bool esp_ready = false; - while ((digitalRead(ESP_READY_PIN) == LOW) && ((millis()-esp_wait_time) < ESP_WAIT_LIMIT)) {delay(1);} - //while (digitalRead(ESP_READY_PIN) == LOW) {delay(1);} - if (digitalRead(ESP_READY_PIN) == HIGH){ - uint32_t led_on_time = millis(); - //while ((digitalRead(ESP_READY_PIN) == HIGH) && ((millis()-led_on_time) < ESP_READY_DURATION)) {delay(1);} - //if ((millis()-led_on_time) >= ESP_READY_DURATION) - {esp_ready = true;} - } - if (esp_ready){ - loopnum = 0; - // NON STOP VERSION //int_loops_cnt++; - // delay(95); - digitalWrite(ESP_RESET_PIN, LOW); - digitalWrite(LED_4BLINK, HIGH); - //digitalWrite(ESP_INFO_PIN, HIGH); - // send data to ESP - //uint32_t sec_start = millis(); - steps++; - if(int_loops_cnt >= LOOPS_CNT_AFTER_INT2){ - Serial.print("L/"); // send last loop flag - } - Serial.print("Start step "); - Serial.print(int_loops_cnt); - Serial.print("/"); - Serial.print(steps); - Serial.print(" / "); - Serial.print(String(tm_esp_fin) + "/" + String(millis())); - Serial.print(" / ESP wait time "+String(esp_wait_time)+"/"); - Serial.print(millis()-esp_wait_time); - Serial.print(" / bat.volt. "); - Serial.println(voltmeter(), 2); - //Serial.println(); - //Serial.println("============================================="); - for (int i = 0; i < LOOPS_LIMIT; i++) { - String ds = String(i) + ","; - // print IMU 1 data / plotter format - ds += String(accel_buf[i * 3]); - ds += ","; - ds += String(accel_buf[i * 3 + 1]); - ds += ","; - ds += String(accel_buf[i * 3 + 2]); - if (i < (LOOPS_LIMIT - 1)) ds += ";"; - Serial.print(ds); - //Serial.println(ds); - //if ((millis() - tmp_time) > ACCSEL_READ_PERIOD) { - // tmp_time = millis(); - // //getAccelData(); - //} - } - Serial.println("~"); - digitalWrite(LED_4BLINK, LOW); - tm_esp_fin = millis(); - esp_wait_time = 0; - }else{ - for(int nblink=0; nblink < 3; nblink++){ - digitalWrite(ESP_RESET_PIN, HIGH); // это не ресет. Для ESP-32 даём на заданую ногу сигнал пробуждения - digitalWrite(LED_4BLINK, HIGH); - delay(50); - digitalWrite(ESP_RESET_PIN, LOW); - digitalWrite(LED_4BLINK, LOW); - delay(50); - } - } - - } - - uint32_t sec_delta = (millis() - sec) % ACCSEL_READ_PERIOD; - delay(ACCSEL_READ_PERIOD - sec_delta); - //digitalWrite(LED_4BLINK, LOW); -} - -#define VOLTMETER_PIN A3 -#define VOLTMETER_BASE 1.1 // встроенный источник опорного 1.1V (для ATmega168 или ATmega328P) и 2.56V (на ATmega8) -#define VOLTMETER_CALIBR 1 -float input_volt = 0.0; -float temp = 0.0; -float r1 = 100000.0; //сопротивление резистора r1 -float r2 = 10000.0; // сопротивление резистора r2 -float voltmeter() { - int analogvalue = analogRead(VOLTMETER_PIN); - temp = (analogvalue * VOLTMETER_BASE) / 1024.0; // формула для конвертирования значения напряжения - input_volt = temp / (r2 / (r1 + r2)) * VOLTMETER_CALIBR; - if (input_volt < 0.1) input_volt = 0.0; - return (input_volt); -} - -void configIntterupts() -{ - uint8_t dataToWrite = 0; - - //LIS3DH_CLICK_CFG - dataToWrite = 0; - //Set these to enable individual axes of generation source (or direction) - // -- set = 1 to enable - dataToWrite |= 0x10;//Z click - dataToWrite |= 0x04;//Y click - dataToWrite |= 0x01;//X click - IMU1.writeRegister(LIS3DH_CLICK_CFG, dataToWrite); - - //LIS3DH_CLICK_SRC - dataToWrite = 0; - //Set these to enable click behaviors (also read to check status) - // -- set = 1 to enable - dataToWrite |= 0x10;//Enable single clicks - //dataToWrite |= 0x08;//sine (0 is positive, 1 is negative) - dataToWrite |= 0x04;//Z click detect enabled - dataToWrite |= 0x02;//Y click detect enabled - dataToWrite |= 0x01;//X click detect enabled - IMU1.writeRegister(LIS3DH_CLICK_SRC, dataToWrite); - - //LIS3DH_CLICK_THS - dataToWrite = 0; - //This sets the threshold where the click detection process is activated. - //Provide 7 bit value, 0x7F always equals max range by accelRange setting - //dataToWrite |= 0x0A; // ~1/16 range - dataToWrite |= 0x05; // ~1/16 range - IMU1.writeRegister(LIS3DH_CLICK_THS, dataToWrite); - - //LIS3DH_TIME_LIMIT - dataToWrite = 0; - //Time acceleration has to fall below threshold for a valid click. - //LSB equals 1/(sample rate) - dataToWrite |= 0x08; // 8 * 1/50 s = 160ms - IMU1.writeRegister(LIS3DH_TIME_LIMIT, dataToWrite); - - //LIS3DH_TIME_LATENCY - dataToWrite = 0; - //hold-off time before allowing detection after click event - //LSB equals 1/(sample rate) - dataToWrite |= 0x08; // 4 * 1/50 s = 160ms - IMU1.writeRegister(LIS3DH_TIME_LATENCY, dataToWrite); - - //LIS3DH_TIME_WINDOW - dataToWrite = 0; - //hold-off time before allowing detection after click event - //LSB equals 1/(sample rate) - dataToWrite |= 0x10; // 16 * 1/50 s = 320ms - IMU1.writeRegister(LIS3DH_TIME_WINDOW, dataToWrite); - - //LIS3DH_CTRL_REG5 - //Int1 latch interrupt and 4D on int1 (preserve fifo en) - IMU1.readRegister(&dataToWrite, LIS3DH_CTRL_REG5); - dataToWrite &= 0xF3; //Clear bits of interest - dataToWrite |= 0x08; //Latch interrupt (Cleared by reading int1_src) - //dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1? - IMU1.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); - - //LIS3DH_CTRL_REG3 - //Choose source for pin 1 - dataToWrite = 0; -// dataToWrite |= 0x40; //AOI1 event (Generator 1 interrupt on pin 1) - dataToWrite |= 0x20; //AOI2 event () - IMU1.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); - - //LIS3DH_CTRL_REG6 - //Choose source for pin 2 and both pin output inversion state - dataToWrite = 0; - dataToWrite |= 0x80; //Click int on pin 2 - IMU1.writeRegister(LIS3DH_CTRL_REG6, dataToWrite); - -} +// для работы с ESP-32 +// TEST +// target Arduino UNO +#include "LowPower.h" +#include "Wire.h" +#include "SparkFunLIS3DH.h" +LIS3DH IMU1(I2C_MODE, 0x19); //Default constructor is I2C, addr 0x19. + +//#include +//AsyncStream<16> serial(&Serial, '~'); + +const int ESP_RESET_PIN = 5; // OLD - 2 +const int ESP_READY_PIN = 3; +const int ESP_CFG_PIN = 4; // OLD - 5 +const int LED_4BLINK = 6; +#define ACCSEL_READ_PERIOD 100 // частота опроса акселя в миллисекундах +#define ESP_WAIT_LIMIT 500 // максимальное время ожидания пробуждения ESP32 +#define ESP_READY_DURATION 25 // длительность сигнала "готов" ESP32 +uint32_t sec; +uint32_t steps = 0; +bool blinkmode = false; +void wakeUp() +{ + // Just a handler for the pin interrupt. +} +int int_loops_cnt = 0; +#define LOOPS_CNT_AFTER_INT2 15 + +void setup() { + delay(100); // а то похоже из-за кондёров по 10мкФ на стабилизаторе аксель не успевает запуститьсы до проверки контроллером при первом включении. + Serial.begin(115200); + //Serial.begin(57600); + //Serial.begin(19200); + //Serial.begin(9600); + //Serial.begin(2400); + //Serial.println("LSM6DS3 Basic Reading Code!"); + Wire.begin(); + pinMode(ESP_READY_PIN, INPUT); + pinMode(ESP_RESET_PIN, OUTPUT); + //pinMode(ESP_INFO_PIN, OUTPUT); + pinMode(ESP_CFG_PIN, OUTPUT); + analogReference(INTERNAL); // встроенный источник опорного на 1.1V (для ATmega168 или ATmega328P) и 2.56V (на ATmega8) + digitalWrite(ESP_RESET_PIN, LOW); + + // IMU 1 - LSM6DS3 + IMU1.settings.accelSampleRate = 10; //Hz. Can be: 0,1,10,25,50,100,200,400,1600,5000 Hz + IMU1.settings.accelRange = 2; //Max G force readable. Can be: 2, 4, 8, 16 + IMU1.settings.xAccelEnabled = 1; + IMU1.settings.yAccelEnabled = 1; + IMU1.settings.zAccelEnabled = 1; + IMU1.settings.adcEnabled = 0; + IMU1.settings.tempEnabled = 0; + //Call .begin() to configure the IMU + //digitalWrite(ESP_CFG_PIN, HIGH); + + + if (IMU1.begin() != IMU_SUCCESS) { + //Serial.println("Not Connected. Please check connections and read the hookup guide."); + blinkmode=true; + pinMode(LED_4BLINK, OUTPUT); + //digitalWrite(ESP_RESET_PIN, LOW); + //delay(50); + //digitalWrite(ESP_RESET_PIN, HIGH); + digitalWrite(ESP_CFG_PIN, HIGH); + delay(50); + }else{ + configIntterupts(); + } + delay(ACCSEL_READ_PERIOD); + sec = millis(); +} + + +#define LOOPS_LIMIT 10 +int16_t accel_buf[LOOPS_LIMIT * 3]; +int loopnum = 0; + +void getAccelData() { + //Serial.println(loopnum); + if (loopnum >= LOOPS_LIMIT) {return;} + accel_buf[loopnum * 3] = IMU1.readRawAccelX(); + accel_buf[loopnum * 3 + 1] = IMU1.readRawAccelY(); + accel_buf[loopnum * 3 + 2] = IMU1.readRawAccelZ(); + loopnum++; + return; +} + +uint32_t tm_esp_fin = 0, esp_wait_time = 0; +void loop() { + if(blinkmode){ + digitalWrite(LED_4BLINK, HIGH); + delay(500); + digitalWrite(LED_4BLINK, LOW); + delay(500); + return; + } + if(int_loops_cnt >= LOOPS_CNT_AFTER_INT2){ + // Allow wake up pin to trigger interrupt on high. + attachInterrupt(0, wakeUp, HIGH); + // Enter power down state with ADC and BOD module disabled. + // Wake up when wake up pin is high. + LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); + // Disable external pin interrupt on wake up pin. + detachInterrupt(0); + int_loops_cnt = 0; + //digitalWrite(LED_4BLINK, HIGH); + sec = millis(); + digitalWrite(ESP_RESET_PIN, HIGH); // это не ресет. Для ESP-32 даём на заданую ногу сигнал пробуждения + delay(10); + digitalWrite(ESP_RESET_PIN, LOW); + } + getAccelData(); + if (loopnum >= LOOPS_LIMIT) { + digitalWrite(LED_4BLINK, HIGH); + // output data + // blink LOW for restert ESP-01 + + digitalWrite(ESP_CFG_PIN, LOW); + //delay(50); + if(esp_wait_time == 0) {esp_wait_time = millis();} + uint32_t tmp_time = millis(); + // wait ESP led ON + bool esp_ready = false; + while ((digitalRead(ESP_READY_PIN) == LOW) && ((millis()-esp_wait_time) < ESP_WAIT_LIMIT)) {delay(1);} + //while (digitalRead(ESP_READY_PIN) == LOW) {delay(1);} + if (digitalRead(ESP_READY_PIN) == HIGH){ + uint32_t led_on_time = millis(); + //while ((digitalRead(ESP_READY_PIN) == HIGH) && ((millis()-led_on_time) < ESP_READY_DURATION)) {delay(1);} + //if ((millis()-led_on_time) >= ESP_READY_DURATION) + {esp_ready = true;} + } + if (esp_ready){ + loopnum = 0; + // NON STOP VERSION //int_loops_cnt++; + // delay(95); + digitalWrite(ESP_RESET_PIN, LOW); + digitalWrite(LED_4BLINK, HIGH); + //digitalWrite(ESP_INFO_PIN, HIGH); + // send data to ESP + //uint32_t sec_start = millis(); + steps++; + if(int_loops_cnt >= LOOPS_CNT_AFTER_INT2){ + Serial.print("L/"); // send last loop flag + } + Serial.print("Start step "); + Serial.print(int_loops_cnt); + Serial.print("/"); + Serial.print(steps); + Serial.print(" / "); + Serial.print(String(tm_esp_fin) + "/" + String(millis())); + Serial.print(" / ESP wait time "+String(esp_wait_time)+"/"); + Serial.print(millis()-esp_wait_time); + Serial.print(" / bat.volt. "); + Serial.println(voltmeter(), 2); + //Serial.println(); + //Serial.println("============================================="); + for (int i = 0; i < LOOPS_LIMIT; i++) { + String ds = String(i) + ","; + // print IMU 1 data / plotter format + ds += String(accel_buf[i * 3]); + ds += ","; + ds += String(accel_buf[i * 3 + 1]); + ds += ","; + ds += String(accel_buf[i * 3 + 2]); + if (i < (LOOPS_LIMIT - 1)) ds += ";"; + Serial.print(ds); + //Serial.println(ds); + //if ((millis() - tmp_time) > ACCSEL_READ_PERIOD) { + // tmp_time = millis(); + // //getAccelData(); + //} + } + Serial.println("~"); + digitalWrite(LED_4BLINK, LOW); + tm_esp_fin = millis(); + esp_wait_time = 0; + }else{ + for(int nblink=0; nblink < 3; nblink++){ + digitalWrite(ESP_RESET_PIN, HIGH); // это не ресет. Для ESP-32 даём на заданую ногу сигнал пробуждения + digitalWrite(LED_4BLINK, HIGH); + delay(50); + digitalWrite(ESP_RESET_PIN, LOW); + digitalWrite(LED_4BLINK, LOW); + delay(50); + } + } + + } + + uint32_t sec_delta = (millis() - sec) % ACCSEL_READ_PERIOD; + delay(ACCSEL_READ_PERIOD - sec_delta); + //digitalWrite(LED_4BLINK, LOW); +} + +#define VOLTMETER_PIN A3 +#define VOLTMETER_BASE 1.1 // встроенный источник опорного 1.1V (для ATmega168 или ATmega328P) и 2.56V (на ATmega8) +#define VOLTMETER_CALIBR 1 +float input_volt = 0.0; +float temp = 0.0; +float r1 = 100000.0; //сопротивление резистора r1 +float r2 = 10000.0; // сопротивление резистора r2 +float voltmeter() { + int analogvalue = analogRead(VOLTMETER_PIN); + temp = (analogvalue * VOLTMETER_BASE) / 1024.0; // формула для конвертирования значения напряжения + input_volt = temp / (r2 / (r1 + r2)) * VOLTMETER_CALIBR; + if (input_volt < 0.1) input_volt = 0.0; + return (input_volt); +} + +void configIntterupts() +{ + uint8_t dataToWrite = 0; + + //LIS3DH_CLICK_CFG + dataToWrite = 0; + //Set these to enable individual axes of generation source (or direction) + // -- set = 1 to enable + dataToWrite |= 0x10;//Z click + dataToWrite |= 0x04;//Y click + dataToWrite |= 0x01;//X click + IMU1.writeRegister(LIS3DH_CLICK_CFG, dataToWrite); + + //LIS3DH_CLICK_SRC + dataToWrite = 0; + //Set these to enable click behaviors (also read to check status) + // -- set = 1 to enable + dataToWrite |= 0x10;//Enable single clicks + //dataToWrite |= 0x08;//sine (0 is positive, 1 is negative) + dataToWrite |= 0x04;//Z click detect enabled + dataToWrite |= 0x02;//Y click detect enabled + dataToWrite |= 0x01;//X click detect enabled + IMU1.writeRegister(LIS3DH_CLICK_SRC, dataToWrite); + + //LIS3DH_CLICK_THS + dataToWrite = 0; + //This sets the threshold where the click detection process is activated. + //Provide 7 bit value, 0x7F always equals max range by accelRange setting + //dataToWrite |= 0x0A; // ~1/16 range + dataToWrite |= 0x05; // ~1/16 range + IMU1.writeRegister(LIS3DH_CLICK_THS, dataToWrite); + + //LIS3DH_TIME_LIMIT + dataToWrite = 0; + //Time acceleration has to fall below threshold for a valid click. + //LSB equals 1/(sample rate) + dataToWrite |= 0x08; // 8 * 1/50 s = 160ms + IMU1.writeRegister(LIS3DH_TIME_LIMIT, dataToWrite); + + //LIS3DH_TIME_LATENCY + dataToWrite = 0; + //hold-off time before allowing detection after click event + //LSB equals 1/(sample rate) + dataToWrite |= 0x08; // 4 * 1/50 s = 160ms + IMU1.writeRegister(LIS3DH_TIME_LATENCY, dataToWrite); + + //LIS3DH_TIME_WINDOW + dataToWrite = 0; + //hold-off time before allowing detection after click event + //LSB equals 1/(sample rate) + dataToWrite |= 0x10; // 16 * 1/50 s = 320ms + IMU1.writeRegister(LIS3DH_TIME_WINDOW, dataToWrite); + + //LIS3DH_CTRL_REG5 + //Int1 latch interrupt and 4D on int1 (preserve fifo en) + IMU1.readRegister(&dataToWrite, LIS3DH_CTRL_REG5); + dataToWrite &= 0xF3; //Clear bits of interest + dataToWrite |= 0x08; //Latch interrupt (Cleared by reading int1_src) + //dataToWrite |= 0x04; //Pipe 4D detection from 6D recognition to int1? + IMU1.writeRegister(LIS3DH_CTRL_REG5, dataToWrite); + + //LIS3DH_CTRL_REG3 + //Choose source for pin 1 + dataToWrite = 0; +// dataToWrite |= 0x40; //AOI1 event (Generator 1 interrupt on pin 1) + dataToWrite |= 0x20; //AOI2 event () + IMU1.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); + + //LIS3DH_CTRL_REG6 + //Choose source for pin 2 and both pin output inversion state + dataToWrite = 0; + dataToWrite |= 0x80; //Click int on pin 2 + IMU1.writeRegister(LIS3DH_CTRL_REG6, dataToWrite); + +}