James Martel
Published © GPL3+

What Do I Build Next? Some Assembly Required? Part 5 of 4

I've built these two Tanked Vehicles using Raspberry Pi... now to convert one to Arduino

IntermediateFull instructions provided4 hours547
What Do I Build Next? Some Assembly Required? Part 5 of 4

Things used in this project

Hardware components

Kookye Arduino Electronics Kit
×1
Sainsmart Tank Chassis
×1
18650 Battery and Charger
Be sure to read reviews, I purchased 3000maH Ultrafire batteries
×2

Story

Read more

Schematics

Battery Pack and Power Distribution

Ultrasonic sensor Interconnect

Buzzer Interconnect

IR Receiver Interconnect

L298N Motor Controller Interconnect

Motors to L298N Interconnect

L298N Voltage Display Interconnect

Servo Interconnect

ESP8266 and LEDs

Tracking Sensors Interconnect

Code

tank_robot_lessons_CODE.zip

Arduino
Hopefully this is all code examples
No preview (download only).

Servo Adjust

Arduino
This is used in 2nd Learning lesson to center the servo horn
#include <Servo.h>
#define SERVO_PIN     11  //servo connect to D11
Servo myservo;
void setup() {
  myservo.attach(SERVO_PIN); // 
  myservo.write(90); //turn to middle posiztion
}

void loop() {
}

Lesson 2 All Modules Testing code

Arduino
For Setup and testing individual modules
#include <Servo.h>
#include <IRremote.h>
#define IN1  8   //K1K2 motor direction
#define IN2  9     //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define LED1 2  //lefe led connect to D2
#define LED2 3  //right led connect to D3
#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define LFSensor_1 A0 //line follow sensor1
#define LFSensor_2 A1 //line follow sensor2
#define SERVO     11  //servo connect to D11
#define echo    A3 // Ultrasonic Echo pin connect to A2
#define trig    A2  // Ultrasonic Trig pin connect to A3
#define buzzer     7 //buzzer connect to D7
Servo head;    // create servo object to control a servo
IRrecv IR(IRPIN);  //   IRrecv object  IR get code from IR remoter
decode_results IRresults;   
String inputString = "";//Store serial data
boolean stringComplete = false;  // whether the string is complete

int pos = 0;
void setup() {
  /******LED******/
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  digitalWrite(LED1,HIGH);
  digitalWrite(LED2,HIGH);
  /*line follow sensors */
  pinMode(LFSensor_1,INPUT);
  pinMode(LFSensor_2,INPUT); 
  /*servo*/
  head.attach(SERVO);
  head.write(90);
  /*init HC-SR04*/
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  digitalWrite(trig, LOW);
  /*buzzer*/
  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer, HIGH);//close buzzer
  /*IR sensor*/
  pinMode(IRPIN, INPUT); 
  digitalWrite(IRPIN, HIGH);  
  IR.enableIRIn();
  /******L298N******/
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
  
  Serial.begin(9600);
  Serial.println("welcome to use tank robot car...");
  Serial.println("send <line follow/>:test line follow sensor");
  Serial.println("send <led on/>:turn on LED ");
  Serial.println("send <led off/>:turn off LED ");
  Serial.println("send <servo/>: test servo");
  Serial.println("send <distance/>: test HC-SR04");
  Serial.println("send <buzzer/>: test buzzer");
  Serial.println("send <go/>: test robot go ahead");
  Serial.println("send <back/>: test robot go back");
  Serial.println("send <stop/>: test robot stop");
  Serial.println("--------------------------------------------------->>");
}

/*receive serial data*/
void read_serial()
{
  if (Serial.available()>0) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '/') {
      stringComplete = true;
    }
  }
}

void loop() {
  read_serial();
  if(stringComplete){
    if(inputString =="line follow/") read_sensor_values();
    else if(inputString =="led on/") led_on();
    else if(inputString =="led off/") led_off();
    else if(inputString =="servo/") test_servo();
    else if(inputString == "distance/") test_hc_sr04();
    else if(inputString == "buzzer/") test_buzzer();
    else if(inputString == "go/") go_ahead();
    else if(inputString == "back/") go_back();
    else if(inputString == "stop/") go_stop();
    inputString = "";
    stringComplete = false;
  }
  test_ir();//test IR receiver
}

