Control 2 servos and 2 leds through NRF24L01

I have a problem with control of 2 servos (x,y) and 2 leds through the module nrfl01.

My task is to control blinking of 4 leds and 4 servos independently, but first i try with just 2 servos and 2 leds and there is a problem and servos doesnt rotate + leds are not blink.

I have no idea what im doing wrong.

Can anyone help with this?

Code for Transmitter:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int pos[2]; // serwa x i y 
int led[2]; // led a i b
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int posx;
int posy;
void setup(void){
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);}

void loop(void){
posx = analogRead(A0); 
posx = map(posx, 0, 1023, 0, 180); 
posy = analogRead(A1);          
posy = map(posy, 0, 1023, 0, 180); 
pos[0]=posy;
pos[1]=posx;
radio.write(pos, sizeof(pos));
if (digitalRead(1)==HIGH){
led[0]=1;
radio.write(led, sizeof(led));
}
else{
led[0]=0;
 }
if (digitalRead(2)==HIGH){
led[1]=1;
radio.write(led, sizeof(led));
}
else{
led[1]=0;
 }
}

Code for Reviver:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int pos[2]; // serwa x i y 
int led[2]; // led a i b
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int posx;
int posy;
void setup(void){
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);}

void loop(void){
posx = analogRead(A0); 
posx = map(posx, 0, 1023, 0, 180); 
posy = analogRead(A1);          
posy = map(posy, 0, 1023, 0, 180); 
pos[0]=posy;
pos[1]=posx;
 radio.write(pos, sizeof(pos));
  if (digitalRead(1)==HIGH){
  led[0]=1;
  radio.write(led, sizeof(led));
  }
else{
led[0]=0;
  }
 if (digitalRead(2)==HIGH){
 led[1]=1;
  radio.write(led, sizeof(led));
  }
 else{
   led[1]=0;
   }
}

michalm92: I have no idea what im doing wrong.

You are posting the wrong code, the receiver code is the same as the transmitter code. (probably cut&paste error)

You should send all the information in one packet. In the moment there is no way for the receiver to distinguish between led and pos packets.

You should not send packets in such an unmoderated back to back fashion.

As you are mapping the positions to values between 0 and 180, a byte would work.

You could use something like

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct packet {
  byte posx;
  byte posy;
  byte led1;
  byte led2;
} State;

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
unsigned long lastSend;
const unsigned int sendInterval = 200;
const byte button1Pin = 2;
const byte button2Pin = 3;

void setup(void) {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
}

void loop(void) {
  if (millis() - lastSend >= sendInterval) {
    lastSend = millis();
    State.posx = map(analogRead(A0), 0, 1023, 0, 180);
    State.posy = map(analogRead(A1), 0, 1023, 0, 180);
    State.led1 = digitalRead(button1Pin);
    State.led2 = digitalRead(button2Pin);
    radio.write(&State, sizeof(State));
  }
}

P.S. I changed the button on pin 1 to pin 3.

This Simple nRF24L01+ Tutorial may get you started.

IMHO the simplest way to organize the data is as a small array

int dataToSend[4];

and in the 4 array spaces store (in order) the value for the first servo position, the second servo, the first LED value and the second LED value.

Then you can send the whole thing with

rslt = radio.write( &dataToSend, sizeof(dataToSend) );

I am, of course, assuming you have an identical array in the receiving program.

...R

Robin2:
This Simple nRF24L01+ Tutorial may get you started.

IMHO the simplest way to organize the data is as a small array

int dataToSend[4];

and in the 4 array spaces store (in order) the value for the first servo position, the second servo, the first LED value and the second LED value.

Then you can send the whole thing with

rslt = radio.write( &dataToSend, sizeof(dataToSend) );

I am, of course, assuming you have an identical array in the receiving program.

…R

Sorry, of course it was copy&paste mistake.

So, the reciver code which i used is:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int pos[2]; // serwa x i y
int led[2]; // led a i b

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
#include <Servo.h> 

Servo servox; 
Servo servoy;
void setup(void){
  servox.attach(3);
  servoy.attach(5);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();
}
void loop(void){
 
if (radio.available()){
  bool done = false;    
  while (!done){

radio.read(pos, sizeof(pos));      
    Serial.println(pos[0]);
    Serial.println(pos[1]);
    servox.write(pos[0]);
    servoy.write(pos[1]); 
    delay(10);
    radio.read(led, sizeof(led));
if (led[0]==1){digitalWrite(1,HIGH);}
else{digitalWrite(1,LOW);}
if (led[1]==1){digitalWrite(2,HIGH);}
else{digitalWrite(2,LOW);}

}}}

