Hello, i’m having a problem with a i2c comunication project.
In my project i have a master acquiring raw data at 250Hz from a MPU9250 and calculating roll and pitch angles. This information than is sended to a slave at 5Hz. The slave collectit and display the angles at a LCD i2c module. However, when the slave is receiving the information its seems that the lcd get corrupted as well the slave doesnt collect the information from the master.
MPU i2c address: 0x68
Slave i2c address: 0x20
LCD i2c address: 0x27
Does anyone knows why this is happening? I’m doing something wrong with the master-slave communication? When i just use the master to acquire and display it at the lcd, everything works fine.
Thanks!!
Slave code:
#include <Wire.h>
#define nodeAdress 0x20
#define dataSize 4
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int data[4];
unsigned int aux0;
unsigned int aux1;
float rollAngle, pitchAngle;
int ok = 1;
void setup() {
Serial.begin(57600);
Serial.println("1");
Wire.begin(nodeAdress);
Wire.setClock(400000);
Serial.println("1");
Wire.onReceive(receiveEvent);
Serial.println("1");
lcd.begin();
Serial.println("1");
lcd.backlight();
Serial.println("1");
lcd.clear();
}
void loop() {
delay(100);
aux0 = (data[1]<<8) | data[0];
pitchAngle = (aux0/100.0)-180.0;
aux1 = (data[3]<<8) | data[2];
rollAngle = (aux1/100.0)-180.0;
Serial.print("Pitch angle: ");
Serial.print(pitchAngle);
Serial.print(" - Roll angle: ");
Serial.println(rollAngle);
lcdPrint();
}
void lcdPrint() {
lcd.setCursor(0, 0);
lcd.print(F("Pitch: "));
lcd.print(pitchAngle);
lcd.print(F("o"));
lcd.setCursor(0, 1);
lcd.print(F("Roll: "));
lcd.print(rollAngle);
lcd.print(F("o"));
}
void receiveEvent(int howMany) {
if(Wire.available()){
data[0] = Wire.read();
data[1] = Wire.read();
data[2] = Wire.read();
data[3] = Wire.read();
}
}
Master code:
#include <Wire.h>
#define dataSize 4
#define nodeAdress 21
int gyro_x, gyro_y, gyro_z;
long acc_x, acc_y, acc_z, acc_total_vector;
int temperature;
long gyro_x_cal, gyro_y_cal, gyro_z_cal;
long loop_timer;
int lcd_loop_counter;
float angle_pitch, angle_roll;
int angle_pitch_buffer, angle_roll_buffer;
boolean set_gyro_angles;
float angle_roll_acc, angle_pitch_acc;
float angle_pitch_output, angle_roll_output;
byte data[4];
unsigned int aux;
int contador;
void setup() {
Serial.begin(57600);
Wire.begin();
Wire.setClock(400000);
setup_mpu_6050_registers();
for (int cal_int = 0; cal_int < 2000 ; cal_int ++) {
read_mpu_6050_data();
gyro_x_cal += gyro_x;
gyro_y_cal += gyro_y;
gyro_z_cal += gyro_z;
delay(3);
}
gyro_x_cal /= 2000;
gyro_y_cal /= 2000;
gyro_z_cal /= 2000;
loop_timer = micros();
}
void loop() {
read_mpu_6050_data();
gyro_x -= gyro_x_cal;
gyro_y -= gyro_y_cal;
gyro_z -= gyro_z_cal;
angle_pitch += gyro_x * 0.0000611;
angle_roll += gyro_y * 0.0000611;
angle_pitch += angle_roll * sin(gyro_z * 0.000001066);
angle_roll -= angle_pitch * sin(gyro_z * 0.000001066);
acc_total_vector = sqrt((acc_x * acc_x) + (acc_y * acc_y) + (acc_z * acc_z));
//57.296 = 1 / (3.142 / 180) The Arduino asin function is in radians
angle_pitch_acc = asin((float)acc_y / acc_total_vector) * 57.296;
angle_roll_acc = asin((float)acc_x / acc_total_vector) * -57.296;
angle_pitch_acc -= 0.0;
angle_roll_acc -= 0.0;
if (set_gyro_angles) {
angle_pitch = angle_pitch * 0.9996 + angle_pitch_acc * 0.0004;
angle_roll = angle_roll * 0.9996 + angle_roll_acc * 0.0004;
}
else {
angle_pitch = angle_pitch_acc;
angle_roll = angle_roll_acc;
set_gyro_angles = true;
}
angle_pitch_output = (angle_pitch_output * 0.9 + angle_pitch * 0.1);
angle_roll_output = (angle_roll_output * 0.9 + angle_roll * 0.1);
aux = (unsigned int)((angle_pitch_output + 180.0) * 100.0);
data[0] = (int)((aux & 0XFF));
data[1] = (int)((aux >> 8) & 0XFF);
aux = (unsigned int)((angle_roll_output + 180.0) * 100.0);
data[2] = (int)((aux & 0XFF));
data[3] = (int)((aux >> 8) & 0XFF);
Serial.print("Pitch angle: ");
Serial.print(angle_pitch_output);
Serial.print(" - Roll angle: ");
Serial.println(angle_roll_output);
if(contador < 50){
contador++;
} else{
Wire.beginTransmission(0x20);
Wire.write(data[0]);
Wire.write(data[1]);
Wire.write(data[2]);
Wire.write(data[3]);
Wire.endTransmission();
contador = 1;
}
Serial.println(contador);
Serial.println(micros() - loop_timer);
while (micros() - loop_timer < 4000)
loop_timer = micros();
}
void read_mpu_6050_data() {
Wire.beginTransmission(0x68); //Start communicating with the MPU-6050
Wire.write(0x3B); //Send the requested starting register
Wire.endTransmission(); //End the transmission
Wire.requestFrom(0x68, 14); //Request 14 bytes from the MPU-6050
while (Wire.available() < 14); //Wait until all the bytes are received
acc_x = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the acc_x variable
acc_y = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the acc_y variable
acc_z = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the acc_z variable
temperature = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the temperature variable
gyro_x = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the gyro_x variable
gyro_y = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the gyro_y variable
gyro_z = Wire.read() << 8 | Wire.read(); //Add the low and high byte to the gyro_z variable
}
void setup_mpu_6050_registers() {
//Activate the MPU-6050
Wire.beginTransmission(0x68); //Start communicating with the MPU-6050
Wire.write(0x6B); //Send the requested starting register
Wire.write(0x00); //Set the requested starting register
Wire.endTransmission(); //End the transmission
//Configure the accelerometer (+/-8g)
Wire.beginTransmission(0x68); //Start communicating with the MPU-6050
Wire.write(0x1C); //Send the requested starting register
Wire.write(0x10); //Set the requested starting register
Wire.endTransmission(); //End the transmission
//Configure the gyro (500dps full scale)
Wire.beginTransmission(0x68); //Start communicating with the MPU-6050
Wire.write(0x1B); //Send the requested starting register
Wire.write(0x08); //Set the requested starting register
Wire.endTransmission(); //End the transmission
}