How to control the motors by potentiometer one on one with nRF24L01?

Hello everyone!
I need some help.
I had tried to control two brushless motor by two potentiometer, and had succeeded.
Now, I want to sent the signal of potentiometer by nRF24L01.
The wiring schemes and codes like the photos.
The problem is that when I turn on the "potentiometer 1", the "motor 1" doesn't move.
When I turn on the "potentiometer 2", the "motor 2" doesn't move too.
when I turn on the "potentiometer 1" and "potentiometer 2" simultaneously, the "motor 1" doesn't move, but the "motor 2" is move.
I want to control the motors one on one.
How can I fix it?


#include <SPI.h>
#include <RF24.h>
 
RF24 radio(7, 8); // CE, CSN
const byte addresses[] = "1Node";
 
void setup() {
  radio.begin();
  radio.setChannel(83);
  radio.openWritingPipe(addresses);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
 
void loop() {
  delay(5);
  int potValue1 = analogRead(A1);
  int angleValue1 = map(potValue1, 0, 1023, 90, 180);
  radio.write(&angleValue1, sizeof(angleValue1));
  int potValue2 = analogRead(A2);
  int angleValue2 = map(potValue2, 0, 1023, 90, 180);
  radio.write(&angleValue2, sizeof(angleValue2));
}
#include <SPI.h>
#include <RF24.h>
#include <Servo.h>
 
RF24 radio(7, 8); // CE, CSN
const byte addresses[] = "1Node";
const byte pipe = 1;
Servo myServo1;
Servo myServo2;
 
void setup() {
  myServo1.attach(10);
  myServo2.attach(11);
  radio.begin();
  radio.setChannel(83);
  radio.setPALevel(RF24_PA_MIN);
  radio.openReadingPipe(pipe, addresses);
  radio.startListening();
}
 
void loop() {
  if (radio.available()) {
    int angleValue1 = 0;
    radio.read(&angleValue1, sizeof(angleValue1));
    myServo1.write(angleValue1);
    int angleValue2 = 0;
    radio.read(&angleValue2, sizeof(angleValue2));
    myServo2.write(angleValue2);
    }
}

Check the values being sent by printing them before sending. Check the values being received when they are received.

How does the receiving system know which value is associated with which servo ?

You should make a 2 int buffer on the transmitter and send both values at the same time to a 2 int buffer on the receiver.

This Simple nRF24L01+ Tutorial may be of interest.

I think your system would be more reliable if you send both values in the same message. That way there can be no doubt about which value belongs to which Pot. Put the two values into an array and send the array.

...R

Hello everybody! I try to rewrite the code. I add a "struct" to combined two value into one message. Is it an array? I hope this is correct. So I can send the value in single package at the same time. I haven't tried it yet. I'll do it as soon as possible.

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

#define potValue_1   A1
#define potValue_2   A2

RF24 radio(7, 8); // CE, CSN
const byte addresses[] = {"1Node"};
struct dataStruct {
  int angleValue_1;         
  int angleValue_2;   
  } myData;  

void setup() {
  radio.begin();
  radio.setChannel(83);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.openWritingPipe(addresses[0]);
  radio.stopListening();
}

void loop() {
  myData.angleValue_1 = map(potValue_1, 0, 1023, 90, 180);
  myData.angleValue_2 = map(potValue_2, 0, 1023, 90, 180);
  radio.write( &myData, sizeof(myData));
}
#include <SPI.h>
#include <RF24.h>
#include <Servo.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[] = "1Node";
const byte pipe = 1;
Servo myServo_1;
Servo myServo_2;
struct dataStruct {
  int angleValue_1;          
  int angleValue_2;
  } myData;

void setup() {
  myServo_1.attach(5);
  myServo_2.attach(6);
  radio.begin();
  radio.setChannel(83);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(pipe, addresses[0]);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    while (radio.available()) {
      radio.read( &myData, sizeof(myData) );
      myServo_1.write(myData.angleValue_1);
      myServo_2.write(myData.angleValue_2);
      }
    }
}

The advice was to put the 2 values in an array. A struct is not an array.

The OP's struct should work fine. I just suggested an array because I thought it would be a simpler concept for a newbie.

