diff --git a/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino b/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino new file mode 100644 index 0000000..1605859 --- /dev/null +++ b/ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino @@ -0,0 +1,283 @@ +// для работы с 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); + +}