Hello everyone,
I am new to the Arduino community and I just finished my first project. The kids loved it!
I though I would share the code so it can inspire other newbies. Basically, an arduino driven shift register is coordinating 2H-Bridge motor drivers. Depending on speed, it uses differential or skid steering. Comments are welcome.
The Rover
/* ---------------------------------------------
Controling 4WD RC vehicule
PARTS
- 2 Arduino Uno
- 2 H-bridge IC (SN754410)
- 1 Shift Register (74HC595)
- 2 2.4Ghz rf transivers (nRF24L01)
- 1 Joystick
- 1 4wd chassis (DAGU robot)
PRINCIPLE
Shist register pins QA-QH are connected to all
8 h-bridge A pins (1A-2A,3A-4A).
TIPS
PWM Enable Pins must be filtered (Low Pass Filtering) for
nice tork and smooth control of the speed.
--------------------------------------------- */
// H-bridge Enable pins
const int EN1=5;
const int EN2=6;
// Shift Register pins
const int SER = 8;
const int LATCH = 7;
const int CLK = 4;
// Initializing constants
int valSpeed = 0;
int valSteer = 0;
int velocity = 0;
int steer = 0;
/* - CONNECTIONS: nRF24L01 Modules See:
http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
1 - GND
2 - VCC => 3.3V
3 - CE => pin 9
4 - CSN => pin 10
5 - SCK => pin 13
6 - MOSI => pin 11
7 - MISO => pin 12
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE_PIN 9
#define CSN_PIN 10
// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
int joystick[2]; // 2 element array holding Joystick readings
void setup()
{
//Serial.begin(9600);
delay(1000);
//Serial.println("Nrf24L01 Receiver Starting");
// Enable pins
pinMode(EN1, OUTPUT);
pinMode(EN2, OUTPUT);
// Shift Register
pinMode(SER, OUTPUT);
pinMode(LATCH, OUTPUT);
pinMode(CLK, OUTPUT);
radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();;
brake(); //Initialize with motor stopped
}
void loop()
{
//RADIO TRANSMISSION
if ( radio.available() )
{
// Read the data payload until we've received everything
bool done = false;
while (!done)
{
// Fetch the data payload
done = radio.read( joystick, sizeof(joystick) );
}
}
else
{
//Serial.println("No radio available");
}
valSpeed = joystick[1];
valSteer = joystick[0];
/*Serial.print("valSeed = ");
Serial.print(valSpeed);
Serial.print(" valSteer = ");
Serial.println(valSteer); */
Serial.println( " Hello World!");
//go forward
if (valSpeed > 562)
{
velocity = map(valSpeed, 563, 1023, 0, 255);
forward(velocity,valSteer);
}
//go backward
else if (valSpeed < 462)
{
velocity = map(valSpeed, 461, 0, 0, 255);
reverse(velocity,valSteer);
}
//brake
else if (valSteer > 562 || valSteer < 462)
{
velocity= 255;
skid(valSteer,velocity);
}
else
{
brake();
}
}
//Motor goes forward at given rate (from 0-255)
void reverse (int rate,int valsteer)
{
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
digitalWrite(LATCH,LOW);
shiftOut(SER,CLK,MSBFIRST,B01010101);
digitalWrite(LATCH,HIGH);
// Sterring Left
if (valsteer > 562)
{
steer = map(valsteer, 563, 1023, 200, 0);
analogWrite(EN1, rate);
analogWrite(EN2, steer);
}
// Sterring Right
else if (valsteer < 462)
{
steer = map(valsteer, 461, 0, 200, 0);
analogWrite(EN1, steer);
analogWrite(EN2, rate);
}
// Same speed on both sides
else
{
analogWrite(EN1, rate);
analogWrite(EN2, rate);
}
}
//Motor goes backward at given rate (from 0-255)
void forward (int rate, int valsteer)
{
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
digitalWrite(LATCH,LOW);
shiftOut(SER,CLK,MSBFIRST,B10101010);
digitalWrite(LATCH,HIGH);
// Sterring Left
if (valsteer > 562)
{
steer = map(valsteer, 563, 1023, 200, 0);
analogWrite(EN1, rate);
analogWrite(EN2, steer);
}
// Sterring Right
else if (valsteer < 462)
{
steer = map(valsteer, 461, 0, 200, 0);
analogWrite(EN1, steer);
analogWrite(EN2, rate);
}
// Same speed on both sides
else
{
analogWrite(EN1, rate);
analogWrite(EN2, rate);
}
}
void skid (int valsteer, int rate) {
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
digitalWrite(LATCH,LOW);
if (valsteer > 562)
{
shiftOut(SER,CLK,MSBFIRST,B10100101);
}
else if (valsteer < 462)
{
shiftOut(SER,CLK,MSBFIRST,B01011010);
}
digitalWrite(LATCH,HIGH);
analogWrite(EN1,rate);
analogWrite(EN2,rate);
}
//Stops motor
void brake ()
{
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
analogWrite(EN1, 0);
analogWrite(EN2, 0);
}
The Joystick
/* YourDuinoStarter Example: nRF24L01 Transmit Joystick values
- WHAT IT DOES: Reads Analog values on A0, A1 and transmits
them over a nRF24L01 Radio Link to another transceiver.
- SEE the comments after "//" on each line below
- CONNECTIONS: nRF24L01 Modules See:
http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
1 - GND
2 - VCC 3.3V !!! NOT 5V
3 - CE to Arduino pin 9
4 - CSN to Arduino pin 10
5 - SCK to Arduino pin 13
6 - MOSI to Arduino pin 11
7 - MISO to Arduino pin 12
8 - UNUSED
-
Analog Joystick or two 10K potentiometers:
GND to Arduino GND
VCC to Arduino +5V
X Pot to Arduino A0
Y Pot to Arduino A1
- V1.00 11/26/13
Based on examples at http://www.bajdi.com/
Questions: terry@yourduino.com */
/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define CE_PIN 9
#define CSN_PIN 10
#define JOYSTICK_X A1
#define JOYSTICK_Y A2
// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe
/*-----( Declare objects )-----*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
/*-----( Declare Variables )-----*/
int joystick[2]; // 2 element array holding Joystick readings
void setup() /****** SETUP: RUNS ONCE ******/
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipe);
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
joystick[0] = analogRead(JOYSTICK_X);
joystick[1] = analogRead(JOYSTICK_Y);
radio.write( joystick, sizeof(joystick) );
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
//NONE
//*********( THE END )***********