arduino rc car/autonomous vehicle

Hi guys

Basically what I'm trying to build is a remote control vehicle, with an autonomous function. I'm using a transmitter and receiver for the remote control bit. I would like the car to go into autonomous mode when I flick the toggle switch on my transmitter, but I'm having problems :(. So far I have got the car being controlled manually with the transmitter, but struggling with the autonomous mode.

Here's the code so far

int motor1_a = 5; // motor 1 outputs
int motor1_b = 9;

int motor2_a = 6; // motor 2 outputs
int motor2_b = 10;


int servo1 = 2;  // r/c channel 1
int servo2 = 3;  // r/c channel 2
int ppm = 7;
int servo_val;
int LED_pin = 13;



//int relay_Pin = 8;

unsigned int relay_val;

volatile unsigned long servo1_startPulse;  //values for channel 1 signal capture
volatile unsigned servo1_val; 
volatile int adj_val1;  
volatile int servo1_Ready;

volatile unsigned long servo2_startPulse; //values for channel 2 signal capture
volatile unsigned servo2_val; 
volatile int adj_val2;  
volatile int servo2_Ready;

int deadband_high = 275; 
int deadband_low = 235;  

int pwm_ceiling = 256; 
int pwm_floor = 255;  

int low1 = 1108;  // adjust these values if your R/C readings are above or below these for channels 1 and 2.
int high1 = 1908;
int low2 = 1096;
int high2 = 1900;

int n = 0;

void setup() {
  
  //TCCR0B = TCCR0B & 0b11111000 | 0x03;
  //TCCR1B = TCCR1B & 0b11111000 | 0x01;
  
  Serial.begin(9600);
  
  //motor1 pins
  pinMode(motor1_a, OUTPUT);
  pinMode(motor1_b, OUTPUT);

  pinMode(motor2_a, OUTPUT);
  pinMode(motor2_b, OUTPUT);

  pinMode(LED_pin, OUTPUT); // declare output
  
 


  //PPM inputs from RC receiver
  pinMode(servo1, INPUT); //Pin 2 as input
  pinMode(servo2, INPUT); //Pin 3 as input
  pinMode(ppm, INPUT); // declare input

  
  //digitalWrite(relay_Pin, LOW);
  
  delay(1200);

  attachInterrupt(0, rc1_begin, RISING);    // catch interrupt 0 (digital pin 2) going HIGH and send to rc1()
  attachInterrupt(1, rc2_begin, RISING);    // catch interrupt 1 (digital pin 3) going HIGH and send to rc2()

}

////////// attach servo signal interrupts to catch signals as they go HIGH then again as they go LOW, then calculate the pulse length.

void rc1_begin() {           // enter rc1_begin when interrupt pin goes HIGH.

  servo1_startPulse = micros();     // record microseconds() value as servo1_startPulse
  
  detachInterrupt(0);  // after recording the value, detach the interrupt from rc1_begin
  
  attachInterrupt(0, rc1_end, FALLING); // re-attach the interrupt as rc1_end, so we can record the value when it goes low
  
}

void rc1_end() {
 
 servo1_val = micros() - servo1_startPulse;  // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
  
 detachInterrupt(0);  // detach and get ready to go HIGH again
 
 attachInterrupt(0, rc1_begin, RISING);
 
}

void rc2_begin() {

  servo2_startPulse = micros();

  detachInterrupt(1);
  
  attachInterrupt(1, rc2_end, FALLING);
  


}

void rc2_end() {
 
 servo2_val = micros() - servo2_startPulse;
  
 detachInterrupt(1);
 
 attachInterrupt(1, rc2_begin, RISING); 
 
}
/////// servo interrupts end

/////// MAIN LOOP

