Go Down

Topic: nrf24l01 + old aritronics + L298N need a little help. (Read 743 times) previous topic - next topic

jonawadl

Hi there. I'm trying to get a basic R/C tank setup going for my son. The setup will have one Servo in the mix too.

I started out by downloading and trying to work with the code from here, Even though the tank in the video seems to work as expected, when I read through the code I found a few flaws and my controller did not work as expected.

The biggest problem with this code was that there was no allowance for speed control. The motors were simply on/off for. For the project I am working on, I want to implement the INA pins on the L298N to control motor speed.

After I discovered that problem in the code, I went hunting for a further example to work from and found another person who had shared his code. This person used a very different method but also used an ESC instead of the L298N and only one motor. I was still able to gather some knowledge from this and try to piece together some code that would do what I want.

Somewhere I messed up. I have been trying to get this to work for a week now. I used the getting started page to make sure my radios could communicate with the hello world sketch.

I used a read potentiometer sketch to find out that the pots in the Airtronics radio i'm working with have a min. Value of around 320 and a max of around 577 it varies depending on the input I check. I also found I have to find the "rest" value, where the joysticks ended up when they were centered. This was not the center of the range so I modified the range a bit to make this "rest place" the middle of the range.

Here's the code I ended up with. The problem is that the motors don't move at all and, while the servo moves, it does not move as expected. When I push the joystick for it to the far left I can get it the servo to move slowly but as soon as I take it out of that corner it moves to the extreme opposite end. I feel I can get the servo fixed with mapping the value from the joysticks properly, so that's not my big concern right now. What the servo action does tell me is that the signal is coming through form the radio and I messed up the code on the receiver side.

code for transmitter.
Code: [Select]

/*
---- Transmitter Code ----
Mert Arduino Tutorial & Projects (YouTube)
Please Subscribe for Support
*/

#include <SPI.h>                      //the communication interface with the modem
#include "RF24.h"                     //the library which helps us to control the radio modem

//define the input pins
int JOYSTICK0_X = A0;  // Throttle input
int TJOYSTICK0_X = A5; // Throttle trim future use
int JOYSTICK0_Y = A3; // Rudder future use
int TJOYSTICK0_Y = A7; // Rudder trim
int JOYSTICK1_X = A1; // Elevator input
int TJOYSTICK1_X = A4; // elevator trim future use
int JOYSTICK1_Y = A2; // ailerons
int TJOYSTICK1_Y = A6; // aileron trim
int aux_switch0 = 2; // switches as labeled on controler
int aux_switch1 = 3;
int trainer_switch = 4;

//define variable values
int joystick[8];     // array containing 8 joystick readings.


int data[1];

RF24 radio(7,8);                     //7 and 8 are a digital pin numbers to which signals CE and CSN are connected.
                                     
const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem, that will receive data from Arduino.


void setup(void){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  radio.begin();                      //it activates the modem.
  radio.openWritingPipe(pipe);        //sets the address of the receiver to which the program will send data.
}

void loop(){
joystick[0] = analogRead(JOYSTICK0_X); // read Throttle input put into array slot 0
joystick[1] = analogRead(JOYSTICK0_Y); // Rudder to array
joystick[2] = analogRead(JOYSTICK1_X); // Elevator to array
joystick[3] = analogRead(JOYSTICK1_Y); //...
joystick[4] = analogRead(TJOYSTICK0_X);
joystick[5] = analogRead(TJOYSTICK0_Y);
joystick[6] = analogRead(TJOYSTICK1_X);
joystick[7] = analogRead(TJOYSTICK1_Y);

radio.write( joystick, sizeof(joystick) );
}
 



Code for Reciever

Code: [Select]

#include <Servo.h>    //the library which helps us to control the servo motor
#include <SPI.h>      //the communication interface with the modem
#include "RF24.h"     //the library which helps us to control the radio modem (nRF24L)

