#include "IRremote.h" #include <Servo.h> //Pins for motor A const int MotorA1 = 6; const int MotorA2 = 7; //Pins for motor B const int MotorB1 = 8; const int MotorB2 = 9; //Pins for ultrasonic sensor const int trigger=10; const int echo=11; int leftscanval, centerscanval, rightscanval, ldiagonalscanval, rdiagonalscanval; char choice; //Pin for IR control int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 12 IRrecv irrecv(receiver); // create instance of 'irrecv' decode_results results; char contcommand; int modecontrol=0; int power=0; const int distancelimit = 27; //Distance limit for obstacles in front const int sidedistancelimit = 12; //Minimum distance in cm to obstacles at both sides (the robot will allow a shorter distance sideways) int distance; int numcycles = 0; char turndirection; //Gets 'l', 'r' or 'f' depending on which direction is obstacle free const int turntime = 900; //Time the robot spends turning (miliseconds) int thereis; Servo head; void setup(){ head.attach(5); head.write(80); irrecv.enableIRIn(); // Start the IR receiver pinMode(MotorA1, OUTPUT); pinMode(MotorA2, OUTPUT); pinMode(MotorB1, OUTPUT); pinMode(MotorB2, OUTPUT); pinMode(trigger,OUTPUT); pinMode(echo,INPUT); //Variable inicialization digitalWrite(MotorA1,LOW); digitalWrite(MotorA2,LOW); digitalWrite(MotorB1,LOW); digitalWrite(MotorB2,LOW); digitalWrite(trigger,LOW); } void go(){ digitalWrite (MotorA1, HIGH); digitalWrite (MotorA2, LOW); digitalWrite (MotorB1, HIGH); digitalWrite (MotorB2, LOW); } void backwards(){ digitalWrite (MotorA1 , LOW); digitalWrite (MotorA2, HIGH); digitalWrite (MotorB1, LOW); digitalWrite (MotorB2, HIGH); } int watch(){ long howfar; digitalWrite(trigger,LOW); delayMicroseconds(5); digitalWrite(trigger,HIGH); delayMicroseconds(15); digitalWrite(trigger,LOW); howfar=pulseIn(echo,HIGH); howfar=howfar*0.01657; //how far away is the object in cm return round(howfar); } void turnleft(int t){ digitalWrite (MotorA1, LOW); digitalWrite (MotorA2, HIGH); digitalWrite (MotorB1, HIGH); digitalWrite (MotorB2, LOW); delay(t); } void turnright(int t){ digitalWrite (MotorA1, HIGH); digitalWrite (MotorA2, LOW); digitalWrite (MotorB1, LOW); digitalWrite (MotorB2, HIGH); delay(t); } void stopmove(){ digitalWrite (MotorA1 ,LOW); digitalWrite (MotorA2, LOW); digitalWrite (MotorB1, LOW); digitalWrite (MotorB2, LOW); } void watchsurrounding(){ //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) centerscanval = watch(); if(centerscanval<distancelimit){stopmove();} head.write(120); delay(100); ldiagonalscanval = watch(); if(ldiagonalscanval<distancelimit){stopmove();} head.write(160); //Didn't use 180 degrees because my servo is not able to take this angle delay(300); leftscanval = watch(); if(leftscanval<sidedistancelimit){stopmove();} head.write(120); delay(100); ldiagonalscanval = watch(); if(ldiagonalscanval<distancelimit){stopmove();} head.write(80); //I used 80 degrees because its the central angle of my 160 degrees span (use 90 degrees if you are moving your servo through the whole 180 degrees) delay(100); centerscanval = watch(); if(centerscanval<distancelimit){stopmove();} head.write(40); delay(100); rdiagonalscanval = watch(); if(rdiagonalscanval<distancelimit){stopmove();} head.write(0); delay(100); rightscanval = watch(); if(rightscanval<sidedistancelimit){stopmove();} head.write(80); //Finish looking around (look forward again) delay(300); } char decide(){ watchsurrounding(); if (leftscanval>rightscanval && leftscanval>centerscanval){ choice = 'l'; } else if (rightscanval>leftscanval && rightscanval>centerscanval){ choice = 'r'; } else{ choice = 'f'; } return choice; } void translateIR() { //Used when robot is switched to operate in remote control mode switch(results.value) { case 0xFF629D: //Case 'FORWARD' go(); break; case 0xFF22DD: //Case 'LEFT' turnleft(turntime); stopmove(); break; case 0xFF02FD: //Case 'OK' stopmove(); break; case 0xFFC23D: //Case 'RIGHT' turnright(turntime); stopmove(); break; case 0xFFA857: //Case 'REVERSE' backwards(); break; case 0xFF42BD: //Case '*' modecontrol=0; stopmove(); // If an '*' is received, switch to automatic robot operating mode break; default: ; }// End Case delay(500); // Do not get immediate repeat } void loop(){ if (irrecv.decode(&results)){ //Check if the remote control is sending a signal if(results.value==0xFF6897){ //If an '1' is received, turn on robot power=1; } if(results.value==0xFF4AB5){ //If a '0' is received, turn off robot stopmove(); power=0; } if(results.value==0xFF42BD){ //If an '*' is received, switch operating mode from automatic robot to remote control (press also "*" to return to automatic robot mode) modecontrol=1; // Activate remote control operating mode stopmove(); //The robot stops and starts responding to the user's directions } irrecv.resume(); // receive the next value } while(modecontrol==1){ //The system gets into this loop during the remote control mode until modecontrol=0 (with '*') if (irrecv.decode(&results)){ //If something is being received translateIR();//Do something depending on the signal received irrecv.resume(); // receive the next value } } if(power==1){ go(); // if nothing is wrong go forward using go() function above. ++numcycles; if(numcycles>130){ //Watch if something is around every 130 loops while moving forward watchsurrounding(); if(leftscanval<sidedistancelimit || ldiagonalscanval<distancelimit){ turnright(turntime); } if(rightscanval<sidedistancelimit || rdiagonalscanval<distancelimit){ turnleft(turntime); } numcycles=0; //Restart count of cycles } 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 (distance<distancelimit){ // The robot will just stop if it is completely sure there's an obstacle ahead (must test 25 times) (needed to ignore ultrasonic sensor's false signals) ++thereis;} if (distance>distancelimit){ thereis=0;} //Count is restarted if (thereis > 25){ stopmove(); // Since something is ahead, stop moving. turndirection = decide(); //Decide which direction to turn. switch (turndirection){ case 'l': turnleft(turntime); break; case 'r': turnright(turntime); break; case 'f': ; //Do not turn if there was actually nothing ahead break; } thereis=0; } } }
for download IRremote.zip
الإبتساماتإخفاء