/*read line folloe sensors*/
void read_sensor_values()
{
  char sensor[2];
  sensor[0]=digitalRead(LFSensor_1);
  sensor[1]=digitalRead(LFSensor_2);
  if(sensor[0]==1 && sensor[1]== 0)
    Serial.println("left sensor is on the black line,right sensor is not on the black line");
  if(sensor[0]==0 && sensor[1]== 1)
    Serial.println("left sensor is not on the black line,right sensor is on the black line");
  if(sensor[0]==1 && sensor[1]== 1)
    Serial.println("all sensons are on the black line");
  if(sensor[0]==0 && sensor[1]== 0)
    Serial.println("all sensons are not on the black line");
}
/*test led*/
void led_on()
{
  //turn on led
  digitalWrite(LED1,LOW);
  digitalWrite(LED2,LOW);
  Serial.println("turn on led");
}
void led_off()
{
  digitalWrite(LED1,HIGH);
  digitalWrite(LED2,HIGH);
  Serial.println("turn off led");
}
/*tets servo*/
void test_servo()
{
  Serial.println("servo is ok!");
   for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    head.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    head.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  head.write(90);//go to centre position
}
/*tets HC-SR04*/
void test_hc_sr04()
{
  long howfar;
  digitalWrite(trig, LOW);
  delayMicroseconds(5);
  digitalWrite(trig, HIGH);
  delayMicroseconds(15);
  digitalWrite(trig, LOW);
  howfar = pulseIn(echo, HIGH);
  howfar = howfar * 0.01657; //how far away is the object in cm
  Serial.print("distance:");
  Serial.print(howfar);
  Serial.println(" cm");
}
/*tets buzzer*/
void test_buzzer()
{
  digitalWrite(buzzer, LOW);//turn on buzzer
  delay(300);
  digitalWrite(buzzer, HIGH);//turn off buzzer
  Serial.println("buzzer is ok!");
}
/*robot go ahead*/
void go_ahead()
{
  //set motor spped
  analogWrite(ENA,255); 
  analogWrite(ENB,255);
  //motor go ahead
  digitalWrite(IN1,LOW);
  digitalWrite(IN2,HIGH);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH); 
}
/*robot go back*/
void go_back()
{ 
  //set motor spped
  analogWrite(ENA,255); 
  analogWrite(ENB,255);
  //motor go back
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW); 
}
/*robot stop*/
void go_stop()
{
  //change the speed to 0 to stop the motor
  analogWrite(ENA,0); 
  analogWrite(ENB,0);
}
/*test IR receiver*/
void test_ir()
{
  if(IR.decode(&IRresults))
  {
    Serial.println(IRresults.value, HEX);
    IR.resume();
  } 
}

Lesson 3 L298N Motor Driver

Arduino
Let's get the motors turning
//Define L298N Dual H-Bridge Motor Controller Pins
#define IN1  8    //K1K2 motor direction
#define IN2  9    //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    //needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6   //needs to be a PWM pin to be able to control motor speed ENB
/*motor control*/
void go_ahead()  //motor rotate clockwise -->robot go ahead
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
}
void go_back() //motor rotate counterclockwise -->robot go back
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
}
void go_stop() //motor brake -->robot stop
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void turn_left()  //left motor rotate counterclockwise and right motor rotate clockwise -->robot turn left
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}
void turn_right() //left motor rotate clockwise and right motor rotate counterclockwise -->robot turn right
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}
/*set motor speed */
void set_motorspeed(int lspeed,int rspeed) //change motor speed
{
  analogWrite(ENA,lspeed);//lspeed:0-255
  analogWrite(ENB,rspeed);//rspeed:0-255   
}
void setup() {
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT); 
  pinMode(ENB, OUTPUT);  
  set_motorspeed(255,255);//maximum speed
  go_ahead(),delay(5000),go_stop();//robot forward 5s
  go_back(),delay(5000),go_stop();//robot go back 5s
  turn_left(),delay(5000),go_stop();//robot turn left 5s
  turn_right(),delay(5000),go_stop();//robot turn right 5s
  go_stop();//stop
}

void loop() {
}

Lesson 4 IR Remote Testing - Motor Control

Arduino
Let's Test the IR Remote Functions
#include <IRremote.h>
#include <Servo.h>
/******************Define L298N Dual H-Bridge Motor Controller Pins******************/
#define IN1  8    //K1K2 motor direction
#define IN2  9    //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define SERVO 11  //servo(SG90) connect to D11
#define LED1 2  //lefe led connect to D2
#define LED2 3  //right led connect to D3
#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define BUZZER  7   //buzzer connect D7

#define IR_ADVANCE       0x00FF18E7       //code from IR controller "" button
#define IR_BACK          0x00FF4AB5       //code from IR controller "" button
#define IR_RIGHT         0x00FF5AA5       //code from IR controller ">" button
#define IR_LEFT          0x00FF10EF       //code from IR controller "<" button
#define IR_SERVO         0x00FF38C7       //code from IR controller "OK" button
#define IR_OPENLED       0x00FFB04F       //code from IR controller "#" button
#define IR_CLOSELED      0x00FF6897       //code from IR controller "*" button
#define IR_BEEP          0x00FF9867       //code from IR controller "0" button

enum DN
{ 
  GO_ADVANCE, //go ahead
  GO_LEFT, //left turn
  GO_RIGHT,//right turn
  GO_BACK,//go back
  MOVE_SERVO,//move servo
  OPEN_LED,//open led
  CLOSE_LED,//close led
  BEEP,//control buzzer
  DEF
}Drive_Num=DEF;