The important thing is to have the exact same data structure on the receiver and the sender.

...R

This is how I did mine and work in progress, This should be help you,

You will need to modify the code to suit your own, So far this works reliable

TX code

#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#define  FWD_input  3 //forward signal from joystick
#define BCK_input 4 //reverse signal from joystick
#define SL_input 5 //steer left input
#define SR_input 6 //sterr right input
#define Lift_input 7 //left select drive default
boolean fwd_dat = 0; //set the forward signal to 0
boolean bck_dat = 0;//set backwards siganl to 0
boolean sl_dat = 0; //set steer left signal to 0
boolean sr_dat = 0; //set sterr right to 0
boolean lift_dat = 0; //set lift to 0
const uint64_t pipeOut = 0xE8E8F0F0E1LL; //IMPORTANT: The same as in the receiver
float input_voltage = 0.0;
RF24 radio(9, 10); // select  CSN  pin

// The sizeof this struct should not exceed 32 bytes
// This gives us up to 32 8 bits channals
struct MyData {
  int throttle; //throttle signal
  byte Steer_left;//sterr left
  byte Steer_right; //Steer right signal
  byte DRV_FWD; //drive forwards
  byte DRV_BCK; //drive backwards
  byte Lift; //left signal
};

MyData data;

void resetData()
{
  //This are the start values of each channal
  // Throttle is 0 in order to stop the motors
  data.throttle = 0;
  data.Steer_left = 0; //Steer left signal
  data.Steer_right = 0;
  data.DRV_FWD = 0;
  data.DRV_BCK = 0;
  data.Lift = 0;
}

void setup()
{
  Serial.begin(115200);
  lcd.begin(16, 2);
  pinMode(FWD_input, INPUT_PULLUP);
  pinMode(BCK_input, INPUT_PULLUP);
  pinMode(SL_input, INPUT);
  pinMode(SR_input, INPUT);
  pinMode(Lift_input, INPUT);
  radio.begin();
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipeOut);
  resetData();
  lcd.clear();
}


void loop()
{
  sl_dat  = digitalRead(SL_input); //Steer left signal
  sr_dat  = digitalRead(SR_input); //Steer right signal
  fwd_dat     = digitalRead(FWD_input); //Drive forward signal
  bck_dat    = digitalRead(BCK_input); //Drive Reverse signal
  lift_dat     = digitalRead(Lift_input); //Select lift drive default
  if (fwd_dat == LOW) {
    data.DRV_FWD = 10;
    lcd.setCursor(0, 1);
    lcd.print("FORWARD");
  }
  else {
    data.DRV_FWD = 0;
    lcd.setCursor(0, 1);
    lcd.print("        ");
  }
  if (bck_dat == LOW) {
    data.DRV_BCK  = 12;
    lcd.setCursor(0, 1);
    lcd.print("BACKWARD");
  }
  else {
    data.DRV_BCK  = 0;
    lcd.setCursor(0, 1);
    lcd.print("        ");
  }
  lcd.setCursor(0, 0);
  lcd.print(data.throttle);
  lcd.print("  ");
  data.throttle = mapJoystickValues( analogRead(A0), 0, 507, 1023, true );
  input_voltage = (data.throttle * 5.0) / 1024.0;
  radio.write(&data, sizeof(MyData));
}

/// 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)
{
  val = constrain(val, lower, upper);
  if ( val < middle )
    val = map(val, lower, middle, 0, 1023);
  else
    val = map(val, middle, upper, 1023, 0);
  return ( reverse ? 1023 - val : val );
}

RX code

#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#define  FWD_input  3
#define BCK_input 4
//#define SL_input 5
//#define SR_input 6
//#define Lift_input 7
const uint64_t pipeIn =  0xE8E8F0F0E1LL;
RF24 radio(9, 10);
int val;
// The sizeof this struct should not exceed 32 bytes
// This gives us up to 32 8 bits channals
struct MyData {
  int throttle; //throttle signal
  byte Steer_left;//sterr left
  byte Steer_right; //Steer right signal
  byte DRV_FWD; //drive forwards
  byte DRV_BCK; //drive backwards
  byte Lift; //left signal
};