void loop() {
  // use pulseIn() command to read the length of the pulse on D2, with a timeout of 20mS (20000uS)
servo_val = pulseIn(ppm, HIGH, 20000);
// check the pulse length to see if it is above 1600 microseconds (ie. Above neutral)
if (servo_val > 1600){
// if so, turn LED off
digitalWrite(LED_pin, HIGH);
Serial.println("Failsafe Active!");

///// channel 1 good signal check
 if (servo1_val < 600 || servo1_val > 2400) {  // only set the servo1_Ready flag if the value is a valid Servo pulse between 600-2400 microseconds.
  servo1_Ready = false; 
  servo1_val = 1500;
 }
 else {
  servo1_Ready = true; // if not, don't pass the value to be processed
 }

///// channel 1 good signal check

 if (servo2_val < 600 || servo2_val > 2400) {
  servo2_Ready = false; 
  servo2_val = 1500;
 }
 else {
  servo2_Ready = true; 
 }

////////// channel 1 motor update	         


    if (servo1_Ready) {
      
      servo1_Ready = false;  
      adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 511); 
      constrain(adj_val1, 0, 511);

      if (adj_val1 < 0) {
        adj_val1 = 0; 
      }     
      if (adj_val1 > 511) {
        adj_val1 = 511; 
      }

      if (adj_val1 > deadband_high) {
        //Forward
        digitalWrite(motor2_a , LOW);
        analogWrite(motor1_a, adj_val1 - pwm_ceiling); 
        
      }
      else if (adj_val1 < deadband_low) {
        //REVERSE
        digitalWrite(motor1_a, LOW);
        analogWrite(motor2_a, pwm_floor - adj_val1);
        
      }
      else {
        //STOP
        digitalWrite(motor1_a, LOW);
        digitalWrite(motor2_a, LOW);
        
      }
      
    }
    
///////////// channel 2 motor update

   if (servo2_Ready) {
      
      servo2_Ready = false;  
      adj_val2 = map(constrain(servo2_val, 600, 2400), low1, high1, 0, 505); 
      constrain(adj_val2, 0, 505);

      if (adj_val2 < 0) {
        adj_val2 = 0; 
      }     
      if (adj_val2 > 505) {
        adj_val2 = 505; 
      }

      if (adj_val2 > deadband_high) {
        //Forward
        digitalWrite(motor2_b, LOW);
        analogWrite(motor1_b, adj_val2 - pwm_ceiling); 
        
      }
      else if (adj_val2 < deadband_low) {
        //REVERSE
        digitalWrite(motor1_b, LOW);
        analogWrite(motor2_b, pwm_floor - adj_val2);
        
      }
      else {
        //STOP
        digitalWrite(motor1_b, LOW);
        digitalWrite(motor2_b, LOW);
        
      }
   }
      else  {
        delay(3000);
// otherwise if signal is below 1600 uS, turn LED Off
       
        digitalWrite(LED_pin, 0);
       
        Serial.println("Failsafe turned Off");
      
    }
   }
    //print values to Serial monitor in Arduino IDE
    Serial.print("ch1:  ");
    Serial.print(adj_val1);
    Serial.print("  ");
    Serial.print("rc1:  ");
    Serial.print(servo1_val);
    Serial.print("  ");
    Serial.print("ch2:  ");
    Serial.print(adj_val2);
    Serial.print("  ");
    Serial.print("rc2:  ");
    Serial.print(servo2_val);
    Serial.print("  ");
    Serial.print("loop counter:  ");
    Serial.print(n);
    Serial.println("  ");    

    //n++;

 
}

The car has tank steering setup.

When I flick the toggle switch on the transmitter, which is connected to pin 7 on the arduino, the Led is meant to turn off, but it doesn't. As you'v probably guessed this is where I would like my autonomous section to be implemented., when I flick the toggle switch.
Can someone help me out :slight_smile:
Btw have a great christmas n a happy new year :smiley:
cheers
Sam

heres a photo

oh and I want to use ultrasonic sensors for autonomous mode

Holiday reading that may have some info you need.

https://www.google.com/search?as_q=arduino+autonomous&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=http%3A%2F%2Fforum.arduino.cc%2Findex&as_occt=any&safe=images&tbs=&as_filetype=&as_rights=

https://www.google.com/search?as_q=arduino+autonomous&as_epq=&as_oq=&as_eq=&as_nlo=&as_nhi=&lr=&cr=&as_qdr=all&as_sitesearch=&as_occt=any&safe=images&tbs=&as_filetype=&as_rights=

Hi
zoomkat
thanks for replying will look through links
holiday greeting
cheers

Still having problems
anymore help XD

I got the toggle switch working now with a LED. Now trying to program HC-SRO ultrasonic sensor, with pan and tilt, struggling lol

heres the code

#include <Servo.h> // need the standard Arduino servo library

int motor1_a = 5; // motor 1 outputs
int motor1_b = 9;

int motor2_a = 6; // motor 2 outputs
int motor2_b = 10;



int panPin = 10;  // this is Servo used for panning (horizontal plane movement)
int tiltPin = 11; // This is Servo used for tilting (vertical plane movement)
Servo panServo, tiltServo;



int trigPin = A4;   // Analog pin 0 used for the Ping Pin (Trig)
int echoPin = A5;   // Analog pin 1 used for the Echo Pin (Echo)
unsigned long duration, inches;
int indec, cmdec;
int inchconv = 147; // ratio between pulse width and inches
int cmconv = 59;    // ratio between pulse width and cm
String s1, s2, s3;
int panCentre = 110;