Servo head;
IRrecv IR(IRPIN);  //   IRrecv object  IR get code from IR remoter
decode_results IRresults;   
bool stopFlag = true;//set stop flag
bool JogFlag = false;
uint16_t JogTimeCnt = 0;
uint32_t JogTime=0;
/*motor control*/
void go_ahead(int t)//go ahead
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
  delay(t);
}
void go_back(int t) //go back
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
  delay(t);
}
void go_stop() //stop
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void turn_left(int t)//turn left
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  delay(t);
}
void turn_right(int t)//turn right
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  delay(t);
}
/*set motor speed */
void set_motorspeed(int lspeed,int rspeed)
{
  analogWrite(ENA,lspeed); 
  analogWrite(ENB,rspeed);   
}
/*******control led*******/
void open_led(int led_num)
{
  if (led_num == 1)  digitalWrite(LED1,LOW);
  else digitalWrite(LED2,LOW);
}
void close_led(int led_num)
{
   if (led_num == 1)  digitalWrite(LED1,HIGH);
   else digitalWrite(LED2,HIGH);
}
/*******control buzzer*******/
void control_beep()
{
  digitalWrite(BUZZER,LOW),delay(100);
  digitalWrite(BUZZER,HIGH),delay(100);
}
/***move servo***/
void move_servo()
{
  int i;
   for(i = 0;i<180;i++){
     head.write(i);
     delay(5);
  }
  for(i = 180;i>=0;i--){
     head.write(i);
     delay(5);
  }
  head.write(90);
}
/**************detect IR code***************/
void do_IR_Tick()
{
  if(IR.decode(&IRresults))
  {
    if(IRresults.value==IR_ADVANCE)
    {
      Drive_Num=GO_ADVANCE;
    }
    else if(IRresults.value==IR_RIGHT)
    {
       Drive_Num=GO_RIGHT;
    }
    else if(IRresults.value==IR_LEFT)
    {
       Drive_Num=GO_LEFT;
    }
    else if(IRresults.value==IR_BACK)
    {
        Drive_Num=GO_BACK;
    }
    else if(IRresults.value==IR_SERVO)
    {
        Drive_Num=MOVE_SERVO;
    }
    else if(IRresults.value==IR_OPENLED)
    {
      Drive_Num=OPEN_LED;
    }
    else if(IRresults.value==IR_CLOSELED)
    {
      Drive_Num=CLOSE_LED;
    }
    else if(IRresults.value==IR_BEEP)
    {
      Drive_Num=BEEP;
    }
    IRresults.value = 0;
    IR.resume();
  }
}
/**************car control**************/
void do_Drive_Tick()
{
    switch (Drive_Num) 
    {
      case GO_ADVANCE:
            go_ahead(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_ADVANCE code is detected, then go advance
      case GO_LEFT:
            turn_left(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_LEFT code is detected, then turn left
      case GO_RIGHT:
            turn_right(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_RIGHT code is detected, then turn right
      case GO_BACK:
            go_back(10);JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//if GO_BACK code is detected, then backward
      case MOVE_SERVO:
            move_servo();JogFlag = true;JogTimeCnt = 1;JogTime=millis();break;//move servo
      case OPEN_LED:
            open_led(1),open_led(2);JogTime = 0;break;//open led
      case CLOSE_LED:
            close_led(1),close_led(2);JogTime = 0;break;//close led
      case BEEP:
            control_beep();JogTime = 0;break;//control beep
      default:break;
    }
    Drive_Num=DEF;
   //keep current moving mode for  200 millis seconds
    if(millis()-JogTime>=200)
    {
      JogTime=millis();
      if(JogFlag == true) 
      {
        stopFlag = false;
        if(JogTimeCnt <= 0) 
        {
          JogFlag = false; stopFlag = true;
        }
        JogTimeCnt--;
      }
      if(stopFlag == true) 
      {
        JogTimeCnt=0;
        go_stop();
      }
    }
}
void setup() {
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  head.attach(SERVO);
  close_led(1),close_led(2);//close led
  digitalWrite(BUZZER,HIGH);//close buzzer
  pinMode(IRPIN, INPUT); 
  digitalWrite(IRPIN, HIGH);  
  IR.enableIRIn();
  set_motorspeed(160,160);
  go_stop();      
}

void loop() {
  do_IR_Tick();
  do_Drive_Tick();
}

Lesson 5 Line Following

Arduino
You guess it ... intro to autonomous functions
#include <IRremote.h>
//Define L298N Dual H-Bridge Motor Controller Pins
#define IN1  8   //K1K2 motor direction
#define IN2  9     //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define LED1 2  //lefe led connect to D2
#define LED2 3  //right led connect to D3
#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define LFSensor_1 A0 //line follow sensor1
#define LFSensor_2 A1 //line follow sensor2

#define IR_LINEFOLLOW         0x00FF38C7       //code from IR controller "OK" button
#define IR_STOP               0x00FF9867       //code from IR controller "0" button
enum DN
{ 
  START_LINEFOLLOW,//start line follow
  STOP_LINEFOLLOW,//stop line follow
  DEF
}Drive_Num=DEF;

IRrecv IR(IRPIN);  //   IRrecv object  IR get code from IR remoter
decode_results IRresults;   
#define M_SPEED1   200  //motor speed
#define M_SPEED2   255  //motor speed
char sensor[2]={0,0};

/*motor control*/
void go_ahead()//go ahead
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
  //delay(t);
}
void go_back() //go back
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
  //delay(t);
}
void go_stop() //stop
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void turn_left(int t)//turn left
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  delay(t);
}
void turn_right(int t)//turn right
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  delay(t);
}
/*set motor speed */
void set_motorspeed(int lspeed,int rspeed)
{
  analogWrite(ENA,lspeed); 
  analogWrite(ENB,rspeed);   
}
/*read line folloe sensors*/
void read_sensor_values()
{
  sensor[0]=digitalRead(LFSensor_1);
  sensor[1]=digitalRead(LFSensor_2);
}
/*******control led*******/
void open_led(int led_num)
{
  if (led_num == 1)  digitalWrite(LED1,LOW);
  else digitalWrite(LED2,LOW);
}
void close_led(char led_num)
{
   if (led_num == 1)  digitalWrite(LED1,HIGH);
   else digitalWrite(LED2,HIGH);
}
/**************detect IR code***************/
void do_IR_Tick()
{
  if(IR.decode(&IRresults))
  {
    if(IRresults.value==IR_LINEFOLLOW)
    {
      Drive_Num=START_LINEFOLLOW;
    }
    else if(IRresults.value==IR_STOP)
    {
       Drive_Num=STOP_LINEFOLLOW;
    }
    IRresults.value = 0;
    IR.resume();
  }
}

