Обновить ArduinoAccelINTto32_1sec/ArduinoAccelINTto32_1sec.ino

This commit is contained in:
2026-05-25 15:46:40 +03:00
parent 5983a241cc
commit 433935c00b

View File

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