//define our L298N control pins
//Motor A
const int RightMotorSpeed = 10;     //enA  for speed control
const int RightMotorForward = 2;    // IN1
const int RightMotorBackward = 3;   // IN2
//Motor B
const int LeftMotorSpeed = 5;       //enB for speed control
const int LeftMotorForward = 4;     // IN3
const int LeftMotorBackward = 6;    // IN4
int LeftMSpeed;   // interger to capture speed
int RightMSpeed; // to capture R speed
int BackSpeed;
int ForSpeed;
int rTurnSpeed;
int lTurnSpeed;
int LMotor;
int RMotor;
int joystick[8]; //The element array holding the data from joysticks
int fail = 0; // for when we lose radio range

//define the servo name
Servo myServo;


RF24 radio(7,8);     /*This object represents a modem connected to the Arduino.
                      Arguments 5 and 10 are a digital pin numbers to which signals
                      CE and CSN are connected.*/

const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.



void setup(){
  Serial.begin(115200); // for outputting debuggin information to serial monitor
  delay(3000);
  Serial.println("Nrf24l01 Receiver Starting");
  pinMode(RightMotorSpeed, OUTPUT);
  pinMode(LeftMotorSpeed, OUTPUT);
  pinMode(RightMotorForward, OUTPUT);
  pinMode(LeftMotorForward, OUTPUT);
  pinMode(LeftMotorBackward, OUTPUT);
  pinMode(RightMotorBackward, OUTPUT);

  //define the servo input pins
  myServo.attach(14); //A0
 
  radio.begin();                    //it activates the modem.
  radio.openReadingPipe(1, pipe);   //determines the address of our modem which receive data.
  radio.startListening();           //enable receiving data via modem
  }

void loop()
{
  if(radio.available() )
    {
      { 
       radio.read( joystick, sizeof(joystick) ); // Fetch the data payload

      LMotor = map(joystick[0], 439, 567, 0, 255); // map Joystick0_X
      if(LMotor > 0 && LMotor <123); { //this is backwards
        //Set Left motor backwards
        digitalWrite(LeftMotorForward, LOW);
        digitalWrite(LeftMotorBackward, HIGH);
        analogWrite(LeftMSpeed, LMotor); // PWM signal for left motor speed
        Serial.print("LMotor = ");
        Serial.print(joystick[0]);}
     
     
      if(LMotor > 127 && LMotor < 255); { //this is forwards
        //Set Left motor forwards
        digitalWrite(LeftMotorForward, HIGH);
        digitalWrite(LeftMotorBackward, LOW);
        analogWrite(LeftMSpeed, LMotor);
        Serial.print("LMotor = ");
        Serial.print(joystick[0]);}
    }
    {
    RMotor = map(joystick[2], 491, 525, 0, 255); // map Joystick1_X
    if(RMotor > 0 && RMotor < 123); { //this is backwards
        //Set Right motor backwards
        digitalWrite(RightMotorForward, LOW);
        digitalWrite(RightMotorBackward, HIGH);
        analogWrite(RightMSpeed, RMotor);
        Serial.print("RMotor = ");
        Serial.print(joystick[2]);}

        if(RMotor > 127 && RMotor <255); { //this is forwards
        //Set Left motor forwards
        digitalWrite(RightMotorForward, HIGH);
        digitalWrite(RightMotorBackward, LOW);
        analogWrite(RightMSpeed, RMotor);
        Serial.print("RMotor = ");
        Serial.print(joystick[0]);}
      }
      }
  else
  {
    Serial.println("No radio available");
   
    }
   
    // for the servo motor    {
     myServo.write(joystick[5]);
    }


The serial output on receiver side shows data coming in through the respective joysticks. I know there are a lot of joysticks I'm not using, but I do plan to use this transmitter for other projects in the future.

jonawadl

I forgot to mention the transmitter arduino is a pro mini and the receiver is an uno.

I know there are some mapping issues concerning the pwm for ena and enb. As it stands right now, reverse would be a lot slower than forward but that's ok. I can probably make another int. and map things out again to fine tune that once the motors are actually turning and responding to input.

Robin2