void auto_tarcking(){
  read_sensor_values();
  if((sensor[0]==LOW)&&(sensor[1]==HIGH)){ //The right sensor is on the black line.The left sensor is on the white line
    set_motorspeed(M_SPEED1,M_SPEED1);
    turn_right(250);
  }
  else if((sensor[0]==HIGH)&&(sensor[1]==LOW)){//The right sensor is on the white line.The left sensor is on the black line
    set_motorspeed(M_SPEED1,M_SPEED1);
    turn_left(250);
  }
  else if((sensor[0]==LOW)&&(sensor[1]==LOW)){//The left an right sensor are on the white line.
    set_motorspeed(M_SPEED2,M_SPEED2);
    go_ahead();
  }
  else if((sensor[0]==HIGH)&&(sensor[1]==HIGH)){//The left an right sensor are on the black line.
    go_stop();
  }
 }
 
void setup() {
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  /*line follow sensors */
  pinMode(LFSensor_1,INPUT);
  pinMode(LFSensor_2,INPUT); 
  close_led(1),close_led(2);//close led
  pinMode(IRPIN, INPUT); 
  digitalWrite(IRPIN, HIGH);  
  IR.enableIRIn();
  go_stop();  
}
void loop() {
  do_IR_Tick();
  if(Drive_Num == START_LINEFOLLOW)
    auto_tarcking();
  else if(Drive_Num == STOP_LINEFOLLOW)
    go_stop();
}

Lesson 6 Obstacle Avoidance

