Hello!
I am trying to make a rc airplane with arduinos. I am currently fighting with the NRF24l01 to work because it will not seem to work. Before anyone says anything, I did solder a 10uf capacitor to the pwr and ground pins on both the nrfs with no luck. Additionally I have checked the power with a multimeter and it is staying solidly at 3.3 with no signs of instability. I also triple checked the wiring of both of them. I also twisted a ground wire around both the miso and mosi wires for both the receiver and the transmitter, again with no luck. I also tried replacing the nrf's with other modules I have around and still had no luck.
I also tried another program and it seemed to work and transmitted and recieved properly so it seems the problem is for sure in the code.
Here is the transmitter code(Arduino Uno):
/*
DIY Arduino based RC Transmitter
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Define the digital inputs
#define jB1 1 // Joystick button 1
#define jB2 0 // Joystick button 2
#define t1 7 // Toggle switch 1
#define t2 4 // Toggle switch 1
#define b1 8 // Button 1
#define b2 9 // Button 2
#define b3 2 // Button 3
#define b4 3 // Button 4
float elapsedTime, currentTime, previousTime;
int c = 0;
RF24 radio(5, 6); // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; //Create a variable with the above structure
void setup() {
Serial.begin(9600);
// Initialize interface to the MPU6050
// Call this function if you need to get the IMU error values for your module
//calculate_IMU_error();
// Define the radio communication
radio.begin();
radio.openWritingPipe(address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
// Activate the Arduino internal pull-up resistors
pinMode(jB1, INPUT_PULLUP);
pinMode(jB2, INPUT_PULLUP);
pinMode(t1, INPUT_PULLUP);
pinMode(t2, INPUT_PULLUP);
pinMode(b1, INPUT_PULLUP);
pinMode(b2, INPUT_PULLUP);
pinMode(b3, INPUT_PULLUP);
pinMode(b4, INPUT_PULLUP);
// Set initial default values
data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}
void loop() {
// Read all analog inputs and map them to one Byte value
data.j1PotX = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
data.j1PotY = map(analogRead(A0), 0, 1023, 0, 255);
data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);
// Read all digital inputs
data.j1Button = digitalRead(jB1);
data.j2Button = digitalRead(jB2);
data.tSwitch2 = digitalRead(t2);
data.button1 = digitalRead(b1);
data.button2 = digitalRead(b2);
data.button3 = digitalRead(b3);
data.button4 = digitalRead(b4);
// If toggle switch 1 is switched on
// Send the whole data from the structure to the receiver
radio.write(&data, sizeof(Data_Package));
Serial.println(data.j1PotX);
}
And here is the receivers code(Teensy 4.0):
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
RF24 radio(10, 9); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
Servo throttle1; // create servo object to control the ESC
Servo throttle2;
Servo rudderServo;
Servo elevatorServo;
Servo aileron1Servo;
Servo aileron2Servo;
int throttleValue, rudderValue, elevatorValue, aileron1Value, aileron2Value, travelAdjust;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; //Create a variable with the above structure
void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 80; // Motors stops // the central point of the joystick is not starting point for the throttle, its at value of 80 instead of 127
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.startListening(); // Set the module as receiver
resetData();
throttle1.attach(2);
throttle2.attach(4);
rudderServo.attach(7); // CH1
elevatorServo.attach(8); // CH2
aileron1Servo.attach(5); // CH3
aileron2Servo.attach(6); // CH4
// throt L - 2
// throt R - 4
// alerion L - 5
// alerion R - 6
// rud - 7
// elevator - 8
}
void loop() {
// Check whether we keep receving data, or we have a connection between the two modules
currentTime = millis();
if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
}
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data
}
// Controlling throttle - brushless motor with ESC
throttleValue = constrain(data.j1PotY, 80, 255); // Joysticks stays in middle. So we only need values the upper values from 130 to 255
throttleValue = map(throttleValue, 80, 255, 1000, 2000);
throttle1.writeMicroseconds(throttleValue);
throttle2.writeMicroseconds(throttleValue);
// Adjusting the servos responsiveness
travelAdjust = map(data.pot2, 0, 255, 0, 25);
// Elevator control
elevatorValue = map(data.j2PotY, 0, 255, (85 - travelAdjust), (35 + travelAdjust));
elevatorServo.write(elevatorValue);
// Ailerons control
aileron1Value = map(data.j2PotX, 0, 255, (10 + travelAdjust), (80 - travelAdjust));
aileron1Servo.write(aileron1Value);
aileron2Servo.write(aileron1Value);
// Rudder trimming function
if (data.j1PotX > 127) {
rudderValue = data.pot1 + (data.j1PotX - 127);
}
if (data.j1PotX < 127) {
rudderValue = data.pot1 - (127 - data.j1PotX);
}
// Rudder control
rudderValue = map(rudderValue, 0, 255, (10 + travelAdjust), (90 - travelAdjust));
rudderServo.write(rudderValue);
Serial.println(data.j1PotX);
}
It is code I used from a tutorial by "How to Mechatronics" and edited to fit my needs.
Currently on the serial monitor for the transmitter it outputs the value of j1PotX as it should, but the receiver just outputs 127, which is the value it should output if it has no signal.
Can someone give me a list of more things to trouble shoot the nrf modules or show me how to fix my code so it works properly? Thank you!