Help! RC Tank--Getting data from Transceivers to do stuff.

The Situation:
Hi, I am currently building an RC Tank. It is controlled by a hand held remote control I made, consisting of a rotary encoder, a joystick,and an UNO. The RC Tank is controlled by two DC motors and a Mega 2560. I am using two transceivers to communicate between the remote control and the Tank.

My Problem:
I am able to communicate/send or receive data from my Arduinos via the transceivers, however I am unable to figure out how to take the data I receive on my Tank from my remote control, and then tell my motors on the tank what to do based on the data.

What I Want My Code TO Do:
I want it so that I have an if statement in the code for my RC Tank that says if the data I recieve from my Remote Control is so and so, motors do such and such.

Extra Info
The title of the attachment of the code for my remote control is: RC Tank--Uno Board.
The title of the attachment of the code for my RC Tank: RC Tank--Mega Board.
(Too clarify, my uno sends the signals and my RC Tank receives them)
I do know how to code my motors on my motor driver.
The RC Tank code is currently set up so that I can see the data I get from the remote control and that all works.

Thank-you so much for helping me! I have unsuccessfully tried for hours to figure this out!

RC_Tank--Mega_Board_Code.ino (717 Bytes)

RC_Tank--Uno_Board_Code.ino (8.37 KB)

I am able to communicate/send or receive data from my Arduinos via the transceivers, however I am unable to figure out how to take the data I receive on my Tank from my remote control, and then tell my motors on the tank what to do based on the data

Can you post the output from the serial monitor for the tank, as you say the remote is working and sending data. Are you getting what you expect (i.e. what you sent) displayed in the serial monitor? Your code doesn't appear to be trying to do anything for the tank at the moment.

When I've used the NRF24L01 in the past, I have created a struct to contain the common data structure for transmission and then included that in both the sender and receiver. That way, both sides know what is being exchanged and the size of it.

Have a look at the examples in this Simple nRF24L01+ Tutorial. I am using the technique in the second example to control a model train. However if you don't need your tank to send back any data the first example will be sufficient.

In your Uno program you have lots of different radio.write() statements to send different values. There is a much simpler way.

Save all the data from your different potentiometers and switches to variables. Then about 5 times per second send whatever happens to be in those variables. If you can save the data into an array it will be easiest. Maybe something like this pseudo code

int commandData[3];
commandData[0] = digitalRead of switch
commandData[1] = analogRead of pot A
commandData[2] = analogRead of pot B

if (millis() - prevRadioSend >= radioSendInterval) {
   radio.write(&commandData, sizeof(commandData);
   prevRadioSend += radioSendInterval;

}

This also has the advantage that the tank will be easily able to detect the fact that transmission have stopped and then shut off the motors.

...R

Hi, the problem isn't with the transceiver sending data, that works fine and the serial monitor is printing out what it should be based on where I move the joystick. The problem is that I can't create an if statement on my RC Tank that has it so,

if (radio.read == "0") {
digitalWrite(22, LOW);
}

if (radio.read == "1.0") {
digitalWrite 22, HIGH);
}

I know the code can't exactly do that, but I want to know how to make it so it does that. Basically if the transceiver sends a 0 turn the motor off, if it sends 1.0 turn it on. I can then take it from there and make it control motors on my Motor Driver Shield.

Your tutorial looked very good Robin2, although I didn't see an if statement in there that said what I wanted.

I hope that makes sense.
Thanks for all your help!

I suspect it is because you are sending and receiving strings (or arrays of char). While they might look the same when you dump them to the serial monitor, they are not exactly the same at a byte level. You are comparing a 32 byte char array to a variable length string (i.e. "0", "1.0" etc.).

    char text[32] = "0";
    radio.read(&text, sizeof(text));
    Serial.println (text);

Try either working with integers if you can (as they are always the same length) or have a look at strcmp.

I'm not an expert with strings - I usually try to avoid them when possible.

If this is not it, can you post your complete code for the tank as the snippets below don't match your earlier attachments.

Vulcan666:
Hi, the problem isn't with the transceiver sending data, that works fine and the serial monitor is printing out what it should be based on where I move the joystick.

The problem is that what you have at the moment is a very ineffective way to implement your project.

The reason my tutorial has no IF statement is because it neither knows nor cares what the data is to be used for. That is not something that should concern the wireless code.

Think of the wireless as the guy who goes to the toolshop to get a newly sharpened chisel that the woodcarver needs. The gopher does not know how to carve wood or how to sharpen chisels.

...R

Hi, I am sorry, but I am very new to Arduino, and a lot of the code doesn't make sense, I just copy pasted parts of it. I tried to get your code to work but I can't make it so that if I send a 1.0 from my remote control, pin 22 will turn on, and if I send 0, pin 22 will turn off. Could you maybe write some code that does that for me, I'll then see how to do it and can modify it to fit my needs and such.

Thanks so much for your help!

Start by learning how to use the Arduino to blink an LED, play a tone, move a servo arm and run a motor forward and backward.

Many of those examples are built in to the Arduino development software, or are posted on the Arduino websites.