Arduino
Let me go... explore
#include <Servo.h>
#include <IRremote.h>
#define IN1  8   //K1K2 motor direction
#define IN2  9     //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define LED1 2  //lefe led connect to D2
#define LED2 3  //right led connect to D3
#define SERVO     11  //servo connect to D11
#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define echo    A3 // Ultrasonic Echo pin connect to A2
#define trig    A2  // Ultrasonic Trig pin connect to A3
#define buzzer     7 //buzzer connect to D7
#define RSPEED   255  //right motor speed
#define LSPEED   255  //left motor speed
#define IR_AVOIDANCE          0x00FF38C7       //code from IR controller "OK" button
#define IR_STOP               0x00FF9867       //code from IR controller "0" button
enum DN
{ 
  START_AVOIDANCE,//start avoidance
  STOP_AVOIDANCE,//stop avoidance
  DEF
}Drive_Num=DEF;
int leftscanval, centerscanval, rightscanval, ldiagonalscanval, rdiagonalscanval;
const int distancelimit = 30; //distance limit for obstacles in front           
const int sidedistancelimit = 18; //minimum distance in cm to obstacles at both sides (the car will allow a shorter distance sideways)
Servo head;
IRrecv IR(IRPIN);  //   IRrecv object  IR get code from IR remoter
decode_results IRresults;   
/*motor control*/
void go_ahead()//go ahead
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
  //delay(t);
}
void go_back() //go back
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
  //delay(t);
}
void go_stop() //stop
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void turn_left()//turn left
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  //delay(t);
}
void turn_right()//turn right
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  //delay(t);
}
/*set motor speed */
void set_motorspeed(int lspeed,int rspeed)
{
  analogWrite(ENA,lspeed); 
  analogWrite(ENB,rspeed);   
}
void buzz_on()   //open buzzer
{
  digitalWrite(buzzer, LOW);
}
void buzz_off()  //close buzzer
{
  digitalWrite(buzzer, HIGH);
}
void alarm() {
  buzz_on();
  delay(100);
  buzz_off();
}
/*******control led*******/
void open_led(int led_num)
{
  if (led_num == 1)  digitalWrite(LED1,LOW);
  else digitalWrite(LED2,LOW);
}
void close_led(char led_num)
{
   if (led_num == 1)  digitalWrite(LED1,HIGH);
   else digitalWrite(LED2,HIGH);
}
/*detection of ultrasonic distance*/
int watch() {
  long howfar;
  digitalWrite(trig, LOW);
  delayMicroseconds(5);
  digitalWrite(trig, HIGH);
  delayMicroseconds(15);
  digitalWrite(trig, LOW);
  howfar = pulseIn(echo, HIGH);
  howfar = howfar * 0.01657; //how far away is the object in cm
  Serial.println((int)howfar);
  return round(howfar);
}
/**************detect IR code***************/
void do_IR_Tick()
{
  if(IR.decode(&IRresults))
  {
    if(IRresults.value==IR_AVOIDANCE)
    {
      Drive_Num=START_AVOIDANCE;
    }
    else if(IRresults.value==IR_STOP)
    {
       Drive_Num=STOP_AVOIDANCE;
    }
    IRresults.value = 0;
    IR.resume();
  }
}

void auto_avoidance() {
  head.write(90); 
  delay(100);
  centerscanval = watch();
  if (centerscanval >= distancelimit) {
    set_motorspeed(LSPEED, RSPEED);
    go_ahead();
  }
  else {
    go_stop();
    alarm();
    head.write(120);
    delay(150);
    ldiagonalscanval = watch();

    head.write(180);
    delay(150);
    leftscanval = watch();

    head.write(90);
    delay(150);

    head.write(60);
    delay(150);
    rdiagonalscanval = watch();

    head.write(0);
    delay(150);
    rightscanval = watch();

    head.write(90);
    if (ldiagonalscanval >= sidedistancelimit && leftscanval >= sidedistancelimit) {
      set_motorspeed(LSPEED, RSPEED);
      go_back();
      delay(200);
      turn_left();
      delay(600);
    }
    else if (rdiagonalscanval >= sidedistancelimit && rightscanval >= sidedistancelimit) {
      set_motorspeed(LSPEED, RSPEED);
      go_back();
      delay(200);
      turn_right();
      delay(600);
    }
  }
}

void setup() {
  /****L298N****/
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
  /****LED****/
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  close_led(1),close_led(2);//close led
  /*init HC-SR04*/
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  digitalWrite(trig, LOW);
  /*init buzzer*/
  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer, HIGH);
  buzz_off();
  /*init servo*/
  head.attach(SERVO);
  head.write(90);
  pinMode(IRPIN, INPUT); 
  digitalWrite(IRPIN, HIGH);  
  IR.enableIRIn();
  /*baud rate*/
  Serial.begin(9600);
  go_stop();
}

void loop() {
   do_IR_Tick();
  if(Drive_Num == START_AVOIDANCE)//remote controller press "OK",robot will avoid obstacles
    auto_avoidance();
  else if(Drive_Num == STOP_AVOIDANCE)//remote controller press "0",robot will stop move
    go_stop();
}

Lesson 7 Bluetooth Control Enable

