Sync two arduino boards

Did you show us any code yet? Did you provide a schematic of the two devices, for clarity? Did you give us links to, for example, your IMU, so we could perhaps explore the nature of the problem in more depth?
Sorry, but we're pawing around in the dark without more information, as usual. Perhaps @paulpaulson is correct, and this won't be resolved without further education, but we've precious little to help you with.

another hypothesis... you could take a board with a dual core processor like esp32 or rp2040 and run "slow sensors" on one core and fast IMU readings on the other.

However this will require you to make an effort to learn how to work with multi-core systems, the learning curve can be quite steep.

2 Likes

You might start with :

I have already tried the interrupt idea but probably corrected some code errors... I will open a topic to talk about this

Keep it here, we may miss the new topic completely. The best advice on this forum is to keep all issues relating to a particular project within one thread, so you don't have to keep re-introducing the project.
FWIW.

opening a multiple threads related the same subject is a violation of the forum rules.

The IMU I use on the Mega is the MPU6050.
I tried searching for something online and found examples on Timer1 and Timer2...
this is the code:

#include <Wire.h>
#include <MPU6050_tockn.h>
#include <SoftwareSerial.h>
#include <SdsDustSensor.h>
#include <SPI.h>
#include <SD.h>
#include <TinyGPS.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

//define for dB meter
#define SoundSensorPin A8  //this pin read the analog voltage from the sound level meter
#define VREF  5.0  //voltage on AREF pin,default:operating voltage

//sensor CO2,NH3,NO2
const int S_analog = 1023.0;
int co, nh3;
float no2;

//variabili per sensore accelerometro/giroscopio
const int MPU = 0x68;  // I2C address of the MPU-6050
float AccX, AccY, AccZ, AngX=0.0, AngY=0.0, AngZ=0.0;
float temp;
float roll, pitch, yaw;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float GyroX, GyroY, GyroZ;
float elapsedTime, currentTime, previousTime;
MPU6050 mpu6050(Wire);
//MPU6050 mpu;
unsigned long t1, dt;

//GPS sensor
float lat, lon;
TinyGPS gps;  // create gps object

//PM10 PM2.5 sensor
int rxPin = 16;
int txPin = 17;
SdsDustSensor sds(Serial2);
float old_value[2];
float pm10, pm25;

//SD Card
File file, file_pm, file_imu;
const int chipSelect = 53;

//variable for dB meter
float voltageValue, dbValue;

//variable for interrupt
unsigned int count_interrupt = 0;
unsigned int reload = 0xF; 

//variable button
int stato = LOW;
int count = 0;

ISR(TIMER1_COMPA_vect){
  if(count_interrupt == 0)
    file_imu = SD.open("imu.csv", FILE_WRITE);

  count_interrupt++;
  OCR2A = reload;
  if(count_interrupt > 5){
    IMU();
  }
}
void setup() {
  
  //button
  pinMode(5,INPUT); //pulsante per tutti i sensori

  Serial.begin(9600);

  // IMU
  Wire.begin();
  mpu6050.begin();

  //gps
  Serial3.begin(9600);  // connect gps sensor

  //pm10 pm2.5
  sds.begin();
  Serial2.begin(9600);

  //controlli sui due file...
  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("datalog.csv")){
    SD.remove("datalog.csv");
    //Serial.println("Rimosso file già esistente!!");
  }

  //per interrupt
  cli();
  TCCR1A = 0;
  TCCR1B = 0; 
  OCR1A = reload;
  TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); 
  TIMSK1 = (1<<OCIE1A); 
  sei(); 

  file = SD.open("datalog.csv", FILE_WRITE);  
}
void loop() {
  if (digitalRead(5) == HIGH){
    stato = !stato;
    Serial.println(stato);
    count++;
    delay(200);
  }

  if(count == 2) {
    file.close();
    file_imu.close();
  }
  else {
    if(count == 1){

      MICS6814();
      file.print(co); 
      file.print(";");
      file.print(no2);
      file.print(";");
      file.print(nh3);
      file.print(";");

      GPS();

      PM10_PM25();
      file.print(pm10);
      file.print(";");
      file.print(pm25);
      file.print(";");

      Sound(); 
      file.print(dbValue);
      file.print(";");

      file.print(millis());
      file.println();
    }
  }
}

