hello everyone!
i am working with an arduino uno rev2 wifi board and i need to manage the reading of the imu integrated on the board.
What i need to do is the following: i need to read the values of the imu (accelerometer and gyroscope) with an interrupt every 100Hz.
This is the code I have done so far:
#include <Arduino_LSM6DS3.h>
#include <SPI.h>
#include <SD.h>
#include <TinyGPS.h>
#include <Wire.h>
#include <RTClib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <Arduino.h>
File file_imu, file_gps;
const int chipSelect = 4;
float gyro_x, gyro_y, gyro_z;
float acc_x, acc_y, acc_z;
char accX[7], accY[7], accZ[7];
char gyroX[8], gyroY[8], gyroZ[8];
int count = 0;
int stato = LOW;
int file_active = 0;
int lunghezza = 0;
long time_cpu_actual = 0, delta_millis = 0, millis_last_utc = 0;
long time_cpu_arduino = millis();
#define N 11
String timestamp_str;
char utc[N];
char delta_millis_str[4];
// BUFFER PER LA RICEZIONE DATI
//volatile byte buf[32];
char myMsg[11];
volatile bool flag = false;
bool usingInterrupt = false;
//void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
int delta_millis_old = 0;
long last_utc_old = 0, tmp = 0;
volatile bool interruptFlag = false;
// Timer 1 interrupt service routine (ISR)
ISR(TIMER0_COMPA_vect){
Serial.print("INT");
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(gyro_x, gyro_y, gyro_z);
time_cpu_actual = millis();
}
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(acc_x, acc_y, acc_z);
time_cpu_actual = millis();
}
}
void setup() {
// TIMER PER ACQUISIRE DATI OGNI 100 HZ
//cli(); // disable interrupts during setup
// // Configure Timer 1 interrupt
// // F_clock = 16e6 Hz, prescaler = 64, Fs = 100 Hz
// TCCR1A = 0;
// TCCR1B = 1<<WGM12 | 0<<CS12 | 1<<CS11 | 1<<CS10;
// TCNT1 = 0; // reset Timer 1 counter
// // OCR1A = ((F_clock / prescaler) / Fs) - 1 = 2499
// OCR1A = 2499; // Set sampling frequency Fs = 100 Hz
// TIMSK1 = 1<<OCIE1A; // Enable Timer 1 interrupt
// normal counting
TCA0_SINGLE_CTRLB = 0;
// enable overflow interrupt
TCA0_SINGLE_INTCTRL = TCA_SINGLE_OVF_bm;
// set TOP value
TCA0_SINGLE_PER = 15999;
// start timer at 15625 Hz
TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc | TCA_SINGLE_ENABLE_bm;
//sei(); // re-enable interrupts
// slave
Wire.begin(8);
Serial.begin(115200);
SD.begin(chipSelect);
pinMode(2, INPUT);
while (!Serial);
if (!IMU.begin()) {
//Serial.println("Failed to initialize IMU!");
while (1);
}
if (!SD.begin(chipSelect)) {
//Serial.println("Errore inizializzazione scheda SD!");
while (true); // Puoi anche gestire l'errore in modo diverso, ad esempio con un messaggio di errore e un loop.
}
if(SD.exists("IMU.csv")){
SD.remove("IMU.csv");
//Serial.println("Rimosso file già esistente!!");
}
if(SD.exists("gps.csv")){
SD.remove("gps.csv");
//Serial.println("Rimosso file già esistente!!");
}
}
void receiveEvent(byte howMany) {
for(byte i=0; i<howMany; i++) {
myMsg[i] = Wire.read();
}
myMsg[howMany] = '\0';
flag = true;
millis_last_utc = millis();
}
void loop(){
Serial.print("LOOP"); // for debug!
if(flag == true){
//Serial.println(myMsg);
flag = false;
}
//Serial.println();
lunghezza = strlen(myMsg);
char dato_ricevuto[lunghezza];
strcpy(dato_ricevuto, myMsg);
//Serial.println(dato_ricevuto);
//delay(1000);
// ----------------- LAVORO SULLA STRINGA CHE RICEVO ------------------
strcpy(utc, dato_ricevuto);
// ------------------------------ GESTIONE IMU -------------------------------
if(file_active == 0){
file_imu = SD.open("IMU.csv", FILE_WRITE);
file_active = 1;
}
//IMU.getGyroOffsets();
if (digitalRead(2) == HIGH){
stato = !stato;
//Serial.println(stato);
count++;
delay(300);
}
if(count == 2){
Serial.println("CHIUSO DATALOG");
file_imu.close();
} else{
if(count == 1){
Serial.println("APERTO DATALOG");
//read_data();
delta_millis = time_cpu_actual - millis_last_utc;
if(delta_millis > 0){
last_utc_old = millis_last_utc;
}
else{
tmp = last_utc_old;
//millis_last_utc = last_utc_old;
//delta_millis = time_cpu_actual - tmp;
if(time_cpu_actual - tmp >= 1000){
Serial.println("AAAAAAAAAAA");
delta_millis = 999;
}
}
snprintf(delta_millis_str, sizeof(delta_millis_str), "%ld", delta_millis);
Serial.print("DELTA: ");
Serial.println(delta_millis_str);
char timestamp[11];
int l_delta = strlen(delta_millis_str);
strcpy(timestamp, utc);
int startIndex = 6;
customConcat(timestamp, delta_millis_str, startIndex);
Serial.println(timestamp);
int pos = 6;
// scrivo su file...
file_imu.print(acc_x);
file_imu.print(";");
file_imu.print(acc_y);
file_imu.print(";");
file_imu.print(acc_z);
file_imu.print(";");
file_imu.print(gyro_x);
file_imu.print(";");
file_imu.print(gyro_y);
file_imu.print(";");
file_imu.print(gyro_z);
file_imu.print(";");
file_imu.print(timestamp);
file_imu.print(";");
file_imu.print(millis());
file_imu.print(";");
file_imu.print(time_cpu_actual);
file_imu.print(";");
file_imu.print(millis_last_utc);
file_imu.println();
}
}
}
void customConcat(char dest[11], const char src[4], int startIndex) {
int destLen = strlen(dest);
int srcLen = strlen(src);
if (startIndex < 0 || startIndex >= destLen) {
// Indice non valido
printf("Indice non valido\n");
return;
}
// Copia i caratteri dalla stringa di origine alla posizione desiderata nella stringa di destinazione
for (int i = 0; i < srcLen; i++) {
if(srcLen == 3){
dest[startIndex + i + 1] = src[i];
}
else if(srcLen == 2){
dest[startIndex + 1] = '0';
dest[startIndex + 2 + i] = src[i];
}
else if(srcLen == 1){
dest[startIndex + 1] = '0';
dest[startIndex + 2] = '0';
dest[startIndex + 3] = src[i];
}
//dest[startIndex + i +1] = src[i];
}
// Aggiungi il terminatore null per assicurarti che la stringa sia correttamente terminata
dest[10] = '\0';
}
in the code you can find everything the application has to do, so there are extra things like the whole loop part.
The interrupt part is right at the beginning of the setup.
With this code the application doesn't go... the interrupt doesn't seem to work, it also doesn't seem to enter the loop either.
Can anyone help me or give me some advice?
thank you all very much in advance!