Arduino
Let's get Bluetooth enabled
#include <Servo.h>
#include "config.h"
Servo head;
void setup() {
  /******L298N******/
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(ENB, OUTPUT);
  /******LED******/
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  close_led(1),close_led(2);//close led
  /*line follow sensors */
  pinMode(LFSensor_1,INPUT);
  pinMode(LFSensor_2,INPUT); 
  /*init HC-SR04*/
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  digitalWrite(trig, LOW);
  /*init buzzer*/
  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer, HIGH);
  buzz_off();
  /*init servo*/
  head.attach(SERVO);
  head.write(90);
  
  Serial.begin(9600);
  go_stop();
}
//WiFi / Bluetooth through the serial control
void do_Uart_Tick()
{

  char Uart_Date=0;
  if(Serial.available()) 
  {
    size_t len = Serial.available();
    uint8_t sbuf[len + 1];
    sbuf[len] = 0x00;
    Serial.readBytes(sbuf, len);
    //parseUartPackage((char*)sbuf);
    memcpy(buffUART + buffUARTIndex, sbuf, len);//ensure that the serial port can read the entire frame of data
    buffUARTIndex += len;
    preUARTTick = millis();
    if(buffUARTIndex >= MAX_PACKETSIZE - 1) 
    {
      buffUARTIndex = MAX_PACKETSIZE - 2;
      preUARTTick = preUARTTick - 200;
    }
  }
  if(buffUARTIndex > 0 && (millis() - preUARTTick >= 100))//APP send flag to modify the obstacle avoidance parameters
  { //data ready
    buffUART[buffUARTIndex] = 0x00;
    if(buffUART[0]=='C') 
    {
      Serial.println(buffUART);
      Serial.println("You have modified the parameters!");//indicates that the obstacle avoidance distance parameter has been modified
      sscanf(buffUART,"CMD%d,%d,%d",&distancelimit,&sidedistancelimit,&turntime);
      // Serial.println(distancelimit);
      // Serial.println(sidedistancelimit);
      // Serial.println(turntime);
    }
    else  Uart_Date=buffUART[0];
    buffUARTIndex = 0;
  }
  /*
  if(Serial.available()>0)
  {
      char temp[32];
      memset(temp,0x00,32);
      size_t len=Serial.available();
      if(len<32) Serial.readBytes(temp,len);
      if(temp[0]=='C') {
        Serial.println(temp);
        Serial.println("You have modified the parameters!");
        sscanf(temp,"CMD%d,%d,%d",&distancelimit,&sidedistancelimit,&turntime);
      }
      else if(len<=1&&temp!=NULL) Uart_Date=temp[0];
*/
  switch (Uart_Date)    //serial control instructions
  {
    case '2':
            Drive_Status=MANUAL_DRIVE; Drive_Num=GO_ADVANCE;Serial.println("forward"); break;
    case '4':
            Drive_Status=MANUAL_DRIVE; Drive_Num=GO_LEFT; Serial.println("turn left");break;
    case '6':
            Drive_Status=MANUAL_DRIVE; Drive_Num=GO_RIGHT; Serial.println("turn right");break;
    case '8':
            Drive_Status=MANUAL_DRIVE; Drive_Num=GO_BACK; Serial.println("go back");break;
    case '5':
            Drive_Status=MANUAL_DRIVE; Drive_Num=STOP_STOP;buzz_off();Serial.println("stop");break;
    case '3':
            Drive_Status=AUTO_DRIVE_UO; Serial.println("avoid obstacles...");break;
    case '1':
          Drive_Status=AUTO_DRIVE_LF; Serial.println("line follow...");break;
    default:break;
  }
}

//robot motor control
void do_Drive_Tick()
{
  if(Drive_Status == MANUAL_DRIVE)
  {
    switch (Drive_Num) 
    {
      case GO_ADVANCE:
          set_motorspeed(255,255);
          go_ahead(300);
          JogFlag = true;
          JogTimeCnt = 1;
          JogTime=millis();
          break;
      case GO_LEFT: 
          set_motorspeed(255,255);
          turn_left(100);
          JogFlag = true;
          JogTimeCnt = 1;
          JogTime=millis();
          break;
      case GO_RIGHT:  
           set_motorspeed(255,255);
           turn_right(100);
          JogFlag = true;
          JogTimeCnt = 1;
          JogTime=millis();
          break;
      case GO_BACK: 
          set_motorspeed(255,255);
          go_back(300);
          JogFlag = true;
          JogTimeCnt = 1;
          JogTime=millis();
          break;
      case STOP_STOP: 
          go_stop();
          JogTime = 0;
          break;
      default:
          break;
    }
    Drive_Num=DEF;
    //keep the car running for 200ms
    if(millis()-JogTime>=200)
    {
      JogTime=millis();
      if(JogFlag == true) 
      {
        stopFlag = false;
        if(JogTimeCnt <= 0) 
        {
          JogFlag = false; stopFlag = true;
        }
        JogTimeCnt--;
      }
      if(stopFlag == true) 
      {
        JogTimeCnt=0;
        go_stop();
      }
    }
  }
  else if(Drive_Status==AUTO_DRIVE_LF)
  {
    auto_tarcking();
  }
  else if(Drive_Status==AUTO_DRIVE_UO)
  {
   auto_avoidance();
  }
}
void loop() {
  do_Uart_Tick();
  do_Drive_Tick();
}

config.h

Arduino
Put this in Lesson 7 folder?
#define IN1  8   //K1K2 motor direction
#define IN2  9     //K1K2 motor direction
#define IN3  10    //K3K4 motor direction
#define IN4  12   //K3K4 motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define LED1 2  //lefe led connect to D2
#define LED2 3  //right led connect to D3
//#define IRPIN  13 //IR receiver Signal pin connect to Arduino pin 13
#define LFSensor_1 A0 //line follow sensor1
#define LFSensor_2 A1 //line follow sensor2
#define SERVO     11  //servo connect to D11
#define echo    A3 // Ultrasonic Echo pin connect to A2
#define trig    A2  // Ultrasonic Trig pin connect to A3
#define buzzer     7 //buzzer connect to D7

