All Arduino programs need to have setup() and loop() functions (see the Arduino website). Since I am using an electronic speed controller I have treated it as a servo.
This code can be copied and pasted in to the Arduino software and uploaded to the Arduino.
#include <Servo.h>
Servo sweeper; // create servo object to control the sweeping servo
Servo motor; // create servo object to control the motor
Servo steering; // create servo object to control the steering
float distance[161]; // store the distance from the infra red sensor
boolean driving=false; // a flag so the car knows if it is moving or not
void setup()
{
sweeper.attach(6); // attaches the servo on pin 6 to the servo object
motor.attach(3); // attaches the servo on pin 3 to the servo object
steering.attach(9); // attaches the servo on pin 5 to the servo object
Serial.begin(115200); // sets the speed of the serial connection to the computer
sweeper.write(80); // sets the sweeper servo to the centre
motor.write(180); // 0 full power, 82 power starts to 180 full brake
steering.write(80); // sets the steering servo to the centre
// 10 second countdown to start
for(int i=10;i>0;i--) {
Serial.println(i); // print to the computer when the USB cable is connected
delay(1000); // 1 second delay
}
}
// This runs continuously on the arduino
void loop() {
// find the space in front of the car
check_front();
//decide what to do
if(distance[80]>79) { // if there is more than 79cm in front then...
if(driving==false) { // if the car thinks it is stopped then ...
Serial.println("Driving forwards...");
//drive forwards
if(steering.read()!=80) { // if the steering servo is not set in the centre then move it to centre
steering.write(80); // sets the steering servo to centre
delay(1000); // wait one second for this to happen
}
motor.write(80); // move very slowly
driving=true; // set the driving flag to true
Serial.println("driving");
}
}
else {
if(driving==true) {// if the car thinks it is moving then ...
Serial.println("Stopping...");
motor.write(180); // switch the brake on
driving=false; // set the drving flag to false
Serial.println("stopped");
}
//Scan left and right
scan();
if(distance[0]>(distance[160]-1) && distance[0]>79) { // if there is more space on the right than the left
Serial.println("Turning Right...");
if(steering.read()!=112) { // if the steering servo is not set to full right then
steering.write(112); // sets the steering servo to full right
delay(1000); // wait one second for this to happen
}
motor.write(80); // move very slowly
delay(1000); // wait one second for this to happen
steering.write(80); // sets the steering servo to centre
delay(1000); // wait one second for this to happen
driving=true; // set the driving flag to true
Serial.println("driving");
}
else if(distance[160]>(distance[0]-1) && distance[160]>79) {
Serial.println("Turning Left...");
if(steering.read()!=48) { // if the steering servo is not set to full left then
steering.write(48); // sets the steering servo to full left
delay(1000); // wait one second for this to happen
}
motor.write(80); // move very slowly
delay(1000); // wait one second for this to happen
steering.write(80); // sets the steering servo to centre
delay(1000); // wait one second for this to happen
driving=true; // set the driving flag to true
Serial.println("driving");
}
else {
// if it can't go forwards, left or right then wait
Serial.println("I'm Stuck!...");
}
}
}
void scan() { // 180 degree scan in front of the car
Serial.println("Scanning...");
int cw[161]; // this array will sort the ADC reading in one direction
int acw[161]; // this array will sort the ADC reading in the other direction
int reading; // used for taking the averages
float dist; // used for calculating the distance in cm
if(sweeper.read()!=0) { // if the servo is not right then
sweeper.write(0); // set the servo to full right
delay(sweeper.read()*10); // wait until this is done
}
//read in first direction
for(int pos=0;pos<161;pos++) {
sweeper.write(pos); //set the servo position
delay(10); //wait until done
reading=0; // needs to start at 0 and then 6 readings will be added to it
for(int i=0;i<6;i++) {
reading+=analogRead(0); // read from analog input 0
delay(1); // wait one millisecond
}
cw[pos]=reading/6; // finally average the 6 reading and put in the first array
}
//reading in the second direction
for(int pos=160;pos>-1;pos--) {
sweeper.write(pos); //set the servo position
delay(10); //wait until done
reading=0; // needs to start at 0 and then 6 readings will be added to it
for(int i=0;i<6;i++) {
reading+=analogRead(0); // read from analog input 0
delay(1); // wait one millisecond
}
acw[pos]=reading/6; // finally average the 6 reading and put in the second array
}
//take the average and convert to distance
for(int i=0;i<161;i++) {
dist=12343.85*pow(((cw[i]+acw[i])*0.5),-1.15); // this formula averages the values of the 2 arrays and
// calculates the distance
if(dist<10) { // the infra red sensor is unreliable below 10 cm so set it to 0cm
dist=0;
}
if(dist>80) { // the infra red sensor is unreliable above 80 cm so set it to 80cm
dist=80;
}
distance[i]=dist; // put the value dist in to the distance array which contains the actual distances in cm
Serial.print(i);
Serial.print(" distance = ");
Serial.println(distance[i]); // this is sent to the computer serial monitor to check
}
sweeper.write(80); // set the servo back to the centre
delay(1000); // wait one second until it is done
}
void check_front() { //just check in front of the car
Serial.println("Checking Front...");
int reading; // used for taking the averages
if(sweeper.read()!=80) { // if the steering servo is not set in the centre then move it to centre
sweeper.write(80);
delay(abs(sweeper.read()-80)*10);
}
//take the readings
reading=0; // this code is the same as in the scan() function with no sweep
for(int i=0;i<6;i++) {
reading+=analogRead(0);
delay(1);
}
float dist = 12343.85*pow((reading/6),-1.15);
if(dist<10) {
dist=0;
}
if(dist>80) {
dist=80;
}
distance[80]=dist; // but the result is put in the centre position in the distance array
Serial.print("80 distance = ");
Serial.println(distance[80]);
}
This comment has been removed by a blog administrator.
ReplyDelete