I am trying to make a remote-control tank that uses nrf radio transmitter and receiver that uses buttons to control the tank head
and the question is?
I am having trouble with sending a signal when the button is pressed and having the tank respond. I have found codes for controlling a servo with a variable resistor. I was wondering if I could have some assistance?
Hello
Post your sketch, well formated, with comments and in so called code tags "</>" and schematic to see how we can help.
Use Serial monitor and debug Serial.print to tell what's tried.
That's often a recipe for confusion and trouble. If You know some about coding it can be a skeleton to build from. Try to learn about code. This business is not like buying LEGO bricks and fitting them.
Have you established reliable communication between 2 rf24 modules?
Is this for school or is it a hobby project?
Like @paulpaulson has requested, please post your code. Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
Tell us what the code actually does and how that differs from what you want the code to do.
Here's the receiver code I have
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
RF24 radio(9,10);
const byte address[6] = "00001";
boolean button_state1 = 0;
boolean button_state2 = 0;
boolean button_state3 = 0;
boolean button_state4 = 0;
boolean button_state5 = 0;
boolean button_state6 = 0;
int Laser = 8;
int LED = 7;
Servo Top;
Servo BottomL;
Servo BottomR;
void setup()
{
pinMode(Laser,OUTPUT);
pinMode(LED,OUTPUT);
Top.attach(4);
BottomL.attach(5);
BottomR.attach(6);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop()
{
if (radio.available())
{
char text[32] = "";
radio.read(&text, sizeof(text));
radio.read(&button_state1, sizeof(button_state1));
radio.read(&button_state2, sizeof(button_state2));
radio.read(&button_state3, sizeof(button_state3));
radio.read(&button_state4, sizeof(button_state4));
radio.read(&button_state5, sizeof(button_state5));
radio.read(&button_state6, sizeof(button_state6));
if(button_state1 == HIGH)
{
Top.write (90);
BottomL.write (135);
BottomR.write (45);
delay(700);
Top.write (110);
BottomL.write (150);
BottomR.write (30);
delay(700);
digitalWrite(Laser, HIGH);
}
if(button_state2 == HIGH)
{
digitalWrite(Laser, LOW);
delay(700);
Top.write (90);
BottomL.write (45);
BottomR.write (135);
delay(700);
Top.write (90);
BottomL.write (0);
BottomR.write (180);
}
if(button_state3 == HIGH)
{ digitalWrite(LED, HIGH);
delay(250);
digitalWrite(LED, LOW);
}
}
}
My transmitter code
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);
const byte address[6] = "00001";
int button_pin1 = 2;
int button_pin2 = 3;
int button_pin3 = 4;
int button_pin4 = 5;
int button_pin5 = 6;
int button_pin6 = 7;
boolean button_state1 = 0;
boolean button_state2 = 0;
boolean button_state3 = 0;
boolean button_state4 = 0;
boolean button_state5 = 0;
boolean button_state6 = 0;
void setup()
{
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
pinMode(button_pin1, INPUT);
pinMode(button_pin2, INPUT);
pinMode(button_pin3,INPUT);
pinMode(button_pin4, INPUT);
pinMode(button_pin5, INPUT);
pinMode(button_pin6, INPUT);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop()
{
button_state1 = digitalRead(button_pin1);
button_state2 = digitalRead(button_pin2);
button_state3 = digitalRead(button_pin3);
button_state4 = digitalRead(button_pin4);
button_state5 = digitalRead(button_pin5);
button_state6 = digitalRead(button_pin6);
if(button_state1 == HIGH)
{
const char text[] = "Your Button State is HIGH";
radio.write(&text, sizeof(text));
}
else if(button_state2 == HIGH)
{
const char text[] = "HIGH";
radio.write(&text, sizeof(text));
}
else if(button_state3 == HIGH)
{
const char text[] = "HIGH";
radio.write(&text, sizeof(text));
}
else if(button_state4 == HIGH)
{
const char text[] = "HIGH";
radio.write(&text, sizeof(text));
}
else if(button_state5 == HIGH)
{
const char text[] = "HIGH";
radio.write(&text, sizeof(text));
}
else if(button_state6 == HIGH)
{
const char text[] = "HIGH";
radio.write(&text, sizeof(text));
}
}
Do not use multiple writes to send the data. Then only one read will be necessary.
Put the switch states into a struct, like this
struct ButtonValues
{
bool butLf;
bool butRt;
bool butUp;
bool butDn;
}buttonValues;
Read the states of the buttons and put the states into the struct
buttonValues.butLf = digitalRead(leftButtonPin);
buttonValues.butRt = digitalRead(rightButtonPin);
buttonValues.butUp = digitalRead(upButtonPin);
buttonValues.butDn = digitalRead(downButtonPin);
Then you send the struct only once.
radio.write( &buttonValues, sizeof(buttonValues) );
Receiving is the reverse. Read the struct in
if ( radio.available() )
{
radio.read( &buttonValues, sizeof(buttonValues) );
}
The button states will be the buttonValues struct
can I have an example of what the receiving end looks like?
This code is adapted from a code that I wrote for a project, previously. The code in my first post is from that as well.
Declare the struct to receive the data in global scope ( above and outside of setup() or loop()). It needs to be exactly the same as the sender in structure. The name can be different.
struct ButtonValues // contains button states
{
bool butLf;
bool butRt;
bool butUp;
bool butDn;
} buttonValues;
Read the incoming packet that contains the struct.
if ( radio.available() )
{
radio.read( &buttonValues, sizeof(buttonValues) );
newData = true;
}
You can display the elements of the struct
if (newData == true)
{
Serial.print("Data received "); // 0 for pressed, 1 for not pressed
Serial.print("left button >> ");
Serial.print( buttonValues.butLf);
Serial.print(" right button >> ");
Serial.print( buttonValues.butRt);
Serial.print(" up button >> ");
Serial.print( buttonValues.butUp);
Serial.print(" down button >> ");
Serial.println( buttonValues.butDn);
//newData = false;
}
Use the button values from the struct to move the servos.
void actOnData()
{
if (newData == true)
{
if (buttonValues.butLf == LOW)
{
trainServoPos = trainServoPos - 5;
if (trainServoPos < 10)
{
trainServoPos = 10;
}
}
if (buttonValues.butRt == LOW)
{
trainServoPos = trainServoPos + 5;
if (trainServoPos > 170)
{
trainServoPos = 170;
}
}
if (buttonValues.butUp == LOW)
{
elevateServoPos = elevateServoPos + 5;
if (elevateServoPos > 170)
{
elevateServoPos = 170;
}
}
if (buttonValues.butDn == LOW)
{
elevateServoPos = elevateServoPos - 5;
if (elevateServoPos < 10)
{
elevateServoPos = 10;
}
}
trainServo.write(trainServoPos);
elevateServo.write(elevateServoPos);
Serial.print("train servo position = ");
Serial.print(trainServoPos);
Serial.print(" elevate servo position = ");
Serial.println(elevateServoPos);
newData = false;
}
}
I now have this for my transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);
struct ButtonValues
{
bool but1;
bool but2;
bool but3;
bool but4;
bool but5;
bool but6;
}buttonValues;
const byte address[6] = "00001";
int button_pin1 = 2;
int button_pin2 = 3;
int button_pin3 = 4;
int button_pin4 = 5;
int button_pin5 = 6;
int button_pin6 = 7;
void setup()
{
digitalWrite(2,LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
pinMode(button_pin1, INPUT);
pinMode(button_pin2, INPUT);
pinMode(button_pin3,INPUT);
pinMode(button_pin4, INPUT);
pinMode(button_pin5, INPUT);
pinMode(button_pin6, INPUT);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop()
{
buttonValues.but1 = digitalRead(button_pin1);
buttonValues.but2 = digitalRead(button_pin2);
buttonValues.but3 = digitalRead(button_pin3);
buttonValues.but4 = digitalRead(button_pin4);
buttonValues.but5 = digitalRead(button_pin5);
buttonValues.but6 = digitalRead(button_pin6);
radio.write( &buttonValues, sizeof(buttonValues) );
}
and my receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
RF24 radio(9,10);
const byte address[6] = "00001";
int Laser = 8;
int LED = 7;
Servo Top;
Servo BottomL;
Servo BottomR;
struct ButtonValues
{
bool but1;
bool but2;
bool but3;
bool but4;
bool but5;
bool but6;
}buttonValues;
void setup()
{
pinMode(Laser,OUTPUT);
pinMode(LED,OUTPUT);
Top.attach(4);
BottomL.attach(5);
BottomR.attach(6);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop()
{
if ( radio.available() )
{
radio.read( &buttonValues, sizeof(buttonValues) );
if(buttonValues.but1== HIGH)
{
Top.write (90);
BottomL.write (135);
BottomR.write (45);
delay(700);
Top.write (110);
BottomL.write (150);
BottomR.write (30);
delay(700);
digitalWrite(Laser, HIGH);
}
if(buttonValues.but2 ==HIGH )
{
digitalWrite(Laser, LOW);
delay(700);
Top.write (90);
BottomL.write (45);
BottomR.write (135);
delay(700);
Top.write (90);
BottomL.write (0);
BottomR.write (180);
}
if(buttonValues.but3 ==HIGH)
{ digitalWrite(LED, HIGH);
}
if(buttonValues.but4 ==HIGH)
{
digitalWrite(LED, LOW);
}
if(buttonValues.but5 ==HIGH)
{ digitalWrite(LED, HIGH);
delay(250);
digitalWrite(LED, LOW);
}
}
}
Why write LOW to the pins before setting the pinModes?
Pins default to INPUT so those lines are superfluous. No harm, just not necessary.
Wiring pins to ground and using the internal pullup resistors is more common and the accepted way to wire switches.
How are your buttons wired? Does each one have a pullup resistor? A schematic would be helpful.
I would suggest that you not send values so often. Your current code sends hundreds if not thousands of time per second. That is not necessary and not likely to work that well. Try 20 to 50 times a second. Use delay() if you must or better use millis() timing.
void loop()
{
static unsigned long timer = 0;
unsigned long interval = 50; // send 20 times per second
if (millis() - timer >= interval)
{
timer = millis();
buttonValues.but1 = digitalRead(button_pin1);
buttonValues.but2 = digitalRead(button_pin2);
buttonValues.but3 = digitalRead(button_pin3);
buttonValues.but4 = digitalRead(button_pin4);
buttonValues.but5 = digitalRead(button_pin5);
buttonValues.but6 = digitalRead(button_pin6);
radio.write( &buttonValues, sizeof(buttonValues) );
}
}
Non-blocking timing tutorials:
Blink without delay().
Beginner's guide to millis().
Several things at a time.
The receive code looks OK. Does it do what you want?
nothing does anything, maybe my transmitter and receiver are wired wrong?
The only thing that happens when I plug it in is that the servos move to a certain position. Nothing else is happening
Please post a wiring diagram. Written descriptions are always more ambiguous than a drawing. Hand drawn, photographed and posted is fine. Include all pin names/numbers, components, their part numbers and/or values and power supplies.
If you made any changes to your code since the last time that you posted code, please post the latest version.
That's why ppl recommend that you establish an ability to communicate between two very simple sketches and circuits, each an Arduino board with an NRF24L01.
Find a tutorial that explains the wiring and has some super simple demo sketches. Do not deviate from the instructions or code. Work until you get the predicted and desired behaviour.
Before you start trying to accomplish anything in the larger project.
Getting that radio set to work has caused a great desk of pain; getting them to work in the context of a real project without having done a simple test is foolish.
a7
+1 for getting the radios to work by themselves using available examples. The example code in Robin2's simple rf24 tutorial is proven to work and is a great starting point.
Here are some tips that I found while getting my rf24 radios to work.
If you read and, closely, follow Robin2's simple rf24 tutorial you should be able to get them working. That tutorial sure helped me. The code in the examples has been proven to work many many times. If it does not work for you, there is likely a hardware problem.
Run the CheckConnection.ino (look in reply #30 in the tutorial) to verify the physical wiring between the radio module and its processor (Arduino). This is especially useful if all you see is “Data received” repeating much more quickly then there is a problem - most likely theArduino is not communicating properly with its nRF24.
Make sure the rf24 power supply can provide enough current. This is especially true for the high power (external antenna) modules. I use homemade adapters like these. They are powered by 5V and have a 3.3V regulator on the board. Robin2 also has suggested trying with a 2 AA cell battery pack.
If using the high powered radios make sure to separate them by a few meters. They may not work too close together. Try the lower power settings.
Reset the radios by cycling power to them after uploading new code. I have found that to help. They do not reset with the Arduino.
Sending too often can also cause a problem. Trying to send every time through a fast loop may not work. Slow down to 1 to 5 packets per second to test.
Switch to 1MB data rate to catch the not so cloned clones.
radio.setDataRate( RF24_1MBPS );
Also for some clones, change TMRh20's RF24.cpp line 44
_SPI.setClockDivider(SPI_CLOCK_DIV2);
Into
_SPI.setClockDivider(SPI_CLOCK_DIV4);
Have a look at the common problems page.
I forgot to mention that I have one of the adapters for the transmitter. I tested the transmitter and receiver codes when I had it hooked up to 3.3 volts, and it failed. when I hooked it up to 5 volts and tested it, it worked.
I got the radios to work, but the servos and other components connected to the receiver go crazy.