My Arduino stops transmitting data through the NRF24L01+ after I add the LCD code update. Especially when I use lcd.print() or lcd.clear(). I am using the i2c protocol when communicating with the 2 LCDs, and then another one to communicate to collect information from another Arduino, thus there are 3 devices using the i2c protocol. If you know why it keeps freezing (stops transmitting) the signal, please let me know, thanks!
Here is my code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define SLAVE_ADDR 9
/*Create a unique pipe out. The receiver has to
wear the same unique code*/
const uint64_t pipeOut = 0xE8E8F0F0E1LL; //IMPORTANT: The same as in the receiver
RF24 radio(9, 10); // select CSN pin
LiquidCrystal_I2C leftLCD(0x26, 16, 2);
LiquidCrystal_I2C rightLCD(0x27, 16, 2);
int rd;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 100; //the value is a number of milliseconds
// The sizeof this struct should not exceed 32 bytes
// This gives us up to 32 8 bits channals
struct MyData {
byte throttle;
byte yaw;
byte pitch;
byte roll;
byte AUX1;
byte AUX2;
byte otherData;
};
MyData data;
void resetData()
{
//This are the start values of each channal
// Throttle is 0 in order to stop the motors
//127 is the middle value of the 10ADC.
data.throttle = 1;
data.yaw = 127;
data.pitch =17;
data.roll = 1;
data.AUX1 = 1;
data.AUX2 = 1;
data.otherData = 0;
}
void setup()
{
//Start everything up
radio.begin();
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.openWritingPipe(pipeOut);
resetData();
leftLCD.init();
leftLCD.backlight();
rightLCD.init();
rightLCD.backlight();
Wire.begin();
// Initialize I2C communications as Slave
Wire.begin(SLAVE_ADDR);
// Function to run when data received from master
Wire.onReceive(receiveEvent);
startMillis = millis(); //initial start time
}
void receiveEvent() {
// read one character from the I2C
rd = Wire.read();
}
/**************************************************/
// Returns a corrected value for a joystick position that takes into account
// the values of the outer extents and the middle of the joystick range.
int mapJoystickValues(int val, int lower, int middle, int upper, bool reverse, int decrease, bool roundVal)
{
val = constrain(val, lower, upper);
if ( val < middle ){
val = map(val, lower, middle, 0, 128);
if(reverse)val+=decrease;
else val-=decrease;
}
else{
val = map(val, middle, upper, 128, 255);
val-=decrease;
}
if(roundVal)
{
if((val-127)<3 && (val-127)>-3){
val=127;
}
}
return ( reverse ? 255 - val : val );
}
void loop()
{
// The calibration numbers used here should be measured
// for your joysticks till they send the correct values.7
data.throttle = mapJoystickValues( analogRead(A3), 13, 524, 1015, true, 0, false);
data.yaw = mapJoystickValues( analogRead(A2), 1, 505, 1020, true, 3, true);
data.pitch = mapJoystickValues( analogRead(A0), 12, 544, 1021, false, -25, true);
data.roll = mapJoystickValues( analogRead(A1), 34, 522, 1020, false,-6, true );
data.otherData = rd;
data.AUX1 = digitalRead(4); //The 2 toggle switches
data.AUX2 = digitalRead(5);
radio.write(&data, sizeof(MyData));
lcdUpdate();
}
void lcdUpdate()
{
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
leftLCD.clear();
rightLCD.clear();
// LEFT LED
leftLCD.setCursor(0,0);
leftLCD.print("Throttle: ");
leftLCD.setCursor(13,0);
leftLCD.print(data.throttle);
leftLCD.setCursor(0,1);
leftLCD.print("Yaw: ");
leftLCD.setCursor(13,1);
leftLCD.print(data.yaw);
// DELAY BEFORE RESET
// LEFT LED
rightLCD.setCursor(0,0);
rightLCD.print("Pitch: ");
rightLCD.setCursor(13,0);
rightLCD.print(data.pitch);
rightLCD.setCursor(0,1);
rightLCD.print("Rpll: ");
rightLCD.setCursor(13,1);
rightLCD.print(data.roll);
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}