MyData data;

void resetData()
{
  //This are the start values of each channal
  // Throttle is 0 in order to stop the motors
  data.throttle = 0;
  data.Steer_left = 0; //Steer left signal
  data.Steer_right = 0;
  data.DRV_FWD = 0;
  data.DRV_BCK = 0;
  data.Lift = 0;
}
/**************************************************/
void setup()
{
  pinMode(FWD_input, OUTPUT); //setup the drive forward pin
  pinMode(BCK_input, OUTPUT);//setup the drive backwards pin
  // pinMode(SL_input, OUTPUT); //setup steer left pin
  // pinMode(SR_input, OUTPUT);//setup steer right pin
  //  pinMode(Lift_input, OUTPUT); //set up lift pin
  resetData();
  lcd.begin(16, 2);
  radio.begin();
  radio.setDataRate(RF24_250KBPS); // Both endpoints must have this set the same
  radio.setAutoAck(false);
  lcd.clear();
  radio.openReadingPipe(1, pipeIn);
  radio.startListening();
}
/**************************************************/
unsigned long lastRecvTime = 0;

void recvData()
{
  while ( radio.available() ) {
    radio.read(&data, sizeof(MyData));
    lastRecvTime = millis();
  }
}

/**************************************************/
void loop()
{
  recvData();
  unsigned long now = millis();
  if ( now - lastRecvTime > 1000 ) { //if data stops coming turn everything off with a second
    // signal lost?
    resetData();
  }
  if (data.DRV_FWD == 10) { // if we recieve a 10 turn on drive forward coil
    digitalWrite(FWD_input, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("FORWARD");
  }
  else {
    digitalWrite(FWD_input, LOW);
    lcd.setCursor(0, 1);
    lcd.print("        ");
  }
  if (data.DRV_BCK == 12) { // if we recieve a 12 turn on drive backwards coil
    digitalWrite(BCK_input, HIGH);
    lcd.setCursor(0, 1);
    lcd.print("BACKWARD");
  }
  else {
    digitalWrite(BCK_input, LOW);
    lcd.setCursor(0, 1);
    lcd.print("        ");
  }
  lcd.setCursor(0, 0);
  lcd.print(data.throttle); //fro debugging data
  lcd.print("  ");
  // sensorValue = data.throttle;

  val = map(data.throttle, 0, 818, 0, 255); //write the pwm signal to motor controller
  analogWrite(6, val);

}

/**************************************************/

Hi! Everyone. I think I have solved the problem. After I add a "struct" to combined two values into one message. Now, I can control the motors by potentiometers one on one. Thank you very much!!

Here's the code

Transmit

#include <SPI.h>
#include <RF24.h>
 
RF24 radio(7, 8); // CE, CSN
const byte addresses[] = {"1Node"};
struct dataStruct {
  int angleValue_1;      
  int angleValue_2;
  } myData;
 
void setup() {
  radio.begin();
  radio.setChannel(83);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.openWritingPipe(addresses[0]);
  radio.stopListening();
}
 
void loop() {
  int potValue_1 = analogRead(A1);
  int potValue_2 = analogRead(A2);
  myData.angleValue_1 = map(potValue_1, 0, 1023, 90, 180);
  myData.angleValue_2 = map(potValue_2, 0, 1023, 90, 180);
  radio.write( &myData, sizeof(myData));
}

Receive

#include <SPI.h>
#include <RF24.h>
#include <Servo.h>
 
RF24 radio(7, 8); // CE, CSN
const byte addresses[] = "1Node";
const byte pipe = 1;
Servo myServo_1;
Servo myServo_2;
struct dataStruct {
  int angleValue_1;        
  int angleValue_2;
  } myData;
 
void setup() {
  myServo_1.attach(5);
  myServo_2.attach(6);
  radio.begin();
  radio.setChannel(83);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(pipe, addresses[0]);
  radio.startListening();
}
 
void loop() {
  if (radio.available()) {
    while (radio.available()) {
      radio.read( &myData, sizeof(myData) );
      myServo_1.write(myData.angleValue_1);
      myServo_2.write(myData.angleValue_2);
      }
    }
}