Go Down

Topic: LINE FOLLOWER THAT REMEMBERS THE PATH (Read 757 times) 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?

There are 10 kinds of people in the world,
those who understand binary, and those who don't.

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?
There are 10 kinds of people in the world,
those who understand binary, and those who don't.


lar3ry

And how much RAM does your Arduino have? I know it isn't an Uno, because it only has 2 KB.
There are 10 kinds of people in the world,
those who understand binary, and those who don't.

dennisrapp

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

Go Up