Go Down

Topic: LINE FOLLOWER THAT REMEMBERS THE PATH (Read 1 time) previous topic - next topic

dennisrapp

Mar 11, 2014, 06:06 am Last Edit: Mar 12, 2014, 05:34 am by dennisrapp Reason: 1
Code: [Select]

#include <TimerOne.h>
#include <EEPROM.h>

int i=0;
volatile int state= 1;
volatile int prevState= 1;
volatile int addr = 0;
int add=0;
int sensorLeft = A5; // sensor left output measured as analog value
int sensorRight = A4; // sensor right output measured as analog value
//int sense = A0;

int sensorLh = 2;
int sensorLgn = 3;
volatile int motorL = 4 ;
volatile int motorL2= 12;
volatile int motorLen = 11;

int sensorRh = 5;
int sensorRgn = 6;
volatile int motorR = 7;
volatile int motorR2= 13;
volatile int motorRen = 9;

int sensorL = 0;
int sensorR = 0;
int sens = 0;
int value = 0;
int time = 0;

void setup() {
 Serial.begin(9600);
// pinMode(sense, INPUT);
 pinMode(sensorLeft, INPUT);
 pinMode(sensorLh, OUTPUT);
 pinMode(sensorLgn, OUTPUT);
 pinMode(motorL, OUTPUT);
 pinMode(motorL2, OUTPUT);
 pinMode(motorLen, OUTPUT);
 
 pinMode(sensorRight, INPUT);
 pinMode(sensorRh, OUTPUT);
 pinMode(sensorRgn, OUTPUT);
 pinMode(motorR, OUTPUT);
 pinMode(motorR2, OUTPUT);
 pinMode(motorRen, OUTPUT);
 
 digitalWrite(sensorLh,HIGH);
 digitalWrite(sensorLgn,LOW);
 digitalWrite(sensorRh,HIGH);
 digitalWrite(sensorRgn,LOW);
 
 Timer1.initialize(20000);
 Timer1.attachInterrupt( takeReading );


}
void loop() {
while(1){
  sensorL = analogRead(sensorLeft);
 sensorR=analogRead(sensorRight);
//sens = analogRead(sense);
 //Serial.println(sens);
   
 if(sensorL>500 && sensorR>500) {
   modeOne();
  state = 1;
 }
 else if(sensorL<100 && sensorR>500){
  modeTwo();
  state = 2;
 
 }
 else if(sensorL>500 && sensorR<100){
   modeThree();
  state = 3;
   }
   else if(sensorL<100 &&sensorR<100){
   
  state = 4;
  modeFour();
   }
     
   
}
 
}
void takeReading() {
 //Serial.println(prevState);
 if(state== prevState){
    i= i+1;
   if(i==255){
     //digitalWrite(13,HIGH);
     goto full;
   }
 }
 else if(state != prevState) {
   EEPROM.write(addr, i);
  // Serial.println(i);
   //Serial.println(addr);
  // Serial.println(addr);
   
   i=0;
   addr= addr + 1;
   
   EEPROM.write(addr, prevState);
   prevState = state;
   addr= addr + 1;
   if (addr > 512){
     goto full;
   }
   if(prevState== 4) {
   full:
  Timer1.detachInterrupt() ;
   
   
   
 }
 }
 
 }
 
 void modeOne(){
 digitalWrite(motorL, HIGH);
  analogWrite(motorLen, 125);
  digitalWrite(motorR, HIGH);
  digitalWrite(motorRen, HIGH);
  Serial.println(value);

 }
void modeTwo(){
  digitalWrite(motorL, LOW);
  digitalWrite(motorLen, HIGH);
  digitalWrite(motorR, HIGH);
  digitalWrite(motorRen, HIGH);
Serial.println(value);  
 }
 void modeThree(){
 digitalWrite(motorR, LOW);
  digitalWrite(motorRen, LOW);
  digitalWrite(motorL, HIGH);
  digitalWrite(motorLen, HIGH);
  Serial.println(value);
 }
 
 
 
   void modeFour(){
   
     digitalWrite(motorR, LOW);
   digitalWrite(motorR2, HIGH);  
  digitalWrite(motorRen, HIGH);
  digitalWrite(motorL, LOW);
  digitalWrite(motorL2, HIGH);
  digitalWrite(motorLen, HIGH);
  delay(10);
  //Serial.println(state);
   digitalWrite(motorR, LOW);
  digitalWrite(motorRen, LOW);
  digitalWrite(motorL, LOW);
  digitalWrite(motorLen, LOW);
   delay(5000);
   output();
}
  void output(){
    for(int j=0; j<=addr;j=j+2){
   int time =EEPROM.read(j);
   Serial.println(time);
   int value=EEPROM.read(j+1);
   Serial.println(value);
   
   if (value==1){
     modeOne();
  delay(time*20);
   }
   else if(value==2){
     modeTwo();
  delay(time*20);
   }
   else if(value==3){
     modeThree();
  delay(time*20);
   }
   else  {
     modeFour();
   }
   }
  }
   
 