Your receiver code is poorly formatted so it is hard to see where the different blocks start and end.  I have tidied it up here. For the future use the AutoForimat tool
Code: [Select]

#include <Servo.h>    //the library which helps us to control the servo motor
#include <SPI.h>      //the communication interface with the modem
#include "RF24.h"     //the library which helps us to control the radio modem (nRF24L)

//define our L298N control pins
//Motor A
const int RightMotorSpeed = 10;     //enA  for speed control
const int RightMotorForward = 2;    // IN1
const int RightMotorBackward = 3;   // IN2
//Motor B
const int LeftMotorSpeed = 5;       //enB for speed control
const int LeftMotorForward = 4;     // IN3
const int LeftMotorBackward = 6;    // IN4
int LeftMSpeed;   // interger to capture speed
int RightMSpeed; // to capture R speed
int BackSpeed;
int ForSpeed;
int rTurnSpeed;
int lTurnSpeed;
int LMotor;
int RMotor;
int joystick[8]; //The element array holding the data from joysticks
int fail = 0; // for when we lose radio range

//define the servo name
Servo myServo;


RF24 radio(7,8);     /*This object represents a modem connected to the Arduino.
                                            Arguments 5 and 10 are a digital pin numbers to which signals
                                            CE and CSN are connected.*/

const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.



void setup(){
    Serial.begin(115200); // for outputting debuggin information to serial monitor
    delay(3000);
    Serial.println("Nrf24l01 Receiver Starting");
    pinMode(RightMotorSpeed, OUTPUT);
    pinMode(LeftMotorSpeed, OUTPUT);
    pinMode(RightMotorForward, OUTPUT);
    pinMode(LeftMotorForward, OUTPUT);
    pinMode(LeftMotorBackward, OUTPUT);
    pinMode(RightMotorBackward, OUTPUT);

    //define the servo input pins
    myServo.attach(14); //A0
    
    radio.begin();                    //it activates the modem.
    radio.openReadingPipe(1, pipe);   //determines the address of our modem which receive data.
    radio.startListening();           //enable receiving data via modem
}

void loop() {
    if(radio.available() ) {

        radio.read( joystick, sizeof(joystick) ); // Fetch the data payload

        LMotor = map(joystick[0], 439, 567, 0, 255); // map Joystick0_X
        if(LMotor > 0 && LMotor <123); { //this is backwards
            //Set Left motor backwards
            digitalWrite(LeftMotorForward, LOW);
            digitalWrite(LeftMotorBackward, HIGH);
            analogWrite(LeftMSpeed, LMotor); // PWM signal for left motor speed
            Serial.print("LMotor = ");
            Serial.print(joystick[0]);
        }
        
        
        if(LMotor > 127 && LMotor < 255); { //this is forwards
            //Set Left motor forwards
            digitalWrite(LeftMotorForward, HIGH);
            digitalWrite(LeftMotorBackward, LOW);
            analogWrite(LeftMSpeed, LMotor);
            Serial.print("LMotor = ");
            Serial.print(joystick[0]);
        }

        RMotor = map(joystick[2], 491, 525, 0, 255); // map Joystick1_X
        if(RMotor > 0 && RMotor < 123); { //this is backwards
                //Set Right motor backwards
            digitalWrite(RightMotorForward, LOW);
            digitalWrite(RightMotorBackward, HIGH);
            analogWrite(RightMSpeed, RMotor);
            Serial.print("RMotor = ");
            Serial.print(joystick[2]);
        }

        if(RMotor > 127 && RMotor <255); { //this is forwards
                //Set Left motor forwards
            digitalWrite(RightMotorForward, HIGH);
            digitalWrite(RightMotorBackward, LOW);
            analogWrite(RightMSpeed, RMotor);
            Serial.print("RMotor = ");
            Serial.print(joystick[0]);
        }
    }

    else
    {
        Serial.println("No radio available");
    
    }
        
        // for the servo motor    {
     myServo.write(joystick[5]);
}


I notice that the last line of code (for the servo) is called irrespective of whether data has been received.

I think you are sending data much too often - the whole system is likely to be swamped. I suggest that sending new values 5 times per second is probably sufficient.

Then, on the receiving side you should have a variable to record when a new piece of data comes in so the new data can be acted on.

Have a look at how the code is organized in the first example in this Simple nRF24L01+ Tutorial. It sends a message once per second.


As far as debugging the behaviour of the motors is concerned, I would do that separately from the wireless stuff. Just write a short program that makes the motors move at a fixed speed and direction and try different values just by editing and re-uploading the code.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jonawadl

Thanks Robin2. That was helpful. I bread used a mini bread board and two joysticks to make the motors and servo do exactly what I want using the example you sent. I'll put it together with the RF units now and see what happens.

jonawadl

Ok, Here's what I came up with in answer to the links you sent me. It is partially working. Right motor is working as expected Servo is working as expected. Left motor does nothing. At one point it started turning exactly where LMotor = 490 which happened to be the lower value of my motor stopped position. This told me that my hardware is OK, but there is a problem with my code. It must be something silly I'm missing, but I cannot find it.


I didn't change my radio setup even though the examples you sent me to added some details like packet size. I wasn't sure what the best practice here is. I have a working radio and am going with "if it works, don't fix  it" for now. If there is a reason to convince me otherwise.


jonawadl

Code: [Select]

/*
  ---- Receiver Code ----
  Mert Arduino Tutorial & Projects (YouTube)
  Please Subscribe for Support
*/

#include <Servo.h>    //the library which helps us to control the servo motor
#include <SPI.h>      //the communication interface with the modem
#include "RF24.h"     //the library which helps us to control the radio modem (nRF24L)

//define our L298N control pins
//Motor Left
const int enA = 10;     //enA  for speed control
const int IN1 = 2;    // IN1
const int IN2 = 3;   // IN2
//Motor RIght
const int enB = 5;       //enB for speed control
const int IN3 = 4;     // IN3
const int IN4 = 6;    // IN4
int LeftMSpeed;   // interger to capture speed
int RightMSpeed; // to capture R speed
int LMotor;
int RMotor;
int joystick[8]; //The element array holding the data from joysticks
int fail = 0; // for when we lose radio range
int servo_pos;
bool newData = false;  //
//define the servo name
Servo myServo;


RF24 radio(7, 8);     /*This object represents a modem connected to the Arduino.
                      Arguments 5 and 10 are a digital pin numbers to which signals
                      CE and CSN are connected.*/

const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.



void setup() {
  Serial.begin(115200); // for outputting debuggin information to serial monitor
  delay(3000);
  Serial.println("Nrf24l01 Receiver Starting");
  pinMode(enB, OUTPUT); // RIgnt Motor speed PWM
  pinMode(enA, OUTPUT); //Left Motor Speed PWM
  pinMode(IN3, OUTPUT); //Right Forward
  pinMode(IN1, OUTPUT); //Left Forward
  pinMode(IN2, OUTPUT); //Left Backward
  pinMode(IN4, OUTPUT);//Right Backward

  //define the servo input pins
  myServo.attach(14); //A0

  radio.begin();                    //it activates the modem.
  radio.openReadingPipe(1, pipe);   //determines the address of our modem which receive data.
  radio.startListening();           //enable receiving data via modem
}

void loop() {

LMotor = joystick[0];
RMotor = joystick[2];

  if (radio.available() ){
    radio.read( joystick, sizeof(joystick) ); // Fetch the data payload
  }
  if (LMotor < 490) { //this is backwards
    LeftMSpeed = map(joystick[0], 490, 417, 0, 255); // map Joystick0_X
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    analogWrite(enA, LeftMSpeed); // PWM signal for left motor speed
    Serial.print("LMotor = ");
    Serial.println(joystick[0]);
  }
  else if (LMotor > 491 && LMotor < 511) { //Motors will not move with the joystick at center
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
  }
  
  else if (LMotor > 510) { //this is forwards
    LeftMSpeed = map(joystick[0], 510, 606, 0, 255);
    //Set Left motor forwards
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(enA, LeftMSpeed);
    Serial.print("LMotor = ");
    Serial.println(joystick[0]);
  }
  

  if (RMotor < 505)  { //this is backwards
    RightMSpeed = map(joystick[2], 505, 366, 0, 255);
    //Set Right motor backwards
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    analogWrite(enB, RightMSpeed);
    Serial.print("    RMotor = ");
    Serial.println(joystick[2]);
  }
  else if (RMotor > 506 && RMotor < 512) {
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
      }
      
  else if (RMotor > 512) { //this is forwards
    RightMSpeed = map(joystick[2], 512, 660, 0, 255);
    //Set Left motor forwards
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    analogWrite(enB, RightMSpeed);
    Serial.print("    RMotor = ");
    Serial.println(joystick[2]);

  
  }





// for the servo motor    
 servo_pos = map(joystick[7], 0, 1024, 0,255);  
      myServo.write(servo_pos);  
}




===========================================


Code: [Select]

/*
---- Transmitter Code ----
Mert Arduino Tutorial & Projects (YouTube)
Please Subscribe for Support
*/

#include <SPI.h>                      //the communication interface with the modem
#include "RF24.h"                     //the library which helps us to control the radio modem

//define the input pins
int JOYSTICK0_X = A0;  // Throttle input
int TJOYSTICK0_X = A5; // Throttle trim future use
int JOYSTICK0_Y = A3; // Rudder future use
int TJOYSTICK0_Y = A7; // Rudder trim
int JOYSTICK1_X = A1; // Elevator input
int TJOYSTICK1_X = A4; // elevator trim future use
int JOYSTICK1_Y = A2; // ailerons
int TJOYSTICK1_Y = A6; // aileron trim
int aux_switch0 = 2; // switches as labeled on controler
int aux_switch1 = 3;
int trainer_switch = 4;

//define variable values
int joystick[8];     // array containing 8 joystick readings.


RF24 radio(7,8);                     //5 and 10 are a digital pin numbers to which signals CE and CSN are connected.
                                      
const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem, that will receive data from Arduino.

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 200; // send 5X per second

void setup(void){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  radio.begin();                      //it activates the modem.
  radio.openWritingPipe(pipe);        //sets the address of the receiver to which the program will send data.
}

void loop(){
  currentMillis = millis();
  if (currentMillis - prevMillis <= txIntervalMillis){
    radio.write( joystick, sizeof(joystick) );
    prevMillis = millis();
  }
  
  joystick[0] = analogRead(JOYSTICK0_X); // read Throttle input put into array slot 0
  joystick[1] = analogRead(JOYSTICK0_Y); // Rudder to array
  joystick[2] = analogRead(JOYSTICK1_X); // Elevator to array
  joystick[3] = analogRead(JOYSTICK1_Y); //...
  joystick[4] = analogRead(TJOYSTICK0_X);
  joystick[5] = analogRead(TJOYSTICK0_Y);
  joystick[6] = analogRead(TJOYSTICK1_X);
  joystick[7] = analogRead(TJOYSTICK1_Y);

}
  



Robin2

These two lines
Code: [Select]
LMotor = joystick[0];
RMotor = joystick[2];

should be AFTER the radio.read() or else they will use the prior value - although that probably won't make much difference.

I think the wireless part of your programs is OK but I don't see any code to print the actual values that are received so you can check.

If the correct values are being received then this is a motor problem and not a wireless problem and you should follow the suggestion at the end of Reply #2

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jonawadl

I have an answer for you on both those cases.

If LMotor and RMotor should be after, then why does RMotor work? I'll move them to see what changes.

I do have output to my serial monitor. I get a nice flow of numbers when I manipulate either joystick. I used that to tweak my mappings.

I did build the separate circuit as you suggested with out the wireless. I even added in joystick control to see how that works. It worked. Here's my code.