void GPS() {
  while (Serial3.available()) {  // check for gps data
    if (gps.encode(Serial3.read()))  // encode gps data
    {
      gps.f_get_position(&lat, &lon);  // get latitude and longitude
      
    }
  }
  file.print(lat,5);
  file.print(";");
  file.print(lon,5);
  file.print(";");
}

void MICS6814() {
  co = map(analogRead(A2), 0, S_analog, 1, 1000);           //monossido di carbonio
  nh3 = map(analogRead(A1), 0, S_analog, 1, 500);           //ammoniaca
  no2 = map(analogRead(A0), 0, S_analog, 5, 1000) / 100.0;  //diossido di azoto
}

void PM10_PM25() {
  PmResult pm = sds.readPm();

  if(pm.isOk()){
    pm10 = pm.pm10;
    pm25 = pm.pm25;

    old_value[0] = pm10;
    old_value[1] = pm25;
  }
  else{
    pm10 = old_value[0];
    pm25 = old_value[1];
  }
}

void IMU() {
  mpu6050.update();
  
  temp = mpu6050.getTemp();

  AccX = mpu6050.getAccX();
  AccY = mpu6050.getAccY();
  AccZ = mpu6050.getAccZ();

  GyroX = mpu6050.getGyroAngleX();
  GyroY = mpu6050.getGyroAngleY();
  GyroZ = mpu6050.getGyroAngleZ();
  
  // for test
  file_imu.print(temp);
  file_imu.print(";");
  file_imu.print(AccX);
  file_imu.println();
}

void Sound() {
  voltageValue = analogRead(SoundSensorPin) / 1024.0 * VREF;
  dbValue = voltageValue * 50.0;  //convert voltage to decibel value
}

Lets stop with the hypothesis. If you want to "sync" two computers you must pick one for the master. The master must send a sync signal to the second board. The program in the second board must wait for the sync signal before it begins it's process and then return to wait for the next sync signal.
Are you prepared to program this?

so I can make the arduino Mega master and the arduino Uno slave.
When the master sends the signal to the slave, the slave will have to send values (obtained from the imu) to the master and will stop sending when the master sends another signal, is this correct?

If that is how you want to define synchronizing, then, yes, you can do that. But the slave will have to determine that there was no message from the master telling it to stop. How long should the slave wait to determine that?

hello everyone!