int servo1 = 2;  // r/c channel 1
int servo2 = 3;  // r/c channel 2
int ppm = 7; // read R/C receiver from this pin

int servo_val; // use “servo_val” to hold the pulse length
int LED_pin = 13; // control LED on Arduino D13




volatile unsigned long servo1_startPulse;  //values for channel 1 signal capture
volatile unsigned servo1_val; 
volatile int adj_val1;  
volatile int servo1_Ready;

volatile unsigned long servo2_startPulse; //values for channel 2 signal capture
volatile unsigned servo2_val; 
volatile int adj_val2;  
volatile int servo2_Ready;

int deadband_high = 275; 
int deadband_low = 235;  

int pwm_ceiling = 256; 
int pwm_floor = 255;  

int low1 = 1108;  // adjust these values if your R/C readings are above or below these for channels 1 and 2.
int high1 = 1908;
int low2 = 1096;
int high2 = 1900;

int n = 0;

void setup()
{
  // initialize the digital pins we will use as an output for the motor
  pinMode(motor1_a, OUTPUT);
  pinMode(motor1_b, OUTPUT);

  pinMode(motor2_a, OUTPUT);
  pinMode(motor2_b, OUTPUT);

  Serial.begin(115200);
  
  // initialize the ultrasonic sensor pins and centre the servos
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  panServo.attach(panPin, 1000, 2000);
  tiltServo.attach(tiltPin, 1000, 2000);
  pointCentre();
  tiltServo.write(90);


//Led pin
  pinMode(LED_pin, OUTPUT); // declare output
  

  
//PPM inputs to RC receiver
  pinMode(ppm, INPUT); // declare input
  pinMode(servo1, INPUT); //Pin 2 as input
  pinMode(servo2, INPUT); //Pin 3 as input
  
  delay(1200);
  
  attachInterrupt(0, rc1_begin, RISING);    // catch interrupt 0 (digital pin 2) going HIGH and send to rc1()
  attachInterrupt(1, rc2_begin, RISING);    // catch interrupt 1 (digital pin 3) going HIGH and send to rc2()
}
void rc1_begin() {           // enter rc1_begin when interrupt pin goes HIGH.

  servo1_startPulse = micros();     // record microseconds() value as servo1_startPulse
  
  detachInterrupt(0);  // after recording the value, detach the interrupt from rc1_begin
  
  attachInterrupt(0, rc1_end, FALLING); // re-attach the interrupt as rc1_end, so we can record the value when it goes low
  
}

void rc1_end() {
 
 servo1_val = micros() - servo1_startPulse;  // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
  
 detachInterrupt(0);  // detach and get ready to go HIGH again
 
 attachInterrupt(0, rc1_begin, RISING);
 
}

void rc2_begin() {

  servo2_startPulse = micros();

  detachInterrupt(1);
  
  attachInterrupt(1, rc2_end, FALLING);
  


}

void rc2_end() {
 
 servo2_val = micros() - servo2_startPulse;
  
 detachInterrupt(1);
 
 attachInterrupt(1, rc2_begin, RISING); 
 
}


void loop()
{
  // use pulseIn() command to read the length of the pulse on D2, with a timeout of 20mS (20000uS)
servo_val = pulseIn(ppm, HIGH, 20000);
// check the pulse length to see if it is above 1600 microseconds (ie. Above neutral)
if (servo_val > 1600){
// if so, turn LED On
digitalWrite(LED_pin, HIGH);

 
  int cm, lcm, rcm;
  forward(100, 200);
  cm = getDistance();
  if(cm < 30)
  {
    halt(0);
    pointLeft();
    lcm = getDistance();
    pointRight();
    rcm = getDistance();
    pointCentre();
    reverse(400, 255);
    halt(0);
    if (rcm < lcm)
      rightSpin(200);
    else
      leftSpin(200);
    halt(0);
  }
}

void pointLeft()
{
  panServo.write(panCentre - 60);
  delay(150); // wait for servo to get there
}

void pointRight()
{
  panServo.write(panCentre + 60);
  delay(300); // wait for servo to get there
}

void pointCentre()
{
  panServo.write(panCentre);
  delay(150); // wait for servo to get there
}

int getDistance()
{
  int rval;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH, 38000L);  // Set timeout to 38mS
  rval = microsecondsToCentimeters(duration);
  Serial.println(rval);
  return rval;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / cmconv;
}