I am making a line follower which remembers the path. The logic is that i am using a timer which is counting the time("i" in my code) for which robot is at a particular state. if state changes it saves the time and state in EEPROM. now this part is working.

[font=Verdana] To check my output i am using OUTPUT loop which is executed 5 seconds after the robot is stopped(state 4). 5 second is for placing the robot back to its initial position. This loop is executed as i have used serialprint to check if the loop is running but the motors are not moving. I am not able to find the error why the motors are not moving.[/font]

the 2 DCmotors are being driven by l293 motor driver

lar3ry

Quote
To check my output i am using OUTPUT loop which is executed 5 seconds after the robot is stopped(state 4). 5 second is for placing the robot back to its initial position. This loop is executed as i have used serialprint to check if the loop is running but the motors are not moving. I am not able to find the error why the motors are not moving.


What? You call output() 5 seconds after the robot is stopped. You don't start the motors in output(), but you wonder why the motors aren't running?


dennisrapp

i have started the motors if you see. the "value" that is read from EEPROM is the "state". and I have given code that if state is 1,2,3,or 4 then the motor will work accordingly by calling modeOne,modeTwo functions.

state is storing whether the motor is moving front , left , right or stopped.

if the robot is stopped i.e. the state is 4 and the interrupt is called every 20 ms therefore if state ==4  loop is executed and then after this as the robot is stopped. the output loop will be executed, in output loop "state" is read from EEPROM as "value".

dennisrapp

#3
Mar 11, 2014, 10:12 am Last Edit: Mar 12, 2014, 07:18 am by dennisrapp Reason: 1
Hi everyone,

I am trying o make a line follower that remembers he path it follows . The logic i used in program is that , the robot has 4 "state" i.e. forward (state1) , left sate2, right-state3 and stop- state 4. I have used a timer interrupt that counts the time by incrementing the time counter("ï" in the sketch) every 20ms.
If there is a change of state for example if the robot takes a right turn then the STATE changes from 1 to 3. if there is a change of state then he timer interrupt saves the state and timevalue in EEPROM. In this way the path is saved.

This part is running properly.

But then i have to make the robot retrace the path without sensors. for this i have written the code that if the robot is sopped i.e. at state 4 then after 5 sec, (this delay is to keep the robot back to is staring point) it calls a function output  that reads the saved state and time and runs the robot at the state for that time. This part has some error it is executed as i have checked it with serial.prinln but robot is not moving .

please help. my code is

#include <TimerOne.h>
#include <EEPROM.h>

int i=0;
volatile int state= 1;
volatile int prevState= 1;
volatile int addr = 0;
int add=0;
int sensorLeft = A5; // sensor left output measured as analog value
int sensorRight = A4; // sensor right output measured as analog value
//int sense = A0;

int sensorLh = 2;
int sensorLgn = 3;
volatile int motorL = 4 ;
volatile int motorL2= 12;
volatile int motorLen = 11;

int sensorRh = 5;
int sensorRgn = 6;
volatile int motorR = 7;
volatile int motorR2= 13;
volatile int motorRen = 9;

int sensorL = 0;
int sensorR = 0;
int sens = 0;
int value = 0;
int time = 0;

