/* ___ ___ ___ _ _ ___ ___ ____ ___ ____ * / _ \ /___)/ _ \| | | |/ _ \ / _ \ / ___) _ \| \ *| |_| |___ | |_| | |_| | |_| | |_| ( (__| |_| | | | | * \___/(___/ \___/ \__ |\___/ \___(_)____)___/|_|_|_| * (____/ * Omni direction Mecanum Wheel Arduino Smart Car Tutorial Lesson 2 Obstacle avoidance auto driving. * Tutorial URL https://osoyoo.com/?p=43404 * CopyRight www.osoyoo.com * This project will show you how to make osoyoo robot car in auto drive mode and avoid obstacles * * */ #include #define speedPinR 9 // Front Wheel PWM pin connect Model-Y M_B ENA #define RightMotorDirPin1 22 //Front Right Motor direction pin 1 to Model-Y M_B IN1 (K1) #define RightMotorDirPin2 24 //Front Right Motor direction pin 2 to Model-Y M_B IN2 (K1) #define LeftMotorDirPin1 26 //Front Left Motor direction pin 1 to Model-Y M_B IN3 (K3) #define LeftMotorDirPin2 28 //Front Left Motor direction pin 2 to Model-Y M_B IN4 (K3) #define speedPinL 10 // Front Wheel PWM pin connect Model-Y M_B ENB #define speedPinRB 11 // Rear Wheel PWM pin connect Left Model-Y M_A ENA #define RightMotorDirPin1B 5 //Rear Right Motor direction pin 1 to Model-Y M_A IN1 ( K1) #define RightMotorDirPin2B 6 //Rear Right Motor direction pin 2 to Model-Y M_A IN2 ( K1) #define LeftMotorDirPin1B 7 //Rear Left Motor direction pin 1 to Model-Y M_A IN3 (K3) #define LeftMotorDirPin2B 8 //Rear Left Motor direction pin 2 to Model-Y M_A IN4 (K3) #define speedPinLB 12 // Rear Wheel PWM pin connect Model-Y M_A ENB #define LPT 2 // scan loop coumter #define SERVO_PIN 13 //servo connect to D5 #define Echo_PIN 31 // Ultrasonic Echo pin connect to A5 #define Trig_PIN 30 // Ultrasonic Trig pin connect to A4 #define FAST_SPEED 160 //both sides of the motor speed #define SPEED 120 //both sides of the motor speed #define TURN_SPEED 120 //both sides of the motor speed #define BACK_SPEED1 160 //back speed #define BACK_SPEED2 90 //back speed int leftscanval, centerscanval, rightscanval, ldiagonalscanval, rdiagonalscanval; const int distancelimit = 30; //distance limit for obstacles in front const int sidedistancelimit = 30; //minimum distance in cm to obstacles at both sides (the car will allow a shorter distance sideways) int distance; int numcycles = 0; const int turntime = 250; //Time the robot spends turning (miliseconds) const int backtime = 300; //Time the robot spends turning (miliseconds) int thereis; Servo head; /*motor control*/ void go_Advance() //Forward { FR_fwd(); FL_fwd(); RR_fwd(); RL_fwd(); } void go_Left() //Turn left { FR_fwd(); FL_bck(); RR_fwd(); RL_bck(); } void go_Right() //Turn right { FR_bck(); FL_fwd(); RR_bck(); RL_fwd(); } void go_Back() //Reverse { FR_bck(); FL_bck(); RR_bck(); RL_bck(); } void stop_Stop() //Stop { digitalWrite(RightMotorDirPin1, LOW); digitalWrite(RightMotorDirPin2,LOW); digitalWrite(LeftMotorDirPin1,LOW); digitalWrite(LeftMotorDirPin2,LOW); digitalWrite(RightMotorDirPin1B, LOW); digitalWrite(RightMotorDirPin2B,LOW); digitalWrite(LeftMotorDirPin1B,LOW); digitalWrite(LeftMotorDirPin2B,LOW); set_Motorspeed(0,0,0,0); } /*set motor speed */ void set_Motorspeed(int leftFront,int rightFront,int leftBack,int rightBack) { analogWrite(speedPinL,leftFront); analogWrite(speedPinR,rightFront); analogWrite(speedPinLB,leftBack); analogWrite(speedPinRB,rightBack); } void FR_fwd() //front-right wheel forward turn { digitalWrite(RightMotorDirPin1,HIGH); digitalWrite(RightMotorDirPin2,LOW); } void FR_bck() // front-right wheel backward turn { digitalWrite(RightMotorDirPin1,LOW); digitalWrite(RightMotorDirPin2,HIGH); } void FL_fwd() // front-left wheel forward turn { digitalWrite(LeftMotorDirPin1,HIGH); digitalWrite(LeftMotorDirPin2,LOW); } void FL_bck() // front-left wheel backward turn { digitalWrite(LeftMotorDirPin1,LOW); digitalWrite(LeftMotorDirPin2,HIGH); } void RR_fwd() //rear-right wheel forward turn { digitalWrite(RightMotorDirPin1B,HIGH); digitalWrite(RightMotorDirPin2B,LOW); } void RR_bck() //rear-right wheel backward turn { digitalWrite(RightMotorDirPin1B,LOW); digitalWrite(RightMotorDirPin2B,HIGH); } void RL_fwd() //rear-left wheel forward turn { digitalWrite(LeftMotorDirPin1B,HIGH); digitalWrite(LeftMotorDirPin2B,LOW); } void RL_bck() //rear-left wheel backward turn { digitalWrite(LeftMotorDirPin1B,LOW); digitalWrite(LeftMotorDirPin2B,HIGH); } /*detection of ultrasonic distance*/ int watch(){ long echo_distance; digitalWrite(Trig_PIN,LOW); delayMicroseconds(5); digitalWrite(Trig_PIN,HIGH); delayMicroseconds(15); digitalWrite(Trig_PIN,LOW); echo_distance=pulseIn(Echo_PIN,HIGH); echo_distance=echo_distance*0.01657; //how far away is the object in cm //Serial.println((int)echo_distance); return round(echo_distance); } //Meassures distances to the right, left, front, left diagonal, right diagonal and asign them in cm to the variables rightscanval, //leftscanval, centerscanval, ldiagonalscanval and rdiagonalscanval (there are 5 points for distance testing) String watchsurrounding(){ /* obstacle_status is a binary integer, its last 5 digits stands for if there is any obstacles in 5 directions, * for example B101000 last 5 digits is 01000, which stands for Left front has obstacle, B100111 means front, right front and right ha */ int obstacle_status =B100000; centerscanval = watch(); if(centerscanval=LPT){ //Watch if something is around every LPT loops while moving forward stop_Stop(); String obstacle_sign=watchsurrounding(); // 5 digits of obstacle_sign binary value means the 5 direction obstacle status Serial.print("begin str="); Serial.println(obstacle_sign); if( obstacle_sign=="10000"){ Serial.println("SLIT right"); set_Motorspeed(FAST_SPEED,SPEED,FAST_SPEED,SPEED); go_Advance(); delay(turntime); stop_Stop(); } else if( obstacle_sign=="00001" ){ Serial.println("SLIT LEFT"); set_Motorspeed(SPEED,FAST_SPEED,SPEED,FAST_SPEED); go_Advance(); delay(turntime); stop_Stop(); } else if( obstacle_sign=="11100" || obstacle_sign=="01000" || obstacle_sign=="11000" || obstacle_sign=="10100" || obstacle_sign=="01100" ||obstacle_sign=="00100" ||obstacle_sign=="01000" ){ Serial.println("hand right"); go_Right(); set_Motorspeed(TURN_SPEED,TURN_SPEED,TURN_SPEED,TURN_SPEED); delay(turntime); stop_Stop(); } else if( obstacle_sign=="00010" || obstacle_sign=="00111" || obstacle_sign=="00011" || obstacle_sign=="00101" || obstacle_sign=="00110" || obstacle_sign=="01010" ){ Serial.println("hand left"); go_Left();//Turn left set_Motorspeed(TURN_SPEED,TURN_SPEED,TURN_SPEED,TURN_SPEED); delay(turntime); stop_Stop(); } else if( obstacle_sign=="01111" || obstacle_sign=="10111" || obstacle_sign=="11111" ){ Serial.println("hand back left"); go_Back(); set_Motorspeed( BACK_SPEED1,BACK_SPEED2,BACK_SPEED1,BACK_SPEED2); delay(backtime); stop_Stop(); } else if( obstacle_sign=="11011" || obstacle_sign=="11101" || obstacle_sign=="11110" || obstacle_sign=="01110" ){ Serial.println("hand back right"); go_Back(); set_Motorspeed(BACK_SPEED2,BACK_SPEED1,BACK_SPEED2,BACK_SPEED1); delay(backtime); stop_Stop(); } else Serial.println("no handle"); numcycles=0; //Restart count of cycles } else { set_Motorspeed(SPEED,SPEED,SPEED,SPEED); go_Advance(); // if nothing is wrong go forward using go() function above. delay(backtime); stop_Stop(); } //else Serial.println(numcycles); distance = watch(); // use the watch() function to see if anything is ahead (when the robot is just moving forward and not looking around it will test the distance in front) if (distancedistancelimit){ thereis=0;} //Count is restarted if (thereis > 25){ Serial.println("final stop"); stop_Stop(); // Since something is ahead, stop moving. thereis=0; } } void setup() { /*setup L298N pin mode*/ pinMode(RightMotorDirPin1, OUTPUT); pinMode(RightMotorDirPin2, OUTPUT); pinMode(speedPinL, OUTPUT); pinMode(LeftMotorDirPin1, OUTPUT); pinMode(LeftMotorDirPin2, OUTPUT); pinMode(speedPinR, OUTPUT); pinMode(RightMotorDirPin1B, OUTPUT); pinMode(RightMotorDirPin2B, OUTPUT); pinMode(speedPinLB, OUTPUT); pinMode(LeftMotorDirPin1B, OUTPUT); pinMode(LeftMotorDirPin2B, OUTPUT); pinMode(speedPinRB, OUTPUT); stop_Stop();//stop move /*init HC-SR04*/ pinMode(Trig_PIN, OUTPUT); pinMode(Echo_PIN,INPUT); /*init buzzer*/ digitalWrite(Trig_PIN,LOW); /*init servo*/ head.attach(SERVO_PIN); head.write(0); delay(1000); head.write(170); delay(1000); head.write(90); delay(8000); Serial.begin(9600); stop_Stop();//Stop } void loop() { auto_avoidance(); // Serial.println( watchsurrounding()); }