Notifications
Clear all

Hello everybody. RCLawn Arduino Robot Car with nRF24L01+

51 Posts
5 Users
0 Likes
4,689 Views
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@rclawn

What would be useful (interesting, clarifying) might be some pictures. If you have a digital camera you can attach some images to your post (see bottom bar).  I find verbal descriptions much harder to follow then a image where I can see exactly what is being described.

So you have a gas (petrol) mower?  Is it self propelled or have you added electric motors to push it? The actual layout isn't clear to me (thus the value in images).

 


   
ReplyQuote
(@rclawn)
Member
Joined: 2 years ago
Posts: 47
Topic starter  

@robotbuilder 

Thank You for response.

I don't have pictures. Try these...microswitch, zero turn, drive motor, toro Model #: 20031,power wheels toy. I'm not trying to be smart. I am only trying to comply. The thing is if I have to pull start it I could just rig up some way junkier mower and fix the fancy one and sell it.

199655204 Honeywell V15 Standard Basic Switch
s50xt 2 2
s l200
ypxffl1v5m
56e2e6bb 2d3d 4fd2 978d 79e127bfe0ac 1.5b0e812f9a5813a3b4155320222de500

 

 

The mower is an electric start, self propelled, gas powered, push mower(the fanciest thing I've ever seen). It has a micro switch(honeywell brand) operated by cable and lever by the safety cross bar(if you let go it stops the engine). It also has a momentary Key switch (to turn it on, or you can pull the string...while holding the crossbar of course).

Mechanically I've done nothing to the mower but clean some electrical connections, the carburetor and fuel tank and replace a fuse. It now starts with the key and runs.

I have the pair of Arduinos Nano and Uno programmed with tx-nRF24L01 and rx-nRF24L01 this operates a pair of geared motors taken from a ride-able child's toy with a joystick to theoretically move the lawnmower about the yard as if it were a riderless zero-turn mower. I would like to add some simple (for some people) code to TX and Rx sketches to operate 2 relays or FETs via push button switches to start and run the beast(sheep) while maneuvering via joystick. lights and a horn would be cool too...

You guys are so nice taking interest in my idea.

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@rclawn 

You guys are so nice taking interest in my idea.

Yeah. Anyone would think we didn't have a life of our own 🙂

It is still unclear to me how you attached the toy car to steer the self propelled mower. The utube examples of your type of project seem to all use motorized wheels from an electric wheel chair.  Cheap RC controllers can be obtained from a toy remote control which is probably the way I would go. I see a proper radio remote control can cost less than AU$50. It comes with everything and thus much simpler than messing about with Arduinos.  I have seen second hand ones come up occasionally as well.

 


   
ReplyQuote
(@rclawn)
Member
Joined: 2 years ago
Posts: 47
Topic starter  

@robotbuilder ok, it drives like a tank. 2 motorized wheels on back of lawn mower. front are like a shopping cart, they go any which way. in forward position both rear wheels propel forward, to turn one wheel goes forward and the other either does nothing or goes in the opposite direction. and visa versa. i am not using the whole toy, just the geared motors.

and yes cheap rc controller 65, receiver?$ speed controller... my buddy does rc cars planes, ect. I had the motors hooked to a cheap walmart rc cars controller to l298n. i would have also needed a massive servo which i was working on and then I cut my grass and decided to apply my new arduino skills....if you don't want to help that's fine. i'm not sitting on my hands. I am pursuing other sketch options but i'm having less luck on these and I'm even more baffled why it isn't working but if I get the motors working i believe that I could get this one to do what I want to do. but i'm too stupid to figure it out apparently...but the money is spent. so I am going to drive on. who knows I might accidently learn something

thank you

Mike


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@rclawn
..if you don't want to help that's fine. i'm not sitting on my hands.

I never wrote that. To be honest I am having a hard time visualizing what you have done so far or what you plan to do.  I like things to be clear in my head and taken one step at a time.

Back in another thread I had to guess what wasn't said with regards to a dust collection system. A simple drawing would have made it all so clear.
https://forum.dronebotworkshop.com/help-wanted/questions-about-changing-to-array-from-buttons/paged/4/

".. it drives like a tank. 2 motorized wheels on back of lawn mower. front are like a shopping cart, they go any which way."

So you removed its wheels and replaced them with the toy car wheels and put swivel wheels on the front? That is why I was suggesting a picture of your setup would make it clear what you have done. Verbal descriptions leave me confused. Each post seems to say something different? I assumed the mower movement was powered by the mower and steered by the toy wheels but now it seems they have replaced the mower wheels to drive the mower like a tank.

mowerMods

 

 


   
ReplyQuote
(@rclawn)
Member
Joined: 2 years ago
Posts: 47
Topic starter  

Hello again,

I'm not trying to be mean or difficult. I really don't need help with the hardware side of things. The FET suggestion was definitely worth considering (Will) .It's the code I need help on this(mainly why I joined). I was revisiting the the sketches and what I had done (that didn't even compile and I think the xmit was the big show stopper. Now if I can help anyone I would be more than happy to do so but I'm more a hands on guy not complex code or circuit design. Now if you needed surgery on a circuit board I would be guy (I try to stay away from tiny cell phone chips but i have). assuming your near STL.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@rclawn 

You have to understand that we can't help you with your code until we can look at it.

Very few of us have the gift of clairvoyance 🙂

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@rclawn 

I really don't need help with the hardware side of things. It's the code I need help on this (mainly why I joined). I was revisiting the the sketches and what I had done (that didn't even compile and I think the xmit was the big show stopper.

Taking this one step at a time. Do you have two Arduinos successfully communicating via their nRF24L01 transceiver modules?  That is your starting point. Code wise have you had success up to that stage after following Bill's tutorial? 

Can you post the sketch that did not compile?

The code and hardware work together.  Programming is essentially wiring up the microprocessor hardware components instead of soldering up hardware components.

 

 

 

 


   
ReplyQuote
(@rclawn)
Member
Joined: 2 years ago
Posts: 47
Topic starter  

@will

Yes I understand. I wanted to reiterate that the code I was using is directly from the dronebot  / youtube project page for " The nRF24L01 - Wireless Joystick for Arduino Robot Car with nRF24L01+  ".

Now I was experimenting with some alternate code(that doesn't use the radiohead library) and although I never did get any of the other prospects going when I tried to revert back to the dronebot code I did something wrong I haven't had time to put my finger on just yet. tonight doesn't look good either. but it did work before and survived a car trip to my friends house and back so I'm confident I just did something silly or these Chinese clones are flaky beyond using the imposter uart chip. Never seem to have an issue with the xmit. Always the receive side.

these are the 2 files I documented and saved as working. tx on nano, rx on uno.

TX

/*
nRF24L01+ Joystick Transmitter
nrf24l01-joy-xmit-car.ino
nRF24L01+ Transmitter with Joystick for Robot Car
Use with Joystick Receiver for Robot Car
DroneBot Workshop 2018
https://dronebotworkshop.com
*/

// Include RadioHead ReliableDatagram & NRF24 Libraries
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>

// Include dependant SPI Library
#include <SPI.h>

// Define Joystick Connections
#define joyVert A0
#define joyHorz A1

// Define Joystick Values - Start at 512 (middle position)
int joyposVert = 512;
int joyposHorz = 512;

// Define addresses for radio channels
#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Create an instance of the radio driver
RH_NRF24 RadioDriver;

// Sets the radio driver to NRF24 and the client address to 1
RHReliableDatagram RadioManager(RadioDriver, CLIENT_ADDRESS);

// Declare unsigned 8-bit motorcontrol array
// 2 Bytes for motor speeds plus 1 byte for direction control
uint8_t motorcontrol[3];

// Define the Message Buffer
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

void setup()
{
// Setup Serial Monitor
Serial.begin(9600);

// Initialize RadioManager with defaults - 2.402 GHz (channel 2), 2Mbps, 0dBm
if (!RadioManager.init())
Serial.println("init failed");

// Set initial motor direction as forward
motorcontrol[2] = 0;

}

void loop()
{
// Print to Serial Monitor
Serial.println("Reading motorcontrol values ");

// Read the Joystick X and Y positions
joyposVert = analogRead(joyVert);
joyposHorz = analogRead(joyHorz);

// Determine if this is a forward or backward motion
// Do this by reading the Verticle Value
// Apply results to MotorSpeed and to Direction

if (joyposVert < 460)
{
// This is Backward
// Set Motors backward
motorcontrol[2] = 1;

//Determine Motor Speeds
// As we are going backwards we need to reverse readings
motorcontrol[0] = map(joyposVert, 460, 0, 0, 255);
motorcontrol[1] = map(joyposVert, 460, 0, 0, 255);

}
else if (joyposVert > 564)
{
// This is Forward
// Set Motors forward
motorcontrol[2] = 0;

//Determine Motor Speeds
motorcontrol[0] = map(joyposVert, 564, 1023, 0, 255);
motorcontrol[1] = map(joyposVert, 564, 1023, 0, 255);

}
else
{
// This is Stopped
motorcontrol[0] = 0;
motorcontrol[1] = 0;
motorcontrol[2] = 0;

}

// Now do the steering
// The Horizontal position will "weigh" the motor speed
// Values for each motor

if (joyposHorz < 460)
{
// Move Left
// As we are going left we need to reverse readings
// Map the number to a value of 255 maximum
joyposHorz = map(joyposHorz, 460, 0, 0, 255);

motorcontrol[0] = motorcontrol[0] - joyposHorz;
motorcontrol[1] = motorcontrol[1] + joyposHorz;

// Don't exceed range of 0-255 for motor speeds
if (motorcontrol[0] < 0)motorcontrol[0] = 0;
if (motorcontrol[1] > 255)motorcontrol[1] = 255;

}
else if (joyposHorz > 564)
{
// Move Right
// Map the number to a value of 255 maximum
joyposHorz = map(joyposHorz, 564, 1023, 0, 255);

motorcontrol[0] = motorcontrol[0] + joyposHorz;
motorcontrol[1] = motorcontrol[1] - joyposHorz;

// Don't exceed range of 0-255 for motor speeds
if (motorcontrol[0] > 255)motorcontrol[0] = 255;
if (motorcontrol[1] < 0)motorcontrol[1] = 0;

}

// Adjust to prevent "buzzing" at very low speed
if (motorcontrol[0] < 8)motorcontrol[0] = 0;
if (motorcontrol[1] < 8)motorcontrol[1] = 0;

//Display the Motor Control values in the serial monitor.
Serial.print("Motor A: ");
Serial.print(motorcontrol[0]);
Serial.print(" - Motor B: ");
Serial.print(motorcontrol[1]);
Serial.print(" - Direction: ");
Serial.println(motorcontrol[2]);

//Send a message containing Motor Control data to manager_server
if (RadioManager.sendtoWait(motorcontrol, sizeof(motorcontrol), SERVER_ADDRESS))
{
// Now wait for a reply from the server
uint8_t len = sizeof(buf);
uint8_t from;
if (RadioManager.recvfromAckTimeout(buf, &len, 2000, &from))
{
Serial.print("got reply from : 0x");
Serial.print(from, HEX);
Serial.print(": ");
Serial.println((char*)buf);
}
else
{
Serial.println("No reply, is nrf24_reliable_datagram_server running?");
}
}
else
Serial.println("sendtoWait failed");

delay(100); // Wait a bit before next transmission
}

 

RX

 

/*
nRF24L01+ Joystick Receiver for Robot Car
nrf24l01-joy-rcv-car.ino
nRF24L01+ Receiver and L298N driver for Robot Car
Use with Joystick Transmitter for Robot Car
DroneBot Workshop 2018
https://dronebotworkshop.com
*/

// Include RadioHead ReliableDatagram & NRF24 Libraries
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>

// Include dependant SPI Library
#include <SPI.h>

// Define addresses for radio channels
#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Motor A Connections
int enA = 9;
int in1 = 14;
int in2 = 4;

// Motor B Connections
int enB = 5;
int in3 = 7;
int in4 = 6;

// Create an instance of the radio driver
RH_NRF24 RadioDriver;

// Sets the radio driver to NRF24 and the server address to 2
RHReliableDatagram RadioManager(RadioDriver, SERVER_ADDRESS);

// Define a message to return if values received
uint8_t ReturnMessage[] = "JoyStick Data Received";

// Define the Message Buffer
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

void setup()
{
// Setup Serial Monitor
Serial.begin(9600);

// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);

// Initialize RadioManager with defaults - 2.402 GHz (channel 2), 2Mbps, 0dBm
if (!RadioManager.init())
Serial.println("init failed");
}

void loop()
{
if (RadioManager.available())
{
// Wait for a message addressed to us from the client
uint8_t len = sizeof(buf);
uint8_t from;
if (RadioManager.recvfromAck(buf, &len, &from))

{

//Serial Print the values of joystick
//Serial.print("got request from : 0x");
//Serial.print(from, HEX);
//Serial.print(": MotorA = ");
//Serial.print(buf[0]);
//Serial.print(" MotorB = ");
//Serial.print(buf[1]);
//Serial.print(" Dir = ");
//Serial.println(buf[2]);

// Set Motor Direction
if (buf[2] == 1)
{
// Motors are backwards
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
}else{
// Motors are forwards
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
}

// Drive Motors
analogWrite(enA, buf[1]);
analogWrite(enB, buf[0]);

// Send a reply back to the originator client, check for error
if (!RadioManager.sendtoWait(ReturnMessage, sizeof(ReturnMessage), from))
Serial.println("sendtoWait failed");
}
}
}

 


   
ReplyQuote
(@rclawn)
Member
Joined: 2 years ago
Posts: 47
Topic starter  

@robotbuilder 

 

Now I was experimenting with some alternate code(that doesn't use the radiohead library) and although I never did get any of the other prospects going when I tried to revert back to the dronebot code I did something wrong I haven't had time to put my finger on just yet. tonight doesn't look good either. but it did work before and survived a car trip to my friends house and back so I'm confident I just did something silly or these Chinese clones are flaky beyond using the imposter uart chip. Never seem to have an issue with the xmit. Always the receive side. I put the codes I would like to modify in the post above to Will.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

@rclawn 

Now I think I get what needs to be done regarding the software side without the distraction of whatever hardware you connect to the Arduinos.

Essentially you just add code to the transmitter software to read the button states and add that to the speedA, speedB and direction list of data that is sent and add code to the receiver software to read that extra data and use it to set other pin states.

Are you going work from the examples using the radiohead library?
The first step is to get that working.

I can work out the extra code you need although you will have to test it out yourself because I don't have a nRF24L01 to test it myself.  But you can't test it out until you get the two Arduino's connection working first which you can test with the "hello world" example.  I might buy a couple of nRF24L01's to play with myself but that will take at least a week or more as there is no local store that stocks them.

 


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@rclawn 

I have written and compiled some code for adding buttons to the TX module and sending signals out on the RX module. They compile cleanly but I can't test them.

The TX module assumes that the buttons are wired with one end to the appropriate Arduino pin and the other end to GND. The code uses pinMode(button,INPUT_PULLUP) which uses an internal (to the Arduino) resistor which ties the button pin's value to HIGH. So the pin is normally HIGH and only goes LOW when pressed.

The isPressed function in the TX module tests to see if the button is pressed (i.e. LOW) and, if not, just returns false.

If the button is pressed, then it waits 10 milliseconds (to allow time for any button bounce to go away) and then tests again. If the value is still LOW, then it decides that the button has been pressed and returns true.

There's not enough information in your RX and TX sketches for me to reliably determine what command format you're sending, so I have left those areas very sparse.

You'll need to open your sketch and copy/paste the code from my files into the corresponding areas of your files. You'll also need to expand the misty bits where you send and receive the commands.

Since you are still able to carry the Arduino around on your person, I would suggest that you use LEDs for the outputs on the RX sketch. That way you can test for proper operation without needing to commit to any particularly expensive components, just 4 LEDs and 4 current limiting resistors.

To avoid bulking up the thread with code, I'm including the new code files as tx_addins and rx_addins

 

 

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@rclawn

I messed up, please substitute this code for the corresponding section in the RX sketch ...

  

    //
    if ( command=7) {
       // do whatever you need to turn lights on or off
      if (lightsOn) {
          digitalWrite(lightPin,LOW);          // Turn lights off
          lightsOn = false;
      } else {
          digitalWrite(lightPin,HIGH);         // Turn lights on
          lightsOn = true;
      }
    }

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 

   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@robotbuilder fyi @rclawn

Thanks for integrating it, I'm much too lazy to re-indent the whole thing and I also wasn't sure whether he might revert to Bill's original sketch. 

It's only fair to let RCLawn test and debug it since he's the only one with a complete set of libraries and components 🙂

I'm not too sure about your interpretation of the start and stopping, though. It seems to me that if the start pin is pressed then the command should be sent and the RX is responsible for the rest of the start procedure. I don't think it should be tested with every command set sent, but as a separate command.

Similarly for the stop button, from POLA - what's the interpretation of the stop button being "not pressed" ? Does that mean stop stopping ? Again, I think this should be a separate command and not part of a commands sent every time.

On the other hand, if it's required to send the whole set of commands every time, then maybe the command should have 3 possible arguments - do, do-not and do nothing. The RX and TX could then co-ordinate what each command means, RX would decide which action is relevant and set the appropriate value. TX would then handle the command if and as required.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Page 2 / 4