Then you will be ready to use commands from the radio to run your RC car.

If you want to keep your existing tank code (which you haven't posted) rather than re-structuring as @Robin2 wisely suggested then change from strings to int and pass integers for your commands (e.g. 0 = stop, 1 = forward, 2 = left etc.). This will make your if statements work as every command will be 2 bytes, but in the long run you should structure your code properly - better to do that now while you don't have much code.

@Jremington i already know how to blink an led, make motors and servos move and lots of other stuff. I was meaning I wasn't sure about transceiver(radio code as you put it).
@Davidrh hi, the tank code is the RC Tank--Mega Board Code I attached on my first post, I'll attach it again here. The problem is centered in this but of code here:

if (radio.available()) {
    int text = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);

    if (text == 48) {
      motor2.run(RELEASE);
      motor4.run(RELEASE);
      digitalWrite(22, LOW);
    }

    if (text == 11825) {
      motor2.run(FORWARD);
      motor2.setSpeed(255);
      motor4.run(FORWARD);
      motor4.setSpeed(255);
      digitalWrite(22, HIGH);
    }
  }

I tried changing the values to integers and instead of printing out a zero, it prints out 48, and 11825 instead of 1.0

Am I doing something wrong? I haven't used anything but integers before, and the radio.read command won't work when I do certain things with them.

Again, thanxs for helping

RC_Tank--Mega_Board_Code.ino (963 Bytes)

I tried changing the values to integers and instead of printing out a zero, it prints out 48, and 11825 instead of 1.0

Did you change your transmitter to send integers as well? "1.0" is not an integer. Both ends have to be speaking the same "language". Until you get what you are sending matching what you are receiving, nothing is going to work as it should.

Davidrh, I tried to change the code on my uno to integers and now it is really messed up and I can't seem to fix it. I really just don't understand this, do you know how to write an bit of code that says if the value I get from my remote control is 0 turn pin 22 on? Because if you do then if you show me that I can fix everything, but I am mostly going by trial and error because everything doesn't make sense.

Sorry for the bother, I haven't done much other than if int data is equal to 0 turn an led on.
As always, thankxs for helping me

You need to post your code and the output you are seeing on the serial monitor. You have recommendations from myself and @Robin2 but we can't see what you have done. Ideally use the serial monitor to show what you are sending and what you are receiving. The serial output should be for the exact code that you post.

Most people won't have the time or inclination to write your code for you but will try to help you find problems in the code you have written yourself.

davidrh:
Most people won't have the time or inclination to write your code for you but will try to help you find problems in the code you have written yourself.

Okay, thanks for letting me know.

davidrh:
You need to post your code and the output you are seeing on the serial monitor. You have recommendations from myself and @Robin2 but we can't see what you have done. Ideally use the serial monitor to show what you are sending and what you are receiving. The serial output should be for the exact code that you post.

Okay, so the first file I attached says it is: RC Tank--Uno Board Code.ino. That is the code for my remote control. It is basically sending different outputs based on joystick and rotary encoder readings.

The second file I attached says it is:RC Tank--Mega Board Code.ino. That is the code for my RC Tank. It reads the code and is correctly outputting in my serial moniter the inputs I get from my Remote Control. Example:

1.a6
1.a6
1.a0
0
0
0
0
0
8.8
8.8
0
0
5.a4
5.a2

The problem is when I say :

    if (text == "0"){
      digitalWrite(22, HIGH);
    }
    if (text == "1.0"){
      digitalWrite(22, LOW);
    }

The led doesn't turn on, I have verified it works, and the serial monitor is outputting a 0.

Sorry for the delay, one of my transceivers doesn't work any more, I think I accidentally put it in 5v pin maybe? Anyway, after hours of trying to figure out why nothing worked, I tried replacing my transceiver, and my code started working again.

As always, thanks for helping me.

RC_Tank--Uno_Board_Code.ino (8.37 KB)

RC_Tank--Mega_Board_Code.ino (803 Bytes)

You don't seem to have implemented any of the recommendations that @Robin2 or I have given you, or posted code containing those recommendations. You are still persisting with strings, so I can't help you further apart from pointing out that:

    char text[] = "0";
    radio.read(&text, sizeof(text));
    Serial.println(text);
    if (text == "1.0"){
      digitalWrite(22, LOW);
    }

will never work, as you are initialising your text array to have 1 character, reading that many characters (plus terminator) from the radio and then seeing if it equals something that has three characters. It never will.

Arrays in C (and most languages) don't magically get bigger, but C will let you go beyond the bounds of the array without telling you. This is why I suggested it would be simpler if you switched to integers as they are always the same size so the sender knows how many bytes to send and the receiver knows how many bytes to receive. If you really want/need a decimal place send the value * 10 to make it an integer (i.e. 8.0 = 80).

Okay, I tried changing everything to integers but I'm not exactly sure how to do that.

I didn't change all of the the Remote Control Code as it has this error message**:**

RC_Tank--Uno_Board_Code:43: error: invalid conversion from 'const char*' to 'int' [-fpermissive]
     int text = "0";
                ^
