Remote control

I'm having ago at creating a remote control system for a machine, This drives forwards,backwards,steer left&right and possible lift function. I'm using NRF24L01 and some nano's, the code attached is working, so far I'm just consecrating on drive forward and backwards. The TX sends the signal to the RX everything is working quite well, At the moment I've just got some LED'S on the outputs but the trouble I'm having is the joystick reaches 70(ADC value) on the display and before Rx unit turns the LED'S on for drive it forward and backward LED'S come on, But the bit I'm not happy with that the PWM signal starts to glow the drive signal control voltage on before the outputs come on, This would cause the machine to jolt slightly on initial drive. I think I need some sort of threshold system for the joystick ??
Is there away in code I could stop this from happening ?
Here is the link to the joystick

This is the 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);

}

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

First of all, if you add some whitespace it makes your writing much easier to read - like this

I'm having a go at creating a remote control system for a machine, This drives forwards,backwards,steer left&right and possible lift function.

I'm using NRF24L01 and some nano's, the code attached is working, so far I'm just consecrating on drive forward and backwards. The TX sends the signal to the RX everything is working quite well,

At the moment I've just got some LED'S on the outputs but the trouble I'm having is the joystick reaches 70(ADC value) on the display and before Rx unit turns the LED'S on for drive it forward and backward LED'S come on,

But the bit I'm not happy with that the PWM signal starts to glow the drive signal control voltage on before the outputs come on,

This would cause the machine to jolt slightly on initial drive. I think I need some sort of threshold system for the joystick ??

Is there away in code I could stop this from happening ?

Second, if you are having problems with the joystick values just write a short program that reads the joystick, displays the value on the Serial Monitor and makes the LEDs light (I am assuming you are using the LEDs as a proxy for the motor).

That way you can concentrate on the problem. It will also make it much easier to help you.

I don't think you can judge the existence of a startup "jolt" without actually trying the motor with its normal load.

...R
Simple nRF24L01+ Tutorial

PS... You are "concentrating". "Consecrating" is what Bishops do :slight_smile:

Thanks Robin
I think your correct I need to test on the motor controller and see how it works in real life

I've measured the output voltage at the pin and it's 0.5v volts so it may not be a problem.

On the LCD I've added the value of the pot on the TX unit as in the centre position I get 2.5V and used the function below to make it 0 and it converts the value to read 0-818 ADC in either direction.

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 );
}

This function seems to work very well.

Would just like to see if I can make the ouput signal start at 0 until it receives the forward/backwards signal at the same time.

From testing the motor controller with the original set up 0.5V just starts to turn the motor but will not be able to test my code until Monday when I'm back at work

Thanks for spotting my mistake thought it did not look right :slight_smile: