Go Down

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

#### Robin2

#15
##### Mar 14, 2019, 02:45 pm
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
I was not aware of that - if you have determined the max and min values then those are what you should use.

However I wonder how you have the joysticks connected to your Arduino - the range seems very small. Can you make a simple pencil drawing showing the connections and post a photo of the drawing? See this  Simple Image Upload Guide

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

#16
##### Mar 14, 2019, 02:57 pm
I still need an answer to the above question, but I have something to add to it.

If I do this;
Code: [Select]

leftAdcVal = joystick[0];           // range 0 to 1032
leftMotorVal = leftAdcVal - 513;    // range -511 to +510
// subtracting 513 (rather than 512) ensures that no later value will exceed 255
Serial.print("LMotor = ");
Serial.println(leftMotorVal);

My serial monitor spits out values I would expect given my joystick max and min limits.

LMotor min is -98 LMotor max is 91.

If I change that snippet to this;

Code: [Select]

leftAdcVal = joystick[0];           // range 319 to 567
leftMotorVal = leftAdcVal - 64;    // range -64 to +64
// subtracting 513 (rather than 512) ensures that no later value will exceed 255
Serial.print("LMotor = ");
Serial.println(leftMotorVal);

The serial output falls back to giving a max reading of 540 and min of 352.

I may just be a very slow school teacher trying to learn how to code, but to me math is math and should give me predictable results. What's up with that?

#### PaulS

#17
##### Mar 14, 2019, 03:12 pm
Quote
I may just be a very slow school teacher trying to learn how to code, but to me math is math and should give me predictable results. What's up with that?
If you print both the value read from the pot and the value you calculate, I'm sure you'll reach for your dunce hat.

#18
##### Mar 14, 2019, 03:23 pmLast Edit: Mar 14, 2019, 03:27 pm by jonawadl
Sorry for posting another question before replying to your previous. I didn't realize we had rolled onto a new page.

Here is a simple drawing of my pots. Connections are as simple as it gets Left post to - right to + middle to signal.

I suspect the limited range is because of the way the pots are mounted in the old radio. It limits travel somewhat so we are not getting full range.

I also added a picture of the back of the radio. There are some extra wires. I want to leave options open for future expansions, but don't want anything else connected while I'm still getting the first stage going.

#19
##### Mar 14, 2019, 06:21 pm
If you print both the value read from the pot and the value you calculate, I'm sure you'll reach for your dunce hat.
Ya whatever. I'll just go sit in a corner for a bit here.

#### Robin2

#20
##### Mar 14, 2019, 06:26 pmLast Edit: Mar 14, 2019, 06:27 pm by Robin2
If your Pot is connected as in your diagram I would expect it to produce ADC values from 0 to 1023 - but maybe the joystick levers cannot move the Pot through its full range.

If the range is from 319 to 567 it would probably simplify the maths if you subtract 319 so that the range is from 0 to 248.

And if you subtract a further 124 (making 443) you will get a symmetrical range from -124 to + 124.

And 124 * 2 is near enough to 255 to make little difference.

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

#21
##### Mar 20, 2019, 05:48 pm
Ok, I'm going nuts here. With the code as it is written bellow. I can use the right joystick to control right motor forward works ok. Reverse starts fast then slows down. That's an easy fix. left motor still does nothing.

Serial output is exactly as expected.

Code: [Select]

/*
Mert Arduino Tutorial & Projects (YouTube)
*/

#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;  //
int leftMotorVal;
int rightMotorVal;
//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);
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.startListening();           //enable receiving data via modem
}

void loop() {

leftAdcVal = joystick[0];           // range 0 to 1023
leftMotorVal = leftAdcVal - 443;    // range -124 to +124
rightAdcVal = joystick[2];           // range 0 to 1023
rightMotorVal = rightAdcVal - 443;    // range -124 to +124
analogWrite(enA, leftMotorVal);
analogWrite(enB, rightMotorVal);
Serial.print("LMotor =");
Serial.print(leftMotorVal);
Serial.print("      RMotor =");
Serial.println(rightMotorVal);
}

LMotor = joystick[0];           // range 319 to 567
// leftMotorVal = leftAdcVal - 443;    // range -64 to +64
// subtracting 513 (rather than 512) ensures that no later value will exceed 255
if (LMotor < 504) {//This is backwards
// LeftMSpeed = map(LMotor, 504, 414, 0, 255); //366
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//  analogWrite(enA, LeftMSpeed);

}

else if (LMotor > 504 && RMotor < 511) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

else if (LMotor > 511) {//This is forwards
// LeftMSpeed = map(LMotor, 511, 604, 0, 255);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//  analogWrite(enA, LeftMSpeed);

}

RMotor = joystick[2];
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);

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

}

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

#### PaulS

#22
##### Mar 20, 2019, 06:10 pm
Quote
left motor still does nothing.
You have an awful lot of code for (still) having a fundamental problem.

Get rid of most of the code. Just make one motor spin in one direction for 5 seconds. Then spin the other motor the same way, for the same length of time. Then, make each motor spin the other way, for the same length of time. Lock the joysticks and radios away until you can positively control the motors.

#23
##### Mar 20, 2019, 06:13 pm
it appears that shifting the numbers down so that we have -124 -- + 124 doesn't translate directly as I, and I assume you expected.

I was expecting the enA pin to disregard the - and take just the numbers to feed to the speed controllers. So we are back to mapping for both a forward and a reverse value.

#24
##### Mar 20, 2019, 06:18 pm
You have an awful lot of code for (still) having a fundamental problem.

Get rid of most of the code. Just make one motor spin in one direction for 5 seconds. Then spin the other motor the same way, for the same length of time. Then, make each motor spin the other way, for the same length of time. Lock the joysticks and radios away until you can positively control the motors.
Paul, That's where I started if you read up on this thread. I broke away from the wireless system and used simple joysticks and a wired connection between the joysticks ==> arduino ==> motor controller ==> motors. Everything worked perfectly. I even added in a servo and a pot and controlled the motion of the servo using the pot. Wired everything worked perfectly.

#### Robin2

#25
##### Mar 20, 2019, 06:23 pm
Everything worked perfectly. I even added in a servo and a pot and controlled the motion of the servo using the pot. Wired everything worked perfectly.
Then the obvious question is how does the motor control code in the non-working program differ from the working program?

Can you remove the "broken" motor control code and replace it with the working code?

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

#26
##### Mar 20, 2019, 06:35 pmLast Edit: Mar 20, 2019, 06:37 pm by jonawadl
I tried to do that. I have uploaded my wired code set here, but I will upload both again together. I have been comparing the two and con't find the difference that would make it go.

Code: [Select]

/*
Mert Arduino Tutorial & Projects (YouTube)
*/

#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;  //
int leftMotorVal;
int rightMotorVal;
//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);
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.startListening();           //enable receiving data via modem
}

void loop() {

leftAdcVal = joystick[0];           // range 0 to 1023
leftMotorVal = leftAdcVal - 443;    // range -124 to +124
rightAdcVal = joystick[2];           // range 0 to 1023
rightMotorVal = rightAdcVal - 443;    // range -124 to +124
analogWrite(enA, leftMotorVal);
analogWrite(enB, rightMotorVal);
Serial.print("LMotor =");
Serial.print(leftMotorVal);
Serial.print("      RMotor =");
Serial.println(rightMotorVal);
}

LMotor = joystick[0];           // range 319 to 567
// leftMotorVal = leftAdcVal - 443;    // range -64 to +64
// subtracting 513 (rather than 512) ensures that no later value will exceed 255
if (LMotor < 504) {//This is backwards
// LeftMSpeed = map(LMotor, 504, 414, 0, 255); //366
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//  analogWrite(enA, LeftMSpeed);

}

else if (LMotor > 504 && RMotor < 511) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

else if (LMotor > 511) {//This is forwards
// LeftMSpeed = map(LMotor, 511, 604, 0, 255);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//  analogWrite(enA, LeftMSpeed);

}

RMotor = joystick[2];
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);

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

}

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

Wired code that worked:

Code: [Select]

//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
int pot_pin = A2;
//Define Servo Name
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) ;
}
void loop () {

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

#### Robin2

#27
##### Mar 20, 2019, 08:28 pm
In the receiver code you posted in Reply #26 both of the motors have analogWrite() commented out.

Also the map() statements are different from the working code.

What happens if you substitute the working code for the non-working code AND make the other variables in your wireless program match the working code.

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

#### Robin2

#28
##### Mar 20, 2019, 08:54 pmLast Edit: Mar 20, 2019, 08:57 pm by Robin2
I have had a go at reorganising the working code in Reply #26 into a series of short functions to separate the activities. If you do that it makes the code much more portable. To use the revised code in your wireless program you would just need to change the function getInputs()

(I have not tested this so there may be some silly typos)

Code: [Select]
void loop() {
getInputs();
calculateMotorValues();
calculateServoPosition();
driveMotors();
}

//============

void getInputs() {
}

//===========

void calculateMotorValues() {
motorSpeed = 0;
if (x_pos < 400){     //Rotating the left motor in clockwise direction
motor_speed = map(x_pos, 400, 0, 0, 255);
motorDir = 'F';
}
else if (x_pos > 600){    //Rotating the left motor in anticlockwise direction
motor_speed = map(x_pos, 600, 1023, 0, 255);
motorDir = 'R';
}

motorSpeed1 = 0;
if (y_pos < 400){     //Rotating the left motor in clockwise direction
motor_speedy = map(y_pos, 400, 0, 0, 255);
motorDir1 = 'F';
}
else if (y_pos > 600){    //Rotating the left motor in anticlockwise direction
motor_speed1 = map(y_pos, 600, 1023, 0, 255);
motorDir1 = 'R';
}
}

//=============

void calculateServoPosition() {
servo_pos = map(pot_value, 0, 1024, 0,255);
}

//=============

void driveMotors() {
if (motorDir == 'F') {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
else {
digitalWrite(IN1, HIGH;
digitalWrite(IN2, LOW);
}
analogWrite(EN_A, motor_speed);

if (motorDir1 == 'F') {
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
else {
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
analogWrite(EN_B, motor_speed);

}

//==============

myServo.write(servo_pos);
}

...R

PS ... If you are going to use this version be sure to get it working in the wired version first.
Two or three hours spent thinking and reading documentation solves most programming problems.

#29
##### Mar 21, 2019, 02:00 pm
Ok, before I go to look at your code very closely, I have made some changes of my own that I want you to look at.

I saved a new version of the existing code I had and completely took out the motor control and replaced it with the motor control from the working wired sketch. Then I added some serial.print code to see what it does.

With a bit of tweaking, I was able to get the serial output to do exactly what I expected it to do. I was reading the input from joystick[2] and the output to LeftMSpeed for both motors. They are exactly the same. I push joystick up I seed joystick input rise to expected values. At the same time, LeftMSpeed goes from 0 - 255 in a smooth sweep exactly as I would expect from a working code.

Here's the weird part though. While the right motor does everything right, the left motor does not twitch UNTIL LeftMSpeed hits 255 in either forward or reverse direction. Then it kicks in and goes at full speed in whatever direction is required of it. I've swapped the motors left to right, I've changed out the speed controller with brand new.

Can anybody suggest what else might be the problem?

In the code you will notice that some of the serial.print stuff is commented out. That's because I'm no good at formatting the output yet so I had to output one motor at a time to get a clear reading.

Code: [Select]

/*
Mert Arduino Tutorial & Projects (YouTube)
*/

#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;  //
int leftMotorVal;
int rightMotorVal;
//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);
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.startListening();           //enable receiving data via modem
}

void loop() {

//Serial.print("LMotor =");
//Serial.print(joystick[0]);
Serial.print("      RMotor =");
Serial.print(joystick[2]);

if (leftAdcVal < 504) {    //Rotating the left motor in clockwise direction
LeftMSpeed = map(leftAdcVal, 504, 416, 0, 255);   //Mapping the values to 0-255 to move the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(enA, LeftMSpeed);
//  Serial.print("    LeftMSpeedR =");
//  Serial.println(LeftMSpeed);
}
else if (leftAdcVal > 504 && leftAdcVal < 517) { //Motors will not move when the joystick will be at center
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
//  Serial.print("    LSTOP =");
//  Serial.println(LeftMSpeed);
}

else if (leftAdcVal > 517) {   //Rotating the left motor in anticlockwise direction
LeftMSpeed = map(leftAdcVal, 517, 605, 0, 255);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(enA, LeftMSpeed);
//   Serial.print("    LeftMSpeedF =");
//   Serial.println(LeftMSpeed);
}

if (rightAdcVal < 508) {        //Rotating the right motor in clockwise direction
RightMSpeed = map(rightAdcVal, 508, 364, 0, 255);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(enB, RightMSpeed);
Serial.print("    RightMSpeedR =");
Serial.println(RightMSpeed);
}
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
Serial.print("    RSTOP =");
Serial.println(LeftMSpeed);
}

else if (rightAdcVal > 511) {       //Rotating the right motor in anticlockwise direction
RightMSpeed = map(rightAdcVal, 511, 652, 0, 255);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(enB, RightMSpeed);
Serial.print("    LeftMSpeedF =");
Serial.println(RightMSpeed);
}
// for the servo motor
servo_pos = map(joystick[7], 0, 1024, 0, 255);
myServo.write(servo_pos);
}
}

Go Up