So Robin2, i tried to transmit data in the same way (through array with 4 int elements) and it didnt work properly. I have no idea what is wrong. i am sure that pins are connected well.

Whandall, thanks for transmiter code. Can you tell me what in the reciver code which i have write (below) is not ok? I ask because it is not displaying in serial monitor any values ;/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct packet {
  byte posx;
  byte posy;
  byte led1;
  byte led2;
} State;

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
#include <Servo.h> 
 
Servo myservo; 
Servo myservo2;
void setup(void){
   myservo.attach(3);
   myservo2.attach(5);
 Serial.begin(9600);
 radio.begin();
 radio.openReadingPipe(1,pipe);
 radio.startListening();
 pinMode(LED1, OUTPUT);
 pinMode(6, OUTPUT);}
void loop(void){
  
 if (radio.available()){
   bool done = false;    
   while (!done){

radio.read(&State, sizeof(State));      
     Serial.println(State.posx);
     myservo.write(State.posx); 
     Serial.println(State.posy);
     myservo2.write(State.posy); 
          Serial.println(State.led1);
               Serial.println(State.led2);


delay(10);




     }
  
   }}

michalm92:
I ask because it is not displaying in serial monitor any values ;/

It is hard for a non-compiling program to show something via Serial.

'LED1' was not declared in this scope

How about something like

#include <Servo.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct packet {
  byte posx;
  byte posy;
  byte led1;
  byte led2;
} State;

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
const byte LED1 = 4; // ??
const byte LED2 = 6;

Servo myservo;
Servo myservo2;

void setup(void) {
  myservo.attach(3);
  myservo2.attach(5);
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.startListening();
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}

void loop(void) {
  if (radio.available()) {
    radio.read(&State, sizeof(State));
    myservo.write(State.posx);
    myservo2.write(State.posy);
    Serial.print(State.posx);
    Serial.print(F(", "));
    Serial.print(State.posy);
    Serial.print(F(", "));
    Serial.print(State.led1);
    Serial.print(F(", "));
    Serial.println(State.led2);
  }
}

I have rearranged your Rx code from Reply #4 so it is easier to read

void loop(void){

    if (radio.available()){
        bool done = false;    
        while (!done) {
            radio.read(pos, sizeof(pos));      
            Serial.println(pos[0]);
            Serial.println(pos[1]);
            servox.write(pos[0]);
            servoy.write(pos[1]);
            delay(10);
            radio.read(led, sizeof(led));
            if (led[0]==1){
                digitalWrite(1,HIGH);
            }
            else {
                digitalWrite(1,LOW);
            }
            if (led[1]==1){
                digitalWrite(2,HIGH);
            }
            else {
                digitalWrite(2,LOW);
            }
        }
    }
}

This can't possibly work for a couple of reasons.

First, there is nothing inside the WHILE to change the variable done to true. I think you can safely delete the two lines

    bool done = false;    
        while (!done) {

and the corresponding closing }

Second, you are (I think) trying to receive 4 values - 2 servos and 2 leds - but your array pos[] only has room for 2 values.

Using a struct as @Whandall recommends is neater, but I had thought it might be confusing to introduce the concept - especially as the arrays will work with my tutorial examples.

...R

Whandall, thank you very much, it works great!

However i have one question: pins 0 and 1 are not avaliable for make them output? They are occupied by module nfr24l01 or something?

On a standard Arduino pins 0 and 1 are occupied by Serial.

hey whandall you really helped a lot.I used the above code retwitched by you and was able to control 2 servos but i wanna control 4 servos and 1 bldc since i making a plane using an arduino a nrf and servos and bldc. i couldn’t use it for 4 servos since as i modified it for 4 one of the 2 servos worked perfectly but other one didn’t show continuous motion . CAN you please modify the above code to control 4 servos and one bldc for me please
here is modification of the code

//TRANSMITTER//
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct packet {
  byte posx;
  byte posy;
  byte posz;
  byte posr;
} State;

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
unsigned long lastSend;
const unsigned int sendInterval = 200;

