Project 10 Ultrasonic Avoiding Robot

vv

1. Description

We combine the hardware knowledge – LED matrix, motor drive, ultrasonic and servo, to build an ultrasonic avoiding robot! In the circuit process, we can make use of ultrasonic sensor to detect the distance between robot and front obstacles. Control the motor rotating by measured data, thus control the robot motion and show the running state by dot matrix. The ultrasonic avoiding capability is almost the same as the ultrasonic following function. We only need to change the source code. The specific logic of ultrasonic avoiding smart car is as shown below:

Flow Chart

2. Connection Diagram

3. Test Code

/*
keyestudio 4wd BT Car V2.0
lesson 10
ultrasonic avoiding robot
http://www.keyestudio.com
*/ 
//Array, used to store the data of pattern, can be calculated by yourself or obtained from the modulus tool
unsigned char front[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char left[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00};
unsigned char right[] = {0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char STOP01[] = {0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00};
unsigned char clear[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define SCL_Pin  A5  //Set clock pin to A5
#define SDA_Pin  A4  //Set data pin to A4
#define ML_Ctrl 4     //define direction control pin of B motor
#define ML_PWM 5   //define PWM control pin of B motor
#define MR_Ctrl 2    //define direction control pin of A motor
#define MR_PWM 6   //define PWM control pin of A motor
#include "SR04.h"//define the library of ultrasonic sensor
#define TRIG_PIN 12// set the signal input of ultrasonic sensor to D12 
#define ECHO_PIN 13//set the signal output of ultrasonic sensor to D13 
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);
long distance,a1,a2;//define three distance
const int servopin = 10;//set the pin of servo to D10 

void setup() 
{
    Serial.begin(9600);//open serial monitor and set baud rate to 9600 
    pinMode(ML_Ctrl, OUTPUT);//set direction control pin of B motor to OUTPUT
    pinMode(ML_PWM, OUTPUT);//set PWM control pin of B motor to OUTPUT
    pinMode(MR_Ctrl, OUTPUT);//set direction control pin of A motor to OUTPUT

    pinMode(MR_PWM, OUTPUT);//set PWM control pin of A motor to OUTPUT
    servopulse(servopin,90);// the angle of servo is 90 degree
    delay(300);
    pinMode(SCL_Pin,OUTPUT);//  set clock pin to OUTPUT
    pinMode(SDA_Pin,OUTPUT);//set data pin to OUTPUT
    matrix_display(clear);// Clear the matrix display
}

void loop()
{
    avoid();//run the main program
}

void avoid()
{
    distance=sr04.Distance(); //obtain the value detected by ultrasonic sensor 
    if((distance < 20)&&(distance > 0))//if the distance is greater than 0 and less than 20  
    {
        car_Stop();//stop
        matrix_display(STOP01);   //show stop pattern
        delay(100);
        servopulse(servopin,180);//servo rotates to 180°
        delay(500);
        a1=sr04.Distance();//measure the distance
        delay(100);
        servopulse(servopin,0);//rotate to 0 degree
        delay(500);
        a2=sr04.Distance();//measure the distance
        delay(100);
        if(a1 > a2)//if distance a1 is greater than a2
        {
            car_left();//turn left
            matrix_display(left);   //display left-turning pattern
            servopulse(servopin,90);//servo rotates to 90 degree
            delay(300); 
            matrix_display(front);   //show forward pattern
        }
        else//if the right distance is greater than the left
        {
            car_right();// turn right
            matrix_display(right);   // display right-turning pattern
            servopulse(servopin,90);// servo rotates to 90 degree
            delay(300); 
            matrix_display(front);   //show forward pattern
        }
    }
    else//otherwise
    {
        car_front();//go forward
        matrix_display(front);   // show forward pattern
    }
}

void servopulse(int servopin,int myangle)//the running angle of servo
{
    for(int i=0; i<30; i++)
    {
        int pulsewidth = (myangle*11)+500;
        digitalWrite(servopin,HIGH);
        delayMicroseconds(pulsewidth);
        digitalWrite(servopin,LOW);
        delay(20-pulsewidth/1000);
    }  
}

void car_front()//car goes forward
{
    digitalWrite(ML_Ctrl,HIGH);//set direction control pin of B motor to HIGH level
    analogWrite(ML_PWM,150);//set PWM control speed of B motor to 150
    digitalWrite(MR_Ctrl,HIGH);//set direction control pin of A motor to HIGH level
    analogWrite(MR_PWM,150);//set PWM control speed of A motor to 150
}

void car_back()//go back
{
    digitalWrite(ML_Ctrl,LOW);//set direction control pin of B motor to LOW
    analogWrite(ML_PWM,200);//set PWM control speed of B motor to 200
    digitalWrite(MR_Ctrl,LOW);//set direction control pin of A motor to LOW
    analogWrite(MR_PWM,200);//set PWM control speed of A motor to 200
}

void car_left()//car turns left
{
    digitalWrite(ML_Ctrl,LOW);//set direction control pin of B motor to LOW
    analogWrite(ML_PWM,200);//set PWM control speed of B motor to 200
    digitalWrite(MR_Ctrl,HIGH);//set direction control pin of A motor to HIGH 
    analogWrite(MR_PWM,200);//set PWM control speed of A motor to 200
}

void car_right()//car turn rights
{
    digitalWrite(ML_Ctrl,HIGH);//set direction control pin of B motor to HIGH 
    analogWrite(ML_PWM,200);//set PWM control speed of B motor to 200
    digitalWrite(MR_Ctrl,LOW);//set direction control pin of A motor to LOW
    analogWrite(MR_PWM,200);//set PWM control speed of A motor to 200
}

void car_Stop()//car stops
{
    digitalWrite(ML_Ctrl,LOW);
    analogWrite(ML_PWM,150);
    digitalWrite(MR_Ctrl,LOW);
    analogWrite(MR_PWM,150);
    delay(50);
    analogWrite(ML_PWM,0);//set PWM control speed of B motor to 0
    analogWrite(MR_PWM,0);//set PWM control speed of A motor to 0
}

//this function is used for dot matrix display
void matrix_display(unsigned char matrix_value[])
{
    IIC_start();  //the function to call the data transmission
    IIC_send(0xc0);  //Select address
    for(int i = 0;i < 16;i++) //Pattern data has 16 bytes
    {
    	IIC_send(matrix_value[i]); //data to convey patterns
    }
    IIC_end();   //end the transmission of patterns data
    IIC_start();
    IIC_send(0x8A);  //display control, set pulse width to 4/16
    IIC_end();
}

//  the condition that data transmission starts  
void IIC_start()
{
    digitalWrite(SCL_Pin,HIGH);
    delayMicroseconds(3);
    digitalWrite(SDA_Pin,HIGH);
    delayMicroseconds(3);
    digitalWrite(SDA_Pin,LOW);
    delayMicroseconds(3);
}

// transmit data
void IIC_send(unsigned char send_data)
{
    for(char i = 0;i < 8;i++)  //Every character has 8 bits
    {
    	digitalWrite(SCL_Pin,LOW);  //pull down the SCL_Pin to change the signal of SDA
    	delayMicroseconds(3);
        if(send_data & 0x01)  //1 or 0 of byte  is used to set high and low level of SDA_Pin
        {
            digitalWrite(SDA_Pin,HIGH);
        }
        else
        {
            digitalWrite(SDA_Pin,LOW);
        }
        delayMicroseconds(3);
        digitalWrite(SCL_Pin,HIGH); //Pull up SCL_Pin to stop data transmission
        delayMicroseconds(3);
        send_data = send_data >> 1;  //Detect bit by bit, so move the data right by one bit
   }
}

//the sign that data transmission ends 
void IIC_end()
{
    digitalWrite(SCL_Pin,LOW);
    delayMicroseconds(3);
    digitalWrite(SDA_Pin,LOW);
    delayMicroseconds(3);
    digitalWrite(SCL_Pin,HIGH);
    delayMicroseconds(3);
    digitalWrite(SDA_Pin,HIGH);
    delayMicroseconds(3);
}

4. Test Result

Upload the code on the keyestudio V4.0 board and wire according to connection diagram. After the DIP switch is dialed to the right end, the smart car can automatically avoid obstacles.