char sensor[2]={0,0};
#define MAX_PACKETSIZE 32    //Serial receive buffer
char buffUART[MAX_PACKETSIZE];
unsigned int buffUARTIndex = 0;
unsigned long preUARTTick = 0;

int leftscanval, centerscanval, rightscanval, ldiagonalscanval, rdiagonalscanval;
const int distancelimit = 30; //distance limit for obstacles in front           
const int sidedistancelimit = 18; //minimum distance in cm to obstacles at both sides (the car will allow a shorter distance sideways)
const int turntime = 700; //Time the robot spends turning (miliseconds)
bool stopFlag = true;
bool JogFlag = false;
uint16_t JogTimeCnt = 0;
uint32_t JogTime=0;
enum DS
{
  MANUAL_DRIVE,
  AUTO_DRIVE_LF, //line follow
  AUTO_DRIVE_UO  //ultrasonic obstruction
}Drive_Status=MANUAL_DRIVE;

enum DN
{ 
  GO_ADVANCE, 
  GO_LEFT, 
  GO_RIGHT,
  GO_BACK,
  STOP_STOP,
  DEF
}Drive_Num=DEF;

basicfun.ino

Arduino
Put this in Lesson 7 folder
/*motor control*/
void go_ahead(int t)//go ahead
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
  delay(t);
}
void go_back(int t) //go back
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
  delay(t);
}
void go_stop() //stop
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void turn_left(int t)//turn left
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  delay(t);
}
void turn_right(int t)//turn right
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  delay(t);
}
/*set motor speed */
void set_motorspeed(int lspeed,int rspeed)
{
  analogWrite(ENA,lspeed); 
  analogWrite(ENB,rspeed);   
}
void buzz_on()   //open buzzer
{
  digitalWrite(buzzer, LOW);
}
void buzz_off()  //close buzzer
{
  digitalWrite(buzzer, HIGH);
}
void alarm() {
  buzz_on();
  delay(100);
  buzz_off();
}
/*******control led*******/
void open_led(int led_num)
{
  if (led_num == 1)  digitalWrite(LED1,LOW);
  else digitalWrite(LED2,LOW);
}
void close_led(char led_num)
{
   if (led_num == 1)  digitalWrite(LED1,HIGH);
   else digitalWrite(LED2,HIGH);
}

avoidance.ino

Arduino
Put this in Lesson 7 folder
/******detection of ultrasonic distance******/
int watch() {
  long howfar;
  digitalWrite(trig, LOW);
  delayMicroseconds(5);
  digitalWrite(trig, HIGH);
  delayMicroseconds(15);
  digitalWrite(trig, LOW);
  howfar = pulseIn(echo, HIGH);
  howfar = howfar * 0.01657; //how far away is the object in cm
  Serial.println((int)howfar);
  return round(howfar);
}
/******auto avoid obstacles******/
void auto_avoidance() {
  head.write(90); 
  delay(100);
  centerscanval = watch();
  if (centerscanval >= distancelimit) {
    set_motorspeed(255, 255);
    go_ahead(0);
  }
  else {
    go_stop();
    alarm();
    head.write(120);
    delay(150);
    ldiagonalscanval = watch();

    head.write(180);
    delay(150);
    leftscanval = watch();

    head.write(90);
    delay(150);

    head.write(60);
    delay(150);
    rdiagonalscanval = watch();

    head.write(0);
    delay(150);
    rightscanval = watch();

    head.write(90);
    if (ldiagonalscanval >= sidedistancelimit && leftscanval >= sidedistancelimit) {
      set_motorspeed(255, 255);
      go_back(200);
      turn_left(600);
    }
    else if (rdiagonalscanval >= sidedistancelimit && rightscanval >= sidedistancelimit) {
      set_motorspeed(255, 255);
      go_back(200);
      turn_right(600);
    }
  }
}

line_follow.ino

Arduino
Put this in Lesson 7 folder
/*read line folloe sensors*/
void read_sensor_values()
{
  sensor[0]=digitalRead(LFSensor_1);
  sensor[1]=digitalRead(LFSensor_2);
}
/*********auto line follow*********/
void auto_tarcking(){
  read_sensor_values();
  if((sensor[0]==LOW)&&(sensor[1]==HIGH)){ //The right sensor is on the black line.The left sensor is on the white line
    set_motorspeed(200,200);
    turn_right(250);
  }
  else if((sensor[0]==HIGH)&&(sensor[1]==LOW)){//The right sensor is on the white line.The left sensor is on the black line
    set_motorspeed(200,200);
    turn_left(250);
  }
  else if((sensor[0]==LOW)&&(sensor[1]==LOW)){//The left an right sensor are on the white line.
    set_motorspeed(255,255);
    go_ahead(0);
  }
  else if((sensor[0]==HIGH)&&(sensor[1]==HIGH)){//The left an right sensor are on the black line.
    go_stop();
  }
 }

