I haven’t finished writing the how-to yet but I have students asking if they can see the code samples, so I am throwing up this page temporarily but later it will get removed when the full how-to is done.
This is the RECEIVER code you put on the robot to be able to drive by RF signals it receives:
#include <VirtualWire.h> // The VirtualWire library is used to control our RF receiver
int pinRF_Receiver = 11; // defining pin D11 as the data pin for the RF receiver module
int pinLB = 7; // defining pin D2 as a control signal for the left wheel reverse direction
int pinLF = 8; // defining pin D4 as a control signal for the left wheel forward direction
int pinRB = 2; // defining pin D7 as a control signal for the right wheel reverse direction
int pinRF = 4; // defining pin D8 as a control signal for the right wheel forward direction
unsigned long previousMillis = 0; // will store last time the timer was updated
long interval = 250; // interval at which to halt the motors if no command has been received, aka signal from the transmitter lost (in milliseconds)
void M_Control_IO_config(void)
{
pinMode(pinLB,OUTPUT); // pin2
pinMode(pinLF,OUTPUT); // pin4
pinMode(pinRB,OUTPUT); // pin7
pinMode(pinRF,OUTPUT); // pin8
}
void runMotors_bothForward() // going forward
{
digitalWrite(pinRB,LOW); // making motor move towards right rear
digitalWrite(pinRF,HIGH);
digitalWrite(pinLB,LOW); // making motor move towards left rear
digitalWrite(pinLF,HIGH);
interval = 250;
}
void runMotors_turnRight() //turning right(dual wheel)
{
digitalWrite(pinRB,LOW); //making motor move towards right rear
digitalWrite(pinRF,HIGH);
digitalWrite(pinLB,HIGH);
digitalWrite(pinLF,LOW); //making motor move towards left front
interval = 100; // temporarily set the timeout a little lower for better control
}
void runMotors_turnLeft() //turning left(dual wheel)
{
digitalWrite(pinRB,HIGH);
digitalWrite(pinRF,LOW ); //making motor move towards right front
digitalWrite(pinLB,LOW); //making motor move towards left rear
digitalWrite(pinLF,HIGH);
interval = 100; // temporarily set the timeout a little lower for better control
}
void stopMotors() //stop
{
digitalWrite(pinRB,HIGH);
digitalWrite(pinRF,HIGH);
digitalWrite(pinLB,HIGH);
digitalWrite(pinLF,HIGH);
}
void runMotors_bothReverse() //runMotors_bothReverse up
{
digitalWrite(pinRB,HIGH); //making motor move towards right rear
digitalWrite(pinRF,LOW);
digitalWrite(pinLB,HIGH); //making motor move towards left rear
digitalWrite(pinLF,LOW);
interval = 250;
}
void setup()
{
Serial.begin(9600); //initializing serial port in case we need to write debugging info to the serial monitor
M_Control_IO_config(); // Setup the output pins that send control signals to the dual motor driver board
stopMotors(); // Make sure the car starts out in the stopMotorsed state
vw_setup(2000); // set up the RF receiver @ 2000 bits per second
vw_set_rx_pin(11); // set up the receiver to listen on digital pin 11
vw_rx_start(); // Begin listening for signals from the transmitter
}
void loop()
{
unsigned long currentMillis = millis(); // Current robot time
byte message[VW_MAX_MESSAGE_LEN];
byte messageLength = VW_MAX_MESSAGE_LEN;
if (vw_get_message(message, &messageLength)) // if the receiver gets a message
{
previousMillis = currentMillis; // We received a signal from the transmitter so we will reset the timer
for (int i = 0; i < messageLength; i++)
{
Serial.write(message[i]); // print in the received message in the serial monitor
if (message[i] == 'w'){ // if message received is 'w', make the motors drive forward
runMotors_bothForward();
}
if (message[i] == 'x'){ // if message received is 'x', make the motors stop
stopMotors();
}
if(message[i] == 'a'){ // if message received is 'a', make the motors turn the bot left
runMotors_turnLeft();
}
if(message[i] == 's') { // if the message received is 's' , make the motors drive runMotors_bothReversewards
runMotors_bothReverse();
}
if (message[i] == 'd') { //if the message received is 'd', make the motors turn the bot right
runMotors_turnRight();
}
}
Serial.println();
}else{
// No message was recieved from the transmitter, check our timer:
if (currentMillis - previousMillis >= interval) {
// If we have not received a message for a while from the transmitter because it is off, or out of range, etc then we stop the motors:
stopMotors();
}
}
}
This is the TRANSMITTER code used on the other Arduino from your starter kit with the joystick and transmitter module:
#include <VirtualWire.h> // The VirtualWire library is used to control our transmitter module
#define Xpin A0 // Define Xpin on A0 (analog) for the X axis of the joystick
#define Ypin A1 // Define Ypin on A1 (analog) for the Y axis of the joystick
int X = 0; // X will be an integer value read from the joystick
int Y = 0; // Y will be an integer value read from the joystick
void setup() {
vw_setup(2000); // begin wireless transmission @ 2000 bps
vw_set_tx_pin(12); // set the digital pin 12 to be the transmit pin we send the signal to the module over
Serial.begin(9600); // begin serial communication with the arduino @ 9600 baud for debugging
}
void loop() {
X = analogRead(Xpin); // Do an analog read of the X axis and store the value in the previously defined integer X
Y = analogRead(Ypin); // Same as above for Y
// The values that come back from the joystick have a much wider range than we need, so we will scale the values down:
X = map(X, 0, 1023, 0, 10); // Map the values of X axis from 0 to 1023, to 0 to 10
Y = map(Y, 0, 1023, 0, 10); // Map the values of Y axis from 0 to 1023, to 0 to 10
/* In the following IF blocks we consider the X and Y values we read from the joystick and decide what to transmit */
/* Some joysticks read a little bit different values so you may need to tweak the decision values a bit in some cases */
/* We will transmit desired motion as WASDX commands, a single letter at a time */
if (X == 4 && Y == 4) { // if the value of X and Y axis is 4 then the joystick is centered and the car should not drive
char *msg = "x"; // store the character 'x' in a char named msg
digitalWrite(13, true); // light up the d13 LED to show transmission
vw_send((uint8_t *)msg, strlen(msg)); // send the message 'x' via the transmitter
vw_wait_tx(); // wait until the whole message is sent
digitalWrite(13, false); // turn off the D13 LED once the message is sent
Serial.println("STOPPED"); // print "STOPPED" in the serial monitor
}
if (X == 0 && Y >= 4) { // if X is equal to zero and Y is more than equal to 4
char *msg = "s"; // store the message 's' in a char named msg
digitalWrite(13, true); // light up the D13 LED to show transmission
vw_send((uint8_t *)msg, strlen(msg)); // send the message 's' via the transmitter
vw_wait_tx(); // wait for the message to be sent
digitalWrite(13, false); // flash the D13 led off to show that the message is sent
Serial.println("GOING BACKWARD"); // print "GOING BACKWARD" in the serial monitor
}
if (X >= 3 && Y == 9) { // if X is more than equal to 3 and Y is equal to 9
char *msg = "a"; // store the message 'a' in a char named msg
digitalWrite(13, true); // light up the D13 LED to show transmission
vw_send((uint8_t *)msg, strlen(msg)); // send the message 'a' via the transmitter
vw_wait_tx(); // wait for the message to be sent
digitalWrite(13, false); // turn off the D13 LED to show that the message is sent
Serial.println("GOING LEFT"); // print "GOING LEFT" in the serial monitor
}
if (X == 10 && Y >= 4) { // if X is equal to 10 and Y is more than equal to 4
char *msg = "w"; // store the message 'w' in a char named msg
digitalWrite(13, true); // light up the D13 LED to show transmission
vw_send((uint8_t *)msg, strlen(msg)); // send the message 'w' via the transmitter
vw_wait_tx(); // wait until the whole message is sent
digitalWrite(13, false); // turn off the D13 LED to show that message is sent
Serial.println("GOING FORWARD"); // print "GOING FORAWARD" in the serial monitor
}
if ( X >= 3 && Y == 0) { // if X is greater than equal to 3 and Y is equal to 0
char *msg = "d"; // store the message 'd', in a char named msg
digitalWrite(13, true); // light up the D13 LED to show transmission
vw_send((uint8_t *)msg, strlen(msg)); // send the message 'd' via the transmitter
vw_wait_tx(); //wait until the whole message is sent
digitalWrite(13, false); // turn off the D13 LED to show that message is sent
Serial.println("GOING RIGHT"); // print "GOING RIGHT" in the serial monitor
}
/*Serial.print("X IS "); Serial.print(X);
Serial.print(" Y IS "); Serial.print(Y);
Serial.println();*/
}
Alternative Servo LIbrary:
Suppose you finished the above and your robot now drives via the RF transmitter setup. Great! Wouldn’t it be fun to add a couple buttons to our transmitter to move the servo head? Sure! If you try this using the previous examples, however, you quickly find that there is a conflict between the VirtualWire.h library (used for the RF receiver) and the Servo.h library.
This happens because both of those libraries are trying to use Timer1 on the Arduino Uno board. Without going into great detail, suffice to say the libraries are incapable of sharing the Timer1 resource and hence any code using both Servo.h and VirtualWire.h will not compile.
There are other ways of running a servo on an Arduino that don’t use Servo.h, the only catch is that most of them are tricker to use.
Here is an example of an alternative servo library that uses Timer2 on the Arduino (avoiding the conflict with anything using Timer1)
https://create.arduino.cc/projecthub/ashraf_minhaj/how-to-use-servotimer2-library-simple-explain-servo-sweep-512fd9
The problem with ServoTimer2 library is that it is not currently in CodeBender’s list of libraries. If you are programming your Arduino from a Windows or Mac computer with the regular Arduino IDE, you can download ServoTimer2 and use it. If you only have your ChromeBook and codebender, however, it won’t work as CodeBender doesn’t currently support adding external libraries that aren’t already in their list.
You can Google for other alternatives, but at the time of this writing CodeBender is only known to have the one Servo.h library and its fairly impractical to control servos without a library hooked into at least one of the hardware timers on the Arduino.
You might want to look into other ways of programming Arduino from a ChromeBook to see if you can find something that allows the use of external libraries, or if you have a windows or mac computer try installing the Arduino IDE on there and use that instead.