Code: [Select]

 #include <Servo.h>; // added by jonawadl
    //Joystick Pins
    int x_key = A0;                                               
    int y_key = A1;                                               
    int x_pos;
    int y_pos;
    //Motor Pins
    int EN_A = 11;      //Enable pin for first motor
    int IN1 = 9;       //control pin for first motor
    int IN2 = 8;       //control pin for first motor
    int IN3 = 7;        //control pin for second motor
    int IN4 = 6;        //control pin for second motor
    int EN_B = 10;      //Enable pin for second motor
    //Servo pins added by jonawadl
    int pot_pin = A2;
    //Define Servo Name
    Servo myServo; // added by jonawadl
    int pot_value;
   
    int servo_pos;
    //Initializing variables to store data
    int motor_speed;
    int motor_speed1;
    void setup ( ) {
      Serial.begin (9600); //Starting the serial communication at 9600 baud rate
      //Initializing the motor pins as output
      pinMode(EN_A, OUTPUT);
      pinMode(IN1, OUTPUT); 
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT); 
      pinMode(IN4, OUTPUT);
      pinMode(EN_B, OUTPUT);
      //Initializng the joystick pins as input
      pinMode (x_key, INPUT) ;                     
      pinMode (y_key, INPUT) ;
      myServo.attach(17); // added by jonawadl                   
    }
    void loop () {
        x_pos = analogRead (x_key) ;  //Reading the horizontal movement value
        y_pos = analogRead (y_key) ;  //Reading the vertical movement value
        pot_value = analogRead (pot_pin);
       
    if (x_pos < 400){     //Rotating the left motor in clockwise direction
        motor_speed = map(x_pos, 400, 0, 0, 255);   //Mapping the values to 0-255 to move the motor
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        analogWrite(EN_A, motor_speed);
      }
    else if (x_pos>400 && x_pos <600){  //Motors will not move when the joystick will be at center
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
      }
     
    else if (x_pos > 600){    //Rotating the left motor in anticlockwise direction
        motor_speed = map(x_pos, 600, 1023, 0, 255);
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        analogWrite(EN_A, motor_speed);
      }
       
    if (y_pos < 400){         //Rotating the right motor in clockwise direction
        motor_speed1 = map(y_pos, 400, 0, 0, 255);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
        analogWrite(EN_B, motor_speed1);
      }
    else if (y_pos>400 && y_pos <600){
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
      }
     
    else if (y_pos > 600){        //Rotating the right motor in anticlockwise direction
        motor_speed1 = map(y_pos, 600, 1023, 0, 255);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
        analogWrite(EN_B, motor_speed1);
      }
      servo_pos = map(pot_value, 0, 1024, 0,255);  // added by jonawadl
      myServo.write(servo_pos);   // added by jonawadl
      }


jonawadl

Something about this code has me puzzled. Can you shed some light on this bit of code and what it does in my program.

Code: [Select]