tank_robot_lesson8.ino

Arduino
Optimization/motor control? admittantly///// I haven't run yet!!!
#include <PinChangeInt.h>    //
#include <MsTimer2.h>        //
#include <DATASCOPE.h>      //PC

//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
const byte encoder0pinB = 4;//B pin -> the digital pin 4
const byte rencodPinA = 3;  //rencodPinA -> the interrupt pin 1
const byte rencodPinB = 7;  //rencodPinB -> the digital pin 11

#define IN1  8    //left motor direction
#define IN2  9    //left motor direction
#define IN3  10   //right motor direction
#define IN4  12   //right motor direction
#define ENA  5    // Needs to be a PWM pin to be able to control motor speed ENA
#define ENB  6    // Needs to be a PWM pin to be able to control motor speed ENB
#define motorspeed   200
const float Kp =20;
const float Ki =1;
byte encoder0PinALast,encoder0PinALast1;
int duration,duration1;//the number of the pulses
boolean l_direction,r_direction;//the rotation direction 
int master_pulse,slave_pulse;
int pwm;
static int i;
unsigned char Send_Count;
DATASCOPE data;//   data
void DataScope(void)
{
  int i;
  data.DataScope_Get_Channel_Data(-1*master_pulse-slave_pulse, 1);//  40ms
  data.DataScope_Get_Channel_Data(0, 2);//  40ms
  data.DataScope_Get_Channel_Data(pwm, 3);// 40ms
  data.DataScope_Get_Channel_Data(slave_pulse, 4);// 40ms
  Send_Count = data.DataScope_Data_Generate(4); 
  for ( i = 0 ; i < Send_Count; i++)
  {
    Serial.write(DataScope_OutPut_Buffer[i]);  
  }
  delay(50);  //
}

void go_ahead()
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,HIGH);
}
void go_back()
{
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4,LOW); 
}
void go_stop()
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4,LOW); 
}
void setup()
{  
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(ENA, OUTPUT);  
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT); 
  pinMode(ENB, OUTPUT); 

  
  Serial.begin(128000);//Initialize the serial port
  /*encoder init*/
  l_direction = true;//default -> Forward  
  r_direction = true;
  pinMode(encoder0pinB,INPUT);  
  pinMode(rencodPinB,INPUT);  
  attachInterrupt(0, lwheelSpeed, CHANGE);
  attachInterrupt(1, rwheelSpeed, CHANGE);
  
  delay(1500);              //
  MsTimer2::set(10, control);  //Timer210ms
  MsTimer2::start();          //
  analogWrite(ENA,motorspeed),analogWrite(ENB,motorspeed); 
}
int PID_controller(int master,int slave)
{ 
  static float power,error,integralerror,lasterror;
  if(master < 0) master = -master;
  if(slave < 0) slave = -slave;
  error = master - slave;
  integralerror += error;
  power += Kp *(error-lasterror) + Ki * error;
  lasterror = error;
  return power;
}

void control()
{
   sei();//enable global interrupts
   if(++i >=4)//20ms
   {
   master_pulse = duration ,duration = 0;
   slave_pulse = duration1, duration1 = 0;
   pwm = PID_controller(master_pulse,slave_pulse);
   i = 0;
   }
   int newpower1 = motorspeed+pwm;
   constrain(newpower1,0,255);
   analogWrite(ENB,newpower1),analogWrite(ENA,motorspeed);
   cli();//disenable global interrupts
}
void loop()
{
  go_ahead();
  Serial.begin(128000), DataScope(); //128000
}
 
void lwheelSpeed()
{
  int Lstate = digitalRead(encoder0pinA);
  if((encoder0PinALast == LOW) && Lstate==HIGH)
  {
    int val = digitalRead(encoder0pinB);
    if(val == LOW && l_direction)
    {
      l_direction = false; //Reverse
    }
    else if(val == HIGH && !l_direction)
    {
      l_direction = true;  //Forward
    }
  }
  encoder0PinALast = Lstate;
 
  if(!l_direction)  duration++;
  else  duration--;
}

void rwheelSpeed()
{
  int Lstate = digitalRead(rencodPinA);
  if((encoder0PinALast1 == LOW) && Lstate==HIGH)
  {
    int val = digitalRead(rencodPinB);
    if(val == LOW && r_direction)
    {
      r_direction = false; //Reverse
    }
    else if(val == HIGH && !r_direction)
    {
      r_direction = true;  //Forward
    }
  }
  encoder0PinALast1 = Lstate;
 
  if(!r_direction)  duration1++;
  else  duration1--;
}

Credits

James Martel

James Martel

48 projects • 62 followers
Self taught Robotics platform developer with electronics background

Comments