RC_Tank--Uno_Board_Code:44: error: no matching function for call to 'RF24::write(int&)'
     radio.write(text);
                     ^
C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Uno_Board_Code\RC_Tank--Uno_Board_Code\RC_Tank--Uno_Board_Code.ino:44:21: note: candidates are:
In file included from C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Uno_Board_Code\RC_Tank--Uno_Board_Code\RC_Tank--Uno_Board_Code.ino:3:0:
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:225:8: note: bool RF24::write(const void*, uint8_t)
   bool write( const void* buf, uint8_t len );
        ^
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:225:8: note:   candidate expects 2 arguments, 1 provided
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:373:8: note: bool RF24::write(const void*, uint8_t, bool)
   bool write( const void* buf, uint8_t len, const bool multicast );
        ^
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:373:8: note:   candidate expects 3 arguments, 1 provided
exit status 1
invalid conversion from 'const char*' to 'int' [-fpermissive]

here is the code I changed

  if (analogRead(X_pin) <= 504 && (analogRead(X_pin) >= 500 && (analogRead(Y_pin) <= 506 && (analogRead(Y_pin) >= 500)))) {//                                                                                  
    int text = "0";
    radio.write(text);
  }

the same thing happened for my mega board code which I attached in a file. Here is its error message:

RC_Tank--Mega_Board_Code:22: error: invalid conversion from 'const char*' to 'int' [-fpermissive]
     int text = "0";
                ^
RC_Tank--Mega_Board_Code:23: error: no matching function for call to 'RF24::read(int&)'
     radio.read(text);
                    ^
C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino:23:20: note: candidate is:
In file included from C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino:3:0:
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:200:8: note: void RF24::read(void*, uint8_t)
   void read( void* buf, uint8_t len );
        ^
C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:200:8: note:   candidate expects 2 arguments, 1 provided
RC_Tank--Mega_Board_Code:28: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
     if (text == "1.1"){
             ^
exit status 1
invalid conversion from 'const char*' to 'int' [-fpermissive]

I have the feeling that that is not how to change stuff from strings to integers but I'm not really sure how to do that.

As usual, thanks for helping me!

RC_Tank--Mega_Board_Code.ino (800 Bytes)

Integers don't have quotes around them, and they must be, well integers. You can't assign 1.1 to an integer, so you need to pick integer values.

Okay, so I took away the quotes, and changed 1.1 to 11 and 1.2 to 12 and so on. However, now I come up with a new error message, it's the same for both of them so I'll just do the mega board (rc tank) code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8);
const byte rxAddr[6] = "00001";

#include <AFMotor.h>
AF_DCMotor motor2(2);
AF_DCMotor motor4(4);

int text = 0;

void setup() {
  radio.begin();
  radio.openReadingPipe(0, rxAddr);
  radio.startListening();
  Serial.begin(9600);
  pinMode(22, OUTPUT);
}
void loop() {
  if (radio.available()) {
    int text = 0;
    radio.read(text);
    Serial.println(text);
    if (text == 0){
      digitalWrite(22, HIGH);
    }
    if (text == 11){
      digitalWrite(22, LOW);
    }
  }
}

here is the new error message, I'm not sure what it is even saying is wrong.

C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino: In function 'void loop()':

RC_Tank--Mega_Board_Code:23: error: no matching function for call to 'RF24::read(int&)'

     radio.read(text);

                    ^

C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino:23:20: note: candidate is:

In file included from C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino:3:0:

C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:200:8: note: void RF24::read(void*, uint8_t)

   void read( void* buf, uint8_t len );

        ^

C:\Users\Leifur\Documents\Arduino\libraries\RF24_Library/RF24.h:200:8: note:   candidate expects 2 arguments, 1 provided

exit status 1
no matching function for call to 'RF24::read(int&)'

Of course, thanks!

Try

    int command;
    boolean ok = radio.read(&command, sizeof(command));
    Serial.println(command);

You need to do similar on the write.

Alright is it like this?

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8);
const byte rxAddr[6] = "00001";

#include <AFMotor.h>
AF_DCMotor motor2(2);
AF_DCMotor motor4(4);

int text = 0;

void setup() {
  radio.begin();
  radio.openReadingPipe(0, rxAddr);
  radio.startListening();
  Serial.begin(9600);
  pinMode(22, OUTPUT);
}
void loop() {
  if (radio.available()) {
    int command;
    boolean ok = radio.read(&command, sizeof(command));
    Serial.println(command);
    if (command == 0) {
      digitalWrite(22, HIGH);
    }
    if (command == 11) {
      digitalWrite(22, LOW);
    }
  }
}

It brings up another error:

C:\Users\Leifur\Documents\Arduino\Arduino Star Trans Files\RC Tank\RC_Tank\RC_Tank--Mega_Board_Code\RC_Tank--Mega_Board_Code.ino: In function 'void loop()':

RC_Tank--Mega_Board_Code:23: error: void value not ignored as it ought to be

     boolean ok = radio.read(&command, sizeof(command));
                                             ^
exit status 1
void value not ignored as it ought to be

No files were added to the sketch.

Thanks!