void loop() {

LMotor = joystick[0];
RMotor = joystick[2];



If I leave it out entirely, Right motor works but acceleration is in wrong direction. I pushup and motor smoothly accelerates. If I push down it starts at full speed then slows down as joystick travels further from center. In this case reversing my map from low to high does not make a difference. Left Motor does nothing.

With the bit of code as it is written above in the sketch. The right motor works exactly as expected. Left does nothing.

if I change at piece to what I think it should be:

Code: [Select]

void loop() {

LMotor = analogRead (joystick[0]);
RMotor = analogRead (joystick[2]);



Then I'm back to right motor behaving exactly as with first example where I leave out that piece entirely and my serial monitor not displaying joystick inputs. 

Robin2

Please wait for a response before writing a second Post - it is difficult to keep up.

The lines
Code: [Select]
LMotor = joystick[0];
RMotor = joystick[2];

copy the values from the joystick[] array into the two variables.

However your code seems very confused because later on it copies the same joystick[] values into LeftMSpeed and RightMSpeed

I suggest that the lines like
Code: [Select]
LeftMSpeed = map(joystick[0], 490, 417, 0, 255);
should be changed to
Code: [Select]
LeftMSpeed = map(LMotor, 490, 417, 0, 255);
That way there will be no danger of different parts of the program using different values.

You have not said if the values in joystick[0] and joystick[2] are the values you expect them to be. Maybe you should be using joystick[0] and joystick[1] ?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jonawadl

Ok Thanks for helping. I changed code as you suggested, but it made no difference. However, I discovered one quirk.

BTW, the serial output shows the numbers exactly as I expect them. They are the same as they are when I run s potentiometer range test on the joysticks.


The quirk is that if I get the left joystick to output exactly 417 I get the left motor going at full speed. Nowhere else does this happen. It is significant because 417 is the lowest number in my mapping LeftMSpeed.

Robin2

Ok Thanks for helping. I changed code as you suggested, but it made no difference. However, I discovered one quirk.
I can't help as I can't see the latest version of your program.

If you are getting the correct values by wireless (i.e. the values that are being sent) then there is probably just some silly error in the program.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jonawadl

receiver code

Code: [Select]

/*
  ---- Receiver Code ----
  Mert Arduino Tutorial & Projects (YouTube)
  Please Subscribe for Support
*/

#include <Servo.h>    //the library which helps us to control the servo motor
#include <SPI.h>      //the communication interface with the modem
#include "RF24.h"     //the library which helps us to control the radio modem (nRF24L)

//define our L298N control pins
//Motor Left
const int enA = 10;     //enA  for speed control
const int IN1 = 2;    // IN1
const int IN2 = 3;   // IN2
//Motor RIght
const int enB = 5;       //enB for speed control
const int IN3 = 4;     // IN3
const int IN4 = 6;    // IN4
int LeftMSpeed;   // interger to capture speed
int RightMSpeed; // to capture R speed
int LMotor;
int RMotor;
int joystick[8]; //The element array holding the data from joysticks
int fail = 0; // for when we lose radio range
int servo_pos;
bool newData = false;  //
//define the servo name
Servo myServo;


RF24 radio(7, 8);     /*This object represents a modem connected to the Arduino.
                      Arguments 5 and 10 are a digital pin numbers to which signals
                      CE and CSN are connected.*/

const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.



void setup() {
  Serial.begin(115200); // for outputting debuggin information to serial monitor
  delay(3000);
  Serial.println("Nrf24l01 Receiver Starting");
  pinMode(enB, OUTPUT); // RIgnt Motor speed PWM
  pinMode(enA, OUTPUT); //Left Motor Speed PWM
  pinMode(IN3, OUTPUT); //Right Forward
  pinMode(IN1, OUTPUT); //Left Forward
  pinMode(IN2, OUTPUT); //Left Backward
  pinMode(IN4, OUTPUT);//Right Backward

  //define the servo input pins
  myServo.attach(14); //A0

  radio.begin();                    //it activates the modem.
  radio.openReadingPipe(1, pipe);   //determines the address of our modem which receive data.
  radio.startListening();           //enable receiving data via modem
}

void loop() {

LMotor = joystick[0];
RMotor = joystick[2];

  if (radio.available() ){
    radio.read( joystick, sizeof(joystick) ); // Fetch the data payload
  }
  if (LMotor < 490) { //this is backwards
    LeftMSpeed = map(LMotor, 490, 417, 0, 255); // map Joystick0_X
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    analogWrite(enA, LeftMSpeed); // PWM signal for left motor speed
    Serial.print("LMotor = ");
    Serial.println(LMotor);
  }
  else if (LMotor > 491 && LMotor < 511) { //Motors will not move with the joystick at center
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
  }
 
  else if (LMotor > 510) { //this is forwards
    LeftMSpeed = map(LMotor, 510, 606, 0, 255);
    //Set Left motor forwards
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    analogWrite(enA, LeftMSpeed);
    Serial.print("LMotor = ");
    Serial.println(LMotor);
  }
 

  if (RMotor < 505)  { //this is backwards
    RightMSpeed = map(RMotor, 505, 366, 0, 255);
    //Set Right motor backwards
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    analogWrite(enB, RightMSpeed);
    Serial.print("    RMotor = ");
    Serial.println(RMotor);
  }
  else if (RMotor > 506 && RMotor < 512) {
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
      }
     
  else if (RMotor > 512) { //this is forwards
    RightMSpeed = map(RMotor, 512, 660, 0, 255);
    //Set Left motor forwards
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    analogWrite(enB, RightMSpeed);
    Serial.print("    RMotor = ");
    Serial.println(RMotor);

 
  }





// for the servo motor   
 servo_pos = map(joystick[7], 0, 1024, 0,255); 
      myServo.write(servo_pos);   
}


========================

Transmitter code

[code]


#include <SPI.h>                      //the communication interface with the modem
#include "RF24.h"                     //the library which helps us to control the radio modem

//define the input pins
int JOYSTICK0_X = A0;  // Throttle input
int TJOYSTICK0_X = A5; // Throttle trim future use
int JOYSTICK0_Y = A3; // Rudder future use
int TJOYSTICK0_Y = A7; // Rudder trim
int JOYSTICK1_X = A1; // Elevator input
int TJOYSTICK1_X = A4; // elevator trim future use
int JOYSTICK1_Y = A2; // ailerons
int TJOYSTICK1_Y = A6; // aileron trim
int aux_switch0 = 2; // switches as labeled on controler
int aux_switch1 = 3;
int trainer_switch = 4;

//define variable values
int joystick[8];     // array containing 8 joystick readings.


RF24 radio(7,8);                     //5 and 10 are a digital pin numbers to which signals CE and CSN are connected.
                                     
const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem, that will receive data from Arduino.

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 200; // send once per second

void setup(void){
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  radio.begin();                      //it activates the modem.
  radio.openWritingPipe(pipe);        //sets the address of the receiver to which the program will send data.
}

void loop(){
  currentMillis = millis();
  if (currentMillis - prevMillis <= txIntervalMillis){
    radio.write( joystick, sizeof(joystick) );
    prevMillis = millis();
  }
 
  joystick[0] = analogRead(JOYSTICK0_X); // read Throttle input put into array slot 0
  joystick[1] = analogRead(JOYSTICK0_Y); // Rudder to array
  joystick[2] = analogRead(JOYSTICK1_X); // Elevator to array
  joystick[3] = analogRead(JOYSTICK1_Y); //...
  joystick[4] = analogRead(TJOYSTICK0_X);
  joystick[5] = analogRead(TJOYSTICK0_Y);
  joystick[6] = analogRead(TJOYSTICK1_X);
  joystick[7] = analogRead(TJOYSTICK1_Y);

}
 


[/code]

Robin2

I wonder should this
Code: [Select]
LeftMSpeed = map(LMotor, 490, 417, 0, 255); // map Joystick0_X
be
Code: [Select]
LeftMSpeed = map(LMotor, 417, 490, 0, 255); // map Joystick0_X

And if this was my project I think I would do it like this  (not tested)
Code: [Select]
LeftAdcVal = joystick[0];           // range 0 to 1023
leftMotorVal = leftAdcVal - 513;    // range -511 to +510
        // subtracting 513 (rather than 512) ensures that no later value will exceed 255
if (leftMotorVal < 0) {         // Reverse
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
}
else {                          // Forward
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
}

leftMotorVal = (abs(leftMotorVal)) / 2; // get rid of the negative values and fit to range 0 - 255

if (leftMotorVal <= 10) {       // allow for dead band
    analogWrite(enA, 0);
}
else {
    analogWrite(enA, leftMotorVal);
}


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

jonawadl

Why are we making a range of 0 to1023?

I know that is the normal range for a joystick pot. My joysticks have a range of 319 - 567 exactly for joystick[0] The rest point as I determined by centering the joystick and checking the pot value is 503. Should I still use 0 - 1023 or should I modify that? Wouldn't I be limiting max motor speed if my joysticks never reach 1023 or max value as described in code?

How far above and below my joystick actual range should I go in the case of me modifying values to suit my joysticks?

I'm working at modifying code. Will report back when I have progress.

Go Up