This is my setup:
I'm making a wireless connection to control some servo's.
I have two nRF24 modules: a transmitter that's connected to an arduino Uno, which is connected to an android tablet via USB. The tablet sends a byte for each servo to the Uno through its Serial connection. The Uno just sends these through SPI to the transmitter.
The receiver sends these bytes to an arduino Mega and sets the servos position.
What's wrong:
After powering both microcontrollers I can successfully control the servo via the joystick on the tablet, it works perfectly and its very accurate.
However it only works when I control the servo very slowly or make slow adjustments on the joystick. As soon as I make a rapid change of position of the servo or make a rapid jerk or swipe on the joystick, the servo stops responding.
What I know.
I suspect the problem lies with the amount of transmissions per timeframe as that amount spikes when I make a rapid change because data is only transmitted when its changed.
I'm also sure that the problem lies with the receiver as everything seems to be working fine again only when I reset the microcontroller on the receiving end.
The Mega still seems to be running as it keeps printing out to Serial.
After debugging in the code, it seems that radio.available() keeps returning false (yes, even without the boolean newData).
Diagram.
Transmitter Code.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN // 5 = D1, 4 = D2
const byte address[6] = "00001";
bool newData = false;
int const byteCount = 5;
byte dataBytes[byteCount];
byte const startMarker = 0x03;
byte const endMarker = 0xfc;
void setup() {
Serial.begin(115200);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(125);
radio.stopListening();
}
void loop() {
receive();
writeNewDataNRF();
}
//syncs Serial data
void receive(){
static boolean recvInProgress = false;
static int count = 0;
byte read;
while(Serial.available() > 0 && !newData){
read = Serial.read();
if(recvInProgress){
if(read != endMarker){
dataBytes[count] = read;
count++;
}
else{
recvInProgress = false;
count = 0;
newData = true;
}
}
else if(read == startMarker){
recvInProgress = true;
}
}
}
void writeNewDataNRF(){
if(newData){
byte payload[] = {
dataBytes[0],
dataBytes[1],
dataBytes[2],
dataBytes[3],
dataBytes[4]
};
radio.write(&payload,sizeof(payload));
newData = false;
}
}
Receiver Code.
#include <Servo.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
byte readByte[5];
Servo rudder;
Servo throttle;
Servo aileronL;
Servo aileronR;
Servo elevator;
Servo flaps;
RF24 radio(26, 27); //CE, CSN
const byte address[6] = "00001";
bool newData = false;
int const bytes = 5;
int positions[bytes];
void setup() {
rudder.attach(2);
throttle.attach(3);
aileronL.attach(4);
aileronR.attach(5);
elevator.attach(6);
flaps.attach(7);
Serial.begin(115200);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(125);
radio.startListening();
}
void loop() {
receive();
assignNewData();
Serial.println("I'm still running here!");
}
void receive(){
if(radio.available() && !newData){
radio.read(&readByte, sizeof(readByte));
newData = true;
}
}
void assignNewData(){
if(!newData){
return;
}
int rudderRead = int(readByte[0]);
float rudderRatio = rudderRead / 255.0;
int rudderPos = 180.0 * rudderRatio;
Serial.println(rudderPos);
// int throttleRead = int(readByte[1]);
// float throttleRatio = throttleRead / 255.0;
// int throttleMicroSec = 1000.0 + (2000.0 * throttleRatio);
// int aileronRead = int(readByte[2]);
// float aileronRatio = aileronRead / 255.0;
// int aileronPos = 180.0 * aileronRatio;
// int elevatorRead = int(readByte[3]);
// float elevatorRatio = elevatorRead / 255.0;
// int elevatorPos = 180.0 * elevatorRatio;
// byte auxByte = readByte[4];
// byte flapsByte = (auxByte & 0b00011100) >> 2;
// int flapsRead = int(flapsByte);
// float flapsRatio = flapsRead / 4.0;
// int flapsPos = 180.0 * flapsRatio;
// bool noseLights = false;
// byte noseLightsByte = (auxByte & 0b00100000);
// if(noseLightsByte == 0b01000000)
// noseLights = true;
// else
// noseLights = false;
rudder.write(rudderPos);
// throttle.writeMicroseconds(throttleMicroSec);
// aileronL.write(aileronPos);
// aileronR.write(180 - aileronPos);
// elevator.write(elevatorPos);
// flaps.write(flapsPos);
newData = false;
}