// robMove routine switches the correct inputs to the L298N for the direction selected.
void robMove(int l1, int l2, int r1, int r2)
{
  analogWrite(motor1_a, l1);
  digitalWrite(motor2_a, l2);
  analogWrite(motor2_b, r1);
  digitalWrite(motor1_b, r2);    
}

void reverse(int wait, int vSpeed)
{
  Serial.println("Moving backward");
  robMove(255-vSpeed, HIGH, 255-vSpeed, HIGH);    // when reversing, the speed needs to be opposite, so subtract from 255
  delay(wait);
}

void forward(int wait, int vSpeed)
{
  Serial.println("Moving forward");
  robMove(vSpeed, LOW, vSpeed, LOW);
  delay(wait);
}

void rightSpin(int wait)
{
  Serial.println("Spinning right");
  robMove(255, LOW, 0, HIGH);
  delay(wait);
}

void leftSpin(int wait)
{
  Serial.println("Spinning left");
  robMove(0, HIGH, 255, LOW);
  delay(wait);
}

void rightTurnFd(int wait, int lSpeed, int rSpeed)
{
  Serial.println("Turning right forward");
  robMove(lSpeed, LOW, rSpeed, LOW);
  delay(wait);
}

void leftTurnFd(int wait, int lSpeed, int rSpeed)
{
  Serial.println("Turning left forward");
  robMove(lSpeed, LOW, rSpeed, LOW);
  delay(wait);
}

void rightTurnBd(int wait, int lSpeed, int rSpeed)
{
  Serial.println("Turning right backward");
  robMove(255-lSpeed, HIGH, 255-rSpeed, HIGH);
  delay(wait);
}

void leftTurnBd(int wait, int lSpeed, int rSpeed)
{
  Serial.println("Turning left backward");
  robMove(255-lSpeed, HIGH, 255-rSpeed, HIGH);
  delay(wait);
}

void halt(int wait)
{
  Serial.println("Stopping");
  robMove(0, LOW, 0, LOW);
  delay(wait);
}

Serial.println("Autonomous mode");
}
else {
// otherwise if signal is below 1600 uS, turn LED Off
digitalWrite(LED_pin, LOW);
analogWrite(motor2_a, 0);
analogWrite(motor1_a, 0);
analogWrite(motor1_b, 0);
analogWrite(motor2_b, 0);

if (servo1_val < 600 || servo1_val > 2400) {  // only set the servo1_Ready flag if the value is a valid Servo pulse between 600-2400 microseconds.
  servo1_Ready = false; 
  servo1_val = 1500;
 }
 else {
  servo1_Ready = true; // if not, don't pass the value to be processed
 }


if (servo2_val < 600 || servo2_val > 2400) {
  servo2_Ready = false; 
  servo2_val = 1500;
 }
 else {
  servo2_Ready = true; 
 }
 
 

 if (servo1_Ready) {
      
      servo1_Ready = false;  
      adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 511); 
      constrain(adj_val1, 0, 511);

      if (adj_val1 < 0) {
        adj_val1 = 0; 
      }     
      if (adj_val1 > 511) {
        adj_val1 = 511; 
      }

      if (adj_val1 > deadband_high) {
        //Forward
        digitalWrite(motor2_a , LOW);
        analogWrite(motor1_a, adj_val1 - pwm_ceiling); 
        
      }
      else if (adj_val1 < deadband_low) {
        //REVERSE
        digitalWrite(motor1_a, LOW);
        analogWrite(motor2_a, pwm_floor - adj_val1);
        
      }
      else {
        //STOP
        digitalWrite(motor1_a, LOW);
        digitalWrite(motor2_a, LOW);
        
      }
      
    }
    
///////////// channel 2 motor update

   if (servo2_Ready) {
      
      servo2_Ready = false;  
      adj_val2 = map(constrain(servo2_val, 600, 2400), low1, high1, 0, 505); 
      constrain(adj_val2, 0, 505);

      if (adj_val2 < 0) {
        adj_val2 = 0; 
      }     
      if (adj_val2 > 505) {
        adj_val2 = 505; 
      }

      if (adj_val2 > deadband_high) {
        //Forward
        digitalWrite(motor2_b, LOW);
        analogWrite(motor1_b, adj_val2 - pwm_ceiling); 
        
      }
      else if (adj_val2 < deadband_low) {
        //REVERSE
        digitalWrite(motor1_b, LOW);
        analogWrite(motor2_b, pwm_floor - adj_val2);
        
      }
      else {
        //STOP
        digitalWrite(motor1_b, LOW);
        digitalWrite(motor2_b, LOW);
        
      }
      
    }

    Serial.println("Radio controlled");
}
}
// end of code