I am currently working with an Arduino Mega2506 R3 board, to which I have connected several sensors: gps, IMU, co sensor, pm sensor.
My goal is to collect data from the IMU (accelerometer and gyroscope), writing them to sd card, every millisecond!!.
The data from the other sensors write to another file, with a frequency of 500ms (and that's fine).
I wanted to manage the writing of the imu file with an interrupt, but not being very familiar with these things I simply enquired online.
The IMU I use on the Mega is the MPU6050.
this is the code:

#include <Wire.h>
#include <MPU6050_tockn.h>
#include <SoftwareSerial.h>
#include <SdsDustSensor.h>
#include <SPI.h>
#include <SD.h>
#include <TinyGPS.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

//define for dB meter
#define SoundSensorPin A8  //this pin read the analog voltage from the sound level meter
#define VREF  5.0  //voltage on AREF pin,default:operating voltage

//sensor CO2,NH3,NO2
const int S_analog = 1023.0;
int co, nh3;
float no2;

//variabili per sensore accelerometro/giroscopio
const int MPU = 0x68;  // I2C address of the MPU-6050
float AccX, AccY, AccZ, AngX=0.0, AngY=0.0, AngZ=0.0;
float temp;
float roll, pitch, yaw;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float GyroX, GyroY, GyroZ;
float elapsedTime, currentTime, previousTime;
MPU6050 mpu6050(Wire);
//MPU6050 mpu;
unsigned long t1, dt;

//GPS sensor
float lat, lon;
TinyGPS gps;  // create gps object

//PM10 PM2.5 sensor
int rxPin = 16;
int txPin = 17;
SdsDustSensor sds(Serial2);
float old_value[2];
float pm10, pm25;

//SD Card
File file, file_pm, file_imu;
const int chipSelect = 53;

//variable for dB meter
float voltageValue, dbValue;

//variable for interrupt
unsigned int count_interrupt = 0;
unsigned int reload = 0xF; 

//variable button
int stato = LOW;
int count = 0;

ISR(TIMER1_COMPA_vect){
  if(count_interrupt == 0)
    file_imu = SD.open("imu.csv", FILE_WRITE);

  count_interrupt++;
  OCR2A = reload;
  if(count_interrupt > 5){
    IMU();
  }
}
void setup() {
  
  //button
  pinMode(5,INPUT); //pulsante per tutti i sensori

  Serial.begin(9600);

  // IMU
  Wire.begin();
  mpu6050.begin();

  //gps
  Serial3.begin(9600);  // connect gps sensor

  //pm10 pm2.5
  sds.begin();
  Serial2.begin(9600);

  //controlli sui due file...
  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("datalog.csv")){
    SD.remove("datalog.csv");
    //Serial.println("Rimosso file già esistente!!");
  }

  //per interrupt
  cli();
  TCCR1A = 0;
  TCCR1B = 0; 
  OCR1A = reload;
  TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); 
  TIMSK1 = (1<<OCIE1A); 
  sei(); 

  file = SD.open("datalog.csv", FILE_WRITE);  
}
void loop() {
  if (digitalRead(5) == HIGH){
    stato = !stato;
    Serial.println(stato);
    count++;
    delay(200);
  }

  if(count == 2) {
    file.close();
    file_imu.close();
  }
  else {
    if(count == 1){

      MICS6814();
      file.print(co); 
      file.print(";");
      file.print(no2);
      file.print(";");
      file.print(nh3);
      file.print(";");

      GPS();

      PM10_PM25();
      file.print(pm10);
      file.print(";");
      file.print(pm25);
      file.print(";");

      Sound(); 
      file.print(dbValue);
      file.print(";");

      file.print(millis());
      file.println();
    }
  }
}

void GPS() {
  while (Serial3.available()) {  // check for gps data
    if (gps.encode(Serial3.read()))  // encode gps data
    {
      gps.f_get_position(&lat, &lon);  // get latitude and longitude
      
    }
  }
  file.print(lat,5);
  file.print(";");
  file.print(lon,5);
  file.print(";");
}

void MICS6814() {
  co = map(analogRead(A2), 0, S_analog, 1, 1000);           //monossido di carbonio
  nh3 = map(analogRead(A1), 0, S_analog, 1, 500);           //ammoniaca
  no2 = map(analogRead(A0), 0, S_analog, 5, 1000) / 100.0;  //diossido di azoto
}

void PM10_PM25() {
  PmResult pm = sds.readPm();

  if(pm.isOk()){
    pm10 = pm.pm10;
    pm25 = pm.pm25;

    old_value[0] = pm10;
    old_value[1] = pm25;
  }
  else{
    pm10 = old_value[0];
    pm25 = old_value[1];
  }
}

void IMU() {
  mpu6050.update();
  
  temp = mpu6050.getTemp();

  AccX = mpu6050.getAccX();
  AccY = mpu6050.getAccY();
  AccZ = mpu6050.getAccZ();

  GyroX = mpu6050.getGyroAngleX();
  GyroY = mpu6050.getGyroAngleY();
  GyroZ = mpu6050.getGyroAngleZ();
  
  // for test
  file_imu.print(temp);
  file_imu.print(";");
  file_imu.print(AccX);
  file_imu.println();
}

void Sound() {
  voltageValue = analogRead(SoundSensorPin) / 1024.0 * VREF;
  dbValue = voltageValue * 50.0;  //convert voltage to decibel value
}

Why did you open a new thread?

this is for the interrupt

@cippe ,

I have merged your topics.

Please read this:

It is clear you have one project and a number of questions related to that project. The context for each question is the same and the previous answers to one question help inform the next. It is therefore better to keep all your questions in one topic that people can follow and help with. I have known topics to grow to over 1000 replies like this and the OP get their project working. Please can you change the title of this topic to reflect what your topic is and then keep adding your new questions to this topic.

Thank you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.