void setup(void) {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
}

void loop(void) {
  if (millis() - lastSend >= sendInterval) {
    lastSend = millis();
    State.posx = map(analogRead(A0), 0, 1023, 0, 180);
    State.posy = map(analogRead(A1), 0, 1023, 0, 180);
    State.posz = map(analogRead(A2), 0, 1023, 0, 180);
    State.posr = map(analogRead(A3), 0, 1023, 0, 180);
    radio.write(&State, sizeof(State));
  }
}
//RECIEVER//
#include <Servo.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct packet {
  byte posx;
  byte posy;
  byte posz;
  byte posr;
} State;

RF24 radio(9, 10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
Servo myservo;
Servo myservo2;
Servo myservo3;
Servo myservo4;

void setup(void) {
  myservo.attach(3);
  myservo2.attach(5);
  myservo3.attach(6);
  myservo4.attach(8);
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.startListening();
 
}

void loop(void) {
  if (radio.available()) {
    radio.read(&State, sizeof(State));
    myservo.write(State.posx);
    myservo2.write(State.posy);
    myservo3.write(State.posz);
    myservo4.write(State.posr);
    Serial.print(State.posx);
    Serial.print(F(", "));
    Serial.print(State.posy);
    Serial.print(F(", "));
    Serial.print(State.posz);
    Serial.print(F(", "));
    Serial.println(State.posr);
  }
}

I can't see anything in your code dealing with a "bldc". What is that? What is it connected to?

You say you modified the code for 4 servos but " one of the 2 servos worked perfectly but other one didn't..." That doesn't make any sense.

And how do you plan to control 5 things if you're only transmitting 4 pieces of information?

Steve

In addition to the questions of @slipstick:

What value were transmitted? (Please post the output of the receivers serial monitor). Were the transmitted values plausible?

well thanks for replying i haven't yet added anything for bldc but i will be controlling it as same as servo. i am not able to control all 4 servos altogether that is the code provided by whandall works perfectly for 2 servos but when i moded it for 4 there is not continuos motion that is they are looks like using each others value provided by the radio they are not stable earlier weren't working i thought but now all 4 work i hope you could understand what i meant to say

I don't do word puzzles, sorry.

Your unstructured gush of words does not make sense to me.

Why didn't you provide answers to the questions?

really sorry whandall i was actually struck and so wrote an ununderstandable message well power seemed to be the problem in my case since earlier i was using only arduino connected to mac via usb but then i added external 5v=600ma phone charger to the vin and they are working perfectly now .THANKYOUY FOR HELPING AND SORRY FOR EARLIER MESSAGE . i wanted to know can we use pins other than pwm for servo since out of 6 pwms on uno 3 preoccupied by nrf so since i need 5 i have only 3 available and plan to use pin 7 ,8 for one servo and esc thank you

Archut: really sorry whandall i was actually struck and so wrote an ununderstandable message well power seemed to be the problem in my case since earlier i was using only arduino connected to mac via usb but then i added external 5v=600ma phone charger to the vin and they are working perfectly now .THANKYOUY FOR HELPING AND SORRY FOR EARLIER MESSAGE . i wanted to know can we use pins other than pwm for servo since out of 6 pwms on uno 3 preoccupied by nrf so since i need 5 i have only 3 available and plan to use pin 7 ,8 for one servo and esc thank you

You seem to have done it again.

Try reading your post out loud and see if it makes sense.

Have you heard of things called paragraphs?

...R

Sorry once again.Now that I am able to control my 4 servos with it of which I power servos with a lipo. I want to know whether is there any way that the Arduino connected to servos set as reciver act as transmitter to to let me know the battery voltage. I'll be connected the lipo with resistors to arduinos analog pin . And in transmitter side I use two joystick modules and power it with 5v usb and want to receive battery voltage on LCD module

Archut: I want to know whether is there any way that the Arduino connected to servos set as reciver act as transmitter to to let me know the battery voltage.

You could use acknowledge payloads for transmitting the battery level back.

Robin2 has an example for acknowledge payloads in his NRF24L01+ samples.

well i just went through it is a really nice example but will it work with the maniac bug library since my whole code is based on that .I don't have that much experience so ill try to modify it to fit in my code

Archut: will it work with the maniac bug library since my whole code is based on that

So change it to compile with the new library, there are only minor incompatibilities.