void setup() {
 Serial.begin(9600);
// pinMode(sense, INPUT);
 pinMode(sensorLeft, INPUT);
 pinMode(sensorLh, OUTPUT);
 pinMode(sensorLgn, OUTPUT);
 pinMode(motorL, OUTPUT);
 pinMode(motorL2, OUTPUT);
 pinMode(motorLen, OUTPUT);
 
 pinMode(sensorRight, INPUT);
 pinMode(sensorRh, OUTPUT);
 pinMode(sensorRgn, OUTPUT);
 pinMode(motorR, OUTPUT);
 pinMode(motorR2, OUTPUT);
 pinMode(motorRen, OUTPUT);
 
 digitalWrite(sensorLh,HIGH);
 digitalWrite(sensorLgn,LOW);
 digitalWrite(sensorRh,HIGH);
 digitalWrite(sensorRgn,LOW);
 
 Timer1.initialize(20000);
 Timer1.attachInterrupt( takeReading );


}
void loop() {
while(1){
  sensorL = analogRead(sensorLeft);
 sensorR=analogRead(sensorRight);
//sens = analogRead(sense);
 //Serial.println(sens);
   
 if(sensorL>500 && sensorR>500) {
   modeOne();
  state = 1;
 }
 else if(sensorL<100 && sensorR>500){
  modeTwo();
  state = 2;
 
 }
 else if(sensorL>500 && sensorR<100){
   modeThree();
  state = 3;
   }
   else if(sensorL<100 &&sensorR<100){
   
  state = 4;
  modeFour();
   }
     
   
}
 
}
void takeReading() {
 //Serial.println(prevState);
 if(state== prevState){
    i= i+1;
   if(i==255){
     //digitalWrite(13,HIGH);
     goto full;
   }
 }
 else if(state != prevState) {
   EEPROM.write(addr, i);
  // Serial.println(i);
   //Serial.println(addr);
  // Serial.println(addr);
   
   i=0;
   addr= addr + 1;
   
   EEPROM.write(addr, prevState);
   prevState = state;
   addr= addr + 1;
   if (addr > 512){
     goto full;
   }
   if(prevState== 4) {
   full:
  Timer1.detachInterrupt() ;
   
   
   
 }
 }
 
 }
 
 void modeOne(){
 digitalWrite(motorL, HIGH);
  analogWrite(motorLen, 125);
  digitalWrite(motorR, HIGH);
  digitalWrite(motorRen, HIGH);
  Serial.println(value);

 }
void modeTwo(){
  digitalWrite(motorL, LOW);
  digitalWrite(motorLen, HIGH);
  digitalWrite(motorR, HIGH);
  digitalWrite(motorRen, HIGH);
Serial.println(value);  
 }
 void modeThree(){
 digitalWrite(motorR, LOW);
  digitalWrite(motorRen, LOW);
  digitalWrite(motorL, HIGH);
  digitalWrite(motorLen, HIGH);
  Serial.println(value);
 }
 
 
 
   void modeFour(){
   
     digitalWrite(motorR, LOW);
   digitalWrite(motorR2, HIGH);  
  digitalWrite(motorRen, HIGH);
  digitalWrite(motorL, LOW);
  digitalWrite(motorL2, HIGH);
  digitalWrite(motorLen, HIGH);
  delay(10);
  //Serial.println(state);
   digitalWrite(motorR, LOW);
  digitalWrite(motorRen, LOW);
  digitalWrite(motorL, LOW);
  digitalWrite(motorLen, LOW);
   delay(5000);
   output();
}
  void output(){
    for(int j=0; j<=addr;j=j+2){
   int time =EEPROM.read(j);
   Serial.println(time);
   int value=EEPROM.read(j+1);
   Serial.println(value);
   
   if (value==1){
     modeOne();
  delay(time*20);
   }
   else if(value==2){
     modeTwo();
  delay(time*20);
   }
   else if(value==3){
     modeThree();
  delay(time*20);
   }
   else  {
     modeFour();
   }
   }
  }

DeepZ

int i = 0;

Should this not also be volatile, as it is updated in the interrupt-routine. Changes are the time in i just stays '0' (optimized away).

Hope this helps,
Thanks,
Guido

dennisrapp

thanks for the reply,

but i have checked the values saved in the eeprom an the value of "i" is being updated it is not 0. Still i will try this

dennisrapp

I am getting the desired output when i am running the OUTPUT loop as a different sketch but while running everything together , its not giving the output

lar3ry

What does it say your RAM usage is when you upload it?


lar3ry

And how much RAM does your Arduino have? I know it isn't an Uno, because it only has 2 KB.

dennisrapp

im really sorry 4kb is the size of the sketch, im using arduino duemilanove and it has 2kb RAM

Go Up