Last updated on March 9th, 2024 at 05:51 pm
A simple path-memorizing robot car repeats the action or path that is stored in its memory. Making such a robot may seem complicated at first but believe me, it’s easier than you think. By the end of this article, you will be able to make:
(a) A wireless IR remote control Car using Arduino
(b) Turn it into a path-memorizing robot without using any extra components and
(c) How to use Arduino’s inbuilt EEPROM to store that path forever in its memory.
Purchase this project kit directly from us
Step by Step Video tutorial:
How does a path memorizing robot work?
Before starting the tutorial let’s see the objective of the project and its working.
The car is operated manually by using the specified control buttons on IR remote. 2 moves it forward, 4 is for left, 6 is for right, 8 is for backward and 0 stops the car.
The first time you run the robot car after powering Arduino, it automatically stores the sequence in its memory. Now to repeat this stored sequence, I have assigned the Repeat button on IR remote. And in order to store a new sequence, you have to delete the current stored sequence first, by pressing a button.
And finally, to store the current sequence permanently to EEPROM, the function button is used. And to play it back the fast forward button is assigned.
Apart from all this, if at any point in time during operation, the robot runs into some error, you can easily reset Arduino by pressing the play button. Please note that you can change any button you like for any certain operation mentioned above in the CODE section.
Components:
To build this robot car you will need:
- One Arduino Uno
- An IR Remote and IR receiver
- Two geared DC Motors
- Motor driver module
- 9V Power supply. I am using 6 X 1.5v AA battery here
- Robot wheels
- Robot chassis
- Breadboard
- Wires
How to build the path memorizing robot?
Part 1: Assembling the chassis
First of all, you will need a Robot chassis, to which you can fit motors and tires. I am using 2 DC motors, 2 Rubber tires, and one Caster wheel. After finishing the robot assembly it’s time for the Electronics part.
Part 2: Brief introduction to the electronics
To control your robot car from the IR remote, you would need an IR receiver. This IR receiver will decode the received signal for the corresponding button pressed and send it to Arduino. Arduino acts as a controller for your Robot Car and the program written in it gives appropriate logic to control the Motors.
But we all know that Arduino cannot supply enough current to a DC Motor. And that’s why you also need a Motor driver here. You can use any motor driver you like. Like in this case, I am using L293D Motor Driver IC for this Robot car.
Purchase this project kit directly from us
Part 3: IR receiver
Let’s talk about the IR remote we all use in our daily life. Yes, a TV remote. You must have observed a white LED in front of it. This white LED is actually an IR transmitter. It transmits Infrared waves of different frequencies depending on the button pressed.
This wave is then received and decoded by the IR receiver on the TV side, to find out which button you have pressed. We are going to use the same logic to build this project.
Now in order to distinguish between the buttons, each button is given a unique frequency. That means you must know what the frequency of each button is before using an IR remote. But the real question is how. Well, an Arduino can help us in this situation. So grab an Arduino and IR receiver.
Connect the left terminal of the sensor to digital pin 10 of Arduino. Middle terminal to GND and Right terminal to 5V pin of Arduino.
Now go to Arduino IDE software and download a library for IR remote.
Next, go to files, then example–>IR remote–>IRrecieve demo sketch.
Upload this code to your board. Now open the serial monitor and press any button on the IR remote. As you can see here, the corresponding Hex code for the button is printed on the Serial Monitor. Note down the Hexadecimal Code for all the buttons. And now you can program Arduino to perform a certain function when it receives a certain hex code.
Part 4: Circuit diagram
Tinkercad file link: https://www.tinkercad.com/things/73bMPNPUEKh
Connect the motor driver IC to your Arduino board and DC motors. I am using L293D IC and the above picture is the schematic for the same. If you are using L293D, then connect it, as shown in the Circuit diagram. And now that we have finished the circuit connections, it is time to move on to the Arduino Code:
Part 5: Arduino program A— Normal IR remote control car
This is a simple IR remote control car program without any memorizing functionality. The end goal is to control the car using an IR remote. First of all download and include the IRremote library from the library manager. Next, write some macros so that you can easily change the Arduino pins directly from here:
/*
***********************IR Remote Control Car**************************
*
* Created on: May 27, 2021
* Author: Ankit Negi
*
* Youtube: www.youtube.com/theelectronicguy
* Website: www.eTechnophiles.com
*/
#include <IRremote.h>
/*
Left Motor
*/
// IN 1
#define LM_IN1 2
// IN 2
#define LM_IN2 4
/*
Right Motor
*/
// IN 3
#define RM_IN3 5
// IN 4
#define RM_IN4 7
// IR receiver
# define RECV_PIN 10
IRrecv irrecv(RECV_PIN);
decode_results results;
//HEX codes for buttons
#define FWD 0xFD8877 // go forward
#define LFT 0xFD28D7 // go left
#define RGT 0xFD6897 // go right
#define BWD 0xFD9867 // go backward
#define STOP 0xFD30CF // stop
#define RESET 0xFD00FF // Resets the Arduino Board(RED)
unsigned long int value=0;
/*
************Arduino Reset Pin**************
*/
#define RESET_PIN A0
void setup() {
// set mode of the pins as output
for (int i = 2; i <= 7; i++) {
pinMode(i, OUTPUT);
}
// start serial communication
Serial.begin(9600);
// In case the interrupt driver crashes on setup, give a clue
// to the user what's going on.
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
}
void loop() {
if (irrecv.decode(&results)) {
value = results.value;
Serial.println(value, HEX);
irrecv.resume(); // Receive the next value
delay(200);
}
delay(100);
check_Inst(value);
value=0;
}
void check_Inst(long int value) {
switch (value) {
case FWD:
go_Forward();
break;
case LFT:
go_Left();
break;
case RGT:
go_Right();
break;
case BWD:
go_Backward();
break;
case STOP:
go_Stop();
break;
case RESET:
pinMode(RESET_PIN,OUTPUT);
digitalWrite(RESET_PIN,HIGH);
break;
default:
value = 0;
}
}
void go_Forward() {
movement_Inst_Fwd();
delay(10);
}
void go_Left() {
movement_Inst_Lft();
delay(10);
}
void go_Right() {
movement_Inst_Rgt();
delay(10);
}
void go_Backward(){
movement_Inst_Bwd();
delay(10);
}
void go_Stop(){
movement_Inst_Stp();
delay(10);
}
/*
* These movement instruction are repeated several times in the code
*/
void movement_Inst_Fwd(void){
Serial.println("Going_Forward");
// forward movement instructions
digitalWrite(LM_IN1,HIGH);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,HIGH);
digitalWrite(RM_IN4,LOW);
}
void movement_Inst_Lft(void){
Serial.println("Going_Left");
// Left movement instructions
digitalWrite(LM_IN1,LOW);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,HIGH);
digitalWrite(RM_IN4,LOW);
delay(500);
digitalWrite(LM_IN1,LOW);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,LOW);
digitalWrite(RM_IN4,LOW);
delay(500);
}
void movement_Inst_Rgt(void){
Serial.println("Going_Right");
// Rgt movement instructions
digitalWrite(LM_IN1,HIGH);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,LOW);
digitalWrite(RM_IN4,LOW);
delay(500);
digitalWrite(LM_IN1,LOW);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,LOW);
digitalWrite(RM_IN4,LOW);
delay(500);
}
void movement_Inst_Bwd(void){
Serial.println("Going_Backward");
// Bwd movement instructions
digitalWrite(LM_IN1,LOW);
digitalWrite(LM_IN2,HIGH);
digitalWrite(RM_IN3,LOW);
digitalWrite(RM_IN4,HIGH);
}
void movement_Inst_Stp(void){
Serial.println("Stopping");
// Stp movement instructions
digitalWrite(LM_IN1,LOW);
digitalWrite(LM_IN2,LOW);
digitalWrite(RM_IN3,LOW);
digitalWrite(RM_IN4,LOW);
}
Part 6: Arduino Program B— Path memorizing robot (temporary)
/*
*********************Path Memorizing Robot(temp)************************
*
* Created on: May 27, 2021
* Author: Ankit Negi
*
* Youtube: www.youtube.com/theelectronicguy
* Website: www.eTechnophiles.com
*/
#include <IRremote.h>
/*
Left Motor
*/
// IN 1
#define LM_IN1 2
// IN 2
#define LM_IN2 4
/*
Right Motor
*/
// IN 3
#define RM_IN3 5
// IN 4
#define RM_IN4 7
// IR receiver
# define RECV_PIN 10
IRrecv irrecv(RECV_PIN);
decode_results results;
//HEX codes for buttons
#define FWD 0xFD8877 // go forward
#define LFT 0xFD28D7 // go left
#define RGT 0xFD6897 // go right
#define BWD 0xFD9867 // go backward
#define STOP 0xFD30CF // stop
#define RPEAT 0xFD708F // repeat the stored sequence of movement from the temporary memory(automatically stores)
#define DEL 0xFDB04F // delete the stored sequence of movement from temporary memory(EQ)
#define RESET 0xFD00FF // Resets the Arduino Board(RED)
unsigned long int value = 0; // stores the incoming hex value
byte seq = 0; //stores the current number of executed sequences
byte seq_Array[50];// array to store the movement sequence in terms of integers(1 for FWD, 2 for LEFT and so on..)
//counter for counting the number of times program pass through a movement function(fwd, lft etc.)
int fwd_Counter = -1;
int lft_Counter = -1;
int rgt_Counter = -1;
int bwd_Counter = -1;
int stp_Counter = -1;
//global "current time" variables for different movement functions(fwd, lft etc.)
unsigned long int current_Time0 = 0;// for FWD movement
unsigned long int current_Time1 = 0;// for LEFT movement
unsigned long int current_Time2 = 0;// for RIGHT movement
unsigned long int current_Time3 = 0;// for BWD movement
unsigned long int current_Time4 = 0;// for STOP
//total time spend by the pgm in executing the movement(fwd, lft etc.) for a particular movement counter
unsigned long int total_Fwd_Time[10];
unsigned long int total_Lft_Time[10];
unsigned long int total_Rgt_Time[10];
unsigned long int total_Bwd_Time[10];
unsigned long int total_Stp_Time[10];
/*
************Arduino Reset Pin**************
*/
#define RESET_PIN A0
void setup() {
// set mode of the pins as output
for (int i = 2; i <= 7; i++) {
pinMode(i, OUTPUT);
}
// start serial communication
Serial.begin(9600);
// In case the interrupt driver crashes on setup, give a clue
// to the user what's going on.
Serial.println("Enabling IRin");
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
}
void loop() {
if (irrecv.decode(&results)) {
value = results.value;
Serial.println(value, HEX);
irrecv.resume(); // Receive the next value
delay(200);
}
delay(100);
check_Inst(value);
value=0;
}
void check_Inst(long int value) {
switch (value) {
case FWD:
go_Forward();
delay(10);
break;
case LFT:
go_Left();
delay(10);
break;
case RGT:
go_Right();
delay(10);
break;
case BWD:
go_Backward();
delay(10);
break;
case STOP:
go_Stop();
delay(10);
break;
case RPEAT:
go_In_Seq();
delay(10);
break;
case DEL:
del_From_Local_Mem();
delay(10);
break;
case RESET:
pinMode(RESET_PIN,OUTPUT);
digitalWrite(RESET_PIN,HIGH);
break;
default:
value = 0;
}
}
void go_Forward() {
movement_Inst_Fwd();
current_Time0 = millis();
int i = seq_Array[(seq - 1)];
switch (i) {
case 2:
total_Lft_Time[lft_Counter + 1] = (current_Time0 - current_Time1);
lft_Counter++;
break;
case 3:
total_Rgt_Time[rgt_Counter + 1] = (current_Time0 - current_Time2);
rgt_Counter++;
break;
case 4:
total_Bwd_Time[bwd_Counter + 1] = (current_Time0 - current_Time3);
bwd_Counter++;
break;
case 5:
total_Stp_Time[stp_Counter + 1] = (current_Time0 - current_Time4);
stp_Counter++;
break;
}
seq_Array[seq] = 1;
seq++;
}
void go_Left() {
movement_Inst_Lft();
current_Time1 = millis();
int i = seq_Array[(seq - 1)];
switch (i) {
case 1:
total_Fwd_Time[fwd_Counter + 1] = (current_Time1 - current_Time0);
fwd_Counter++;
break;
case 3:
total_Rgt_Time[rgt_Counter + 1] = (current_Time1 - current_Time2);
rgt_Counter++;
break;
case 4:
total_Bwd_Time[bwd_Counter + 1] = (current_Time1 - current_Time3);
bwd_Counter++;
break;
case 5:
total_Stp_Time[stp_Counter + 1] = (current_Time1 - current_Time4);
stp_Counter++;
break;
}
seq_Array[seq] = 2;
seq++;
}
void go_Right() {
movement_Inst_Rgt();
current_Time2 = millis();
int i = seq_Array[(seq - 1)];
switch (i) {
case 1:
total_Fwd_Time[fwd_Counter + 1] = (current_Time2 - current_Time0);
fwd_Counter++;
break;
case 2:
total_Lft_Time[lft_Counter + 1] = (current_Time2 - current_Time1);
lft_Counter++;
break;
case 4:
total_Bwd_Time[bwd_Counter + 1] = (current_Time2 - current_Time3);
bwd_Counter++;
break;
case 5:
total_Stp_Time[stp_Counter + 1] = (current_Time2 - current_Time4);
stp_Counter++;
break;
}
seq_Array[seq] = 3;
seq++;
}
void go_Backward() {
movement_Inst_Bwd();
current_Time3 = millis();
int i = seq_Array[(seq - 1)];
switch (i) {
case 1:
total_Fwd_Time[fwd_Counter + 1] = (current_Time3 - current_Time0);
fwd_Counter++;
break;
case 2:
total_Lft_Time[lft_Counter + 1] = (current_Time3 - current_Time1);
lft_Counter++;
break;
case 3:
total_Rgt_Time[rgt_Counter + 1] = (current_Time3 - current_Time2);
rgt_Counter++;
break;
case 5:
total_Stp_Time[stp_Counter + 1] = (current_Time3 - current_Time4);
stp_Counter++;
break;
}
seq_Array[seq] = 4;
seq++;
}
void go_Stop() {
movement_Inst_Stp();
current_Time4 = millis();
int i = seq_Array[(seq - 1)];
switch (i) {
case 1:
total_Fwd_Time[fwd_Counter + 1] = (current_Time4 - current_Time0);
fwd_Counter++;
break;
case 2:
total_Lft_Time[lft_Counter + 1] = (current_Time4 - current_Time1);
lft_Counter++;
break;
case 3:
total_Rgt_Time[rgt_Counter + 1] = (current_Time4 - current_Time2);
rgt_Counter++;
break;
case 4:
total_Bwd_Time[bwd_Counter + 1] = (current_Time4 - current_Time3);
bwd_Counter++;
break;
}
seq_Array[seq] = 5;
seq++;
}
void go_In_Seq(void) {
value = 0;
for (int i = 0; i < (seq + 1); i++) {
int value1 = 0;
value1 = seq_Array[i];
switch (value1) {
case 1:
static int j = 0;
go_Forward_Seq(j);
j++;
break;
case 2:
static int k = 0;
go_Left_Seq(k);
k++;
break;
case 3:
static int l = 0;
go_Right_Seq(l);
l++;
break;
case 4:
static int m = 0;
go_Backward_Seq(m);
m++;
break;
case 5:
static int n = 0;
go_Stop_Seq(n);
n++;
break;
default:
j = 0; k = 0; l = 0; m = 0; n = 0;
}
}
}
void del_From_Local_Mem() {
//set the movement counters to their default values
fwd_Counter = -1;
lft_Counter = -1;
rgt_Counter = -1;
bwd_Counter = - 1;
stp_Counter = - 1;
//set the total movement time to its default value
for (int i = 0; i < 10; i++) {
total_Fwd_Time[i] = 0;
total_Lft_Time[i] = 0;
total_Rgt_Time[i] = 0;
total_Bwd_Time[i] = 0;
total_Stp_Time[i] = 0;
}
// Reset the sequence array(stored movement instructions)
for (int i = 0; i < 50; i++) {
seq_Array[i] = 0;
}
seq = 0;
value = 0;
}
/**********************************************************************************************************
These function moves the car in a direction for the time specified/stored in the total_x_time array
************************************************************************************************************/
void go_Forward_Seq(int j) {
//go in forward direction sequence
movement_Inst_Fwd();//
delay(total_Fwd_Time[j]);
}
void go_Left_Seq(int k) {
//go in Left direction sequence
movement_Inst_Lft();
delay(total_Lft_Time[k]);
}
void go_Right_Seq(int l) {
//go in right direction sequence
movement_Inst_Rgt();
delay(total_Rgt_Time[l]);
}
void go_Backward_Seq(int m) {
//go in backward direction sequence
movement_Inst_Bwd();
delay(total_Bwd_Time[m]);
}
void go_Stop_Seq(int n) {
//go in Stop sequence
movement_Inst_Stp();
delay(total_Stp_Time[n]);
}
/*********************************************************************************************
These movement instruction are repeated(required) several times in the code
**********************************************************************************************/
void movement_Inst_Fwd(void) {
Serial.println("Going_Forward");
// forward movement instructions
digitalWrite(LM_IN1, HIGH);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, HIGH);
digitalWrite(RM_IN4, LOW);
}
void movement_Inst_Lft(void) {
Serial.println("Going_Left");
// Left movement instructions
digitalWrite(LM_IN1, LOW);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, HIGH);
digitalWrite(RM_IN4, LOW);
delay(500);
digitalWrite(LM_IN1, LOW);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, LOW);
digitalWrite(RM_IN4, LOW);
delay(500);
}
void movement_Inst_Rgt(void) {
Serial.println("Going_Right");
// Rgt movement instructions
digitalWrite(LM_IN1, HIGH);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, LOW);
digitalWrite(RM_IN4, LOW);
delay(500);
digitalWrite(LM_IN1, LOW);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, LOW);
digitalWrite(RM_IN4, LOW);
delay(500);
}
void movement_Inst_Bwd(void) {
Serial.println("Going_Backward");
// Bwd movement instructions
digitalWrite(LM_IN1, LOW);
digitalWrite(LM_IN2, HIGH);
digitalWrite(RM_IN3, LOW);
digitalWrite(RM_IN4, HIGH);
}
void movement_Inst_Stp(void) {
Serial.println("Stopping");
// Stp movement instructions
digitalWrite(LM_IN1, LOW);
digitalWrite(LM_IN2, LOW);
digitalWrite(RM_IN3, LOW);
digitalWrite(RM_IN4, LOW);
}
Part 7: Arduino code C— EEPROM path memorizing robot (permanent)
/* ************************Path Memorizing Robot**************************** * * Created on: May 27, 2021 * Author: Ankit Negi * * Youtube: www.youtube.com/theelectronicguy * Website: www.eTechnophiles.com */ #include <IRremote.h>// IR remote library #include <EEPROM.h>// EEPROM pre-installed library /* ***********Left Motor*********** */ // IN 1 #define LM_IN1 2 // IN 2 #define LM_IN2 4 /* ************Right Motor************ */ // IN 3 #define RM_IN3 5 // IN 4 #define RM_IN4 7 /* ********************IR Receiver********************** */ # define RECV_PIN 10// Pin to which IR reciever is connected IRrecv irrecv(RECV_PIN);// Pass the pin number to the function decode_results results;// variable results stores the decoded hex values /* ************HEX code of all the buttons used in the project************** */ #define FWD 0xFD8877 // go forward(2) #define LFT 0xFD28D7 // go left(4) #define RGT 0xFD6897 // go right(6) #define BWD 0xFD9867 // go backward(8) #define STOP 0xFD30CF // stop(0) #define RPEAT 0xFD708F // repeat the stored sequence of movement from the temporary memory(automatically stores) (REPT) #define DEL 0xFDB04F // delete the stored sequence of movement from temporary memory(EQ) #define PERST 0xFD40BF // copy the sequence from temp. memory to the peramanent memory(EEPROM) #define PLAYEPROM 0xFD609F // repeat the sequence stored in EEPROM(FASTFWD) #define RESET 0xFD00FF // Resets the Arduino Board(RED) /* ************Global Variables and Arrays************** */ unsigned long int value = 0; // stores the incoming hex value byte seq = 0; //stores the current number of executed sequences byte seq_Array[50];// array to store the movement sequence in terms of integers(1 for FWD, 2 for LEFT and so on..) //counter for counting the number of times program pass through a movement function(fwd, lft etc.) int fwd_Counter = -1; int lft_Counter = -1; int rgt_Counter = -1; int bwd_Counter = -1; int stp_Counter = -1; //global "current time" variables for different movement functions(fwd, lft etc.) unsigned long int current_Time0 = 0;// for FWD movement unsigned long int current_Time1 = 0;// for LEFT movement unsigned long int current_Time2 = 0;// for RIGHT movement unsigned long int current_Time3 = 0;// for BWD movement unsigned long int current_Time4 = 0;// for STOP //total time spend by the pgm in executing the movement(fwd, lft etc.) for a particular movement counter unsigned long int total_Fwd_Time[10]; unsigned long int total_Lft_Time[10]; unsigned long int total_Rgt_Time[10]; unsigned long int total_Bwd_Time[10]; unsigned long int total_Stp_Time[10]; /* ************Arduino Reset Pin************** */ #define RESET_PIN A0 void setup() { // set mode of the pins as output for (int i = 2; i <= 7; i++) { pinMode(i, OUTPUT); } // start serial communication Serial.begin(9600); // In case the interrupt driver crashes on setup, give a clue // to the user what's going on. Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver Serial.println("Enabled IRin"); } void loop() { if (irrecv.decode(&results)) { value = results.value; Serial.println(value, HEX); irrecv.resume(); // Receive the next value delay(200); } delay(100); check_Inst(value); value=0; } void check_Inst(long int value) { switch (value) { case FWD: go_Forward(); delay(10); break; case LFT: go_Left(); delay(10); break; case RGT: go_Right(); delay(10); break; case BWD: go_Backward(); delay(10); break; case STOP: go_Stop(); delay(10); break; case RPEAT: go_In_Seq(); delay(10); break; case DEL: del_From_Local_Mem(); delay(10); break; case PERST: write_To_Permt_Mem(); delay(10); break; case PLAYEPROM: Read_Permt_Mem(); delay(10); break; case RESET: pinMode(RESET_PIN, OUTPUT); digitalWrite(RESET_PIN,HIGH); break; default: value = 0; } } void go_Forward() { movement_Inst_Fwd(); current_Time0 = millis(); int i = seq_Array[(seq - 1)]; switch (i) { case 2: // total time elaspsed since Left button is pressed including rest time total_Lft_Time[lft_Counter + 1] = (current_Time0 - current_Time1); lft_Counter++; break; case 3: // total time elaspsed since Right button is pressed including rest time total_Rgt_Time[rgt_Counter + 1] = (current_Time0 - current_Time2); rgt_Counter++; break; case 4: total_Bwd_Time[bwd_Counter + 1] = (current_Time0 - current_Time3); bwd_Counter++; break; case 5: total_Stp_Time[stp_Counter + 1] = (current_Time0 - current_Time4); stp_Counter++; break; } seq_Array[seq] = 1; seq++; } void go_Left() { movement_Inst_Lft(); current_Time1 = millis(); int i = seq_Array[(seq - 1)]; switch (i) { case 1: total_Fwd_Time[fwd_Counter + 1] = (current_Time1 - current_Time0); fwd_Counter++; break; case 3: total_Rgt_Time[rgt_Counter + 1] = (current_Time1 - current_Time2); rgt_Counter++; break; case 4: total_Bwd_Time[bwd_Counter + 1] = (current_Time1 - current_Time3); bwd_Counter++; break; case 5: total_Stp_Time[stp_Counter + 1] = (current_Time1 - current_Time4); stp_Counter++; break; } seq_Array[seq] = 2; seq++; } void go_Right() { movement_Inst_Rgt(); current_Time2 = millis(); int i = seq_Array[(seq - 1)]; switch (i) { case 1: total_Fwd_Time[fwd_Counter + 1] = (current_Time2 - current_Time0); fwd_Counter++; break; case 2: total_Lft_Time[lft_Counter + 1] = (current_Time2 - current_Time1); lft_Counter++; break; case 4: total_Bwd_Time[bwd_Counter + 1] = (current_Time2 - current_Time3); bwd_Counter++; break; case 5: total_Stp_Time[stp_Counter + 1] = (current_Time2 - current_Time4); stp_Counter++; break; } seq_Array[seq] = 3; seq++; } void go_Backward() { movement_Inst_Bwd(); current_Time3 = millis(); int i = seq_Array[(seq - 1)]; switch (i) { case 1: total_Fwd_Time[fwd_Counter + 1] = (current_Time3 - current_Time0); fwd_Counter++; break; case 2: total_Lft_Time[lft_Counter + 1] = (current_Time3 - current_Time1); lft_Counter++; break; case 3: total_Rgt_Time[rgt_Counter + 1] = (current_Time3 - current_Time2); rgt_Counter++; break; case 5: total_Stp_Time[stp_Counter + 1] = (current_Time3 - current_Time4); stp_Counter++; break; } seq_Array[seq] = 4; seq++; } void go_Stop() { movement_Inst_Stp(); current_Time4 = millis(); int i = seq_Array[(seq - 1)]; switch (i) { case 1: total_Fwd_Time[fwd_Counter + 1] = (current_Time4 - current_Time0); fwd_Counter++; break; case 2: total_Lft_Time[lft_Counter + 1] = (current_Time4 - current_Time1); lft_Counter++; break; case 3: total_Rgt_Time[rgt_Counter + 1] = (current_Time4 - current_Time2); rgt_Counter++; break; case 4: total_Bwd_Time[bwd_Counter + 1] = (current_Time4 - current_Time3); bwd_Counter++; break; } seq_Array[seq] = 5; seq++; } void go_In_Seq(void) { value = 0; for (int i = 0; i < (seq + 1); i++) { int value1 = 0; value1 = seq_Array[i]; switch (value1) { case 1: static int j = 0; go_Forward_Seq(j); j++; break; case 2: static int k = 0; go_Left_Seq(k); k++; break; case 3: static int l = 0; go_Right_Seq(l); l++; break; case 4: static int m = 0; go_Backward_Seq(m); m++; break; case 5: static int n = 0; go_Stop_Seq(n); n++; break; default: j = 0; k = 0; l = 0; m = 0; n = 0; } } } void del_From_Local_Mem() { //set the movement counters to their default values fwd_Counter = -1; lft_Counter = -1; rgt_Counter = -1; bwd_Counter = - 1; stp_Counter = - 1; //set the total movement time to its default value for (int i = 0; i < 10; i++) { total_Fwd_Time[i] = 0; total_Lft_Time[i] = 0; total_Rgt_Time[i] = 0; total_Bwd_Time[i] = 0; total_Stp_Time[i] = 0; } // Reset the sequence array(stored movement instructions) for (int i = 0; i < 50; i++) { seq_Array[i] = 0; } seq = 0; } /********************************************************************************************************** This function copy the data from the arrays to the EEPROM(permanent memory) ************************************************************************************************************/ void write_To_Permt_Mem(){ // total number of movement is stored in a random address i.e, 100 EEPROM.write(100,seq); //writing the movement sequence for(int i=0; i<seq; i++){ EEPROM.write(2*i,seq_Array[i]); } //storing the time bw two successive movements for(int i=1; i<seq+1; i++){ if(seq_Array[i-1]==1){ static byte a=0; EEPROM.write(2*i-1,(total_Fwd_Time[a])/1000);// Note: One location can store maximum value of 255, hence the time is divided by 1000 here. And then multiplied by 1000 while retreiving the data from EEPROM location a++; } else if(seq_Array[i-1]==2){ static byte b=0; EEPROM.write(2*i-1,(total_Lft_Time[b])/1000); b++; } else if(seq_Array[i-1]==3){ static byte c=0; EEPROM.write(2*i-1,(total_Rgt_Time[c])/1000); c++; } else if(seq_Array[i-1]==4){ static byte d=0; EEPROM.write(2*i-1,(total_Bwd_Time[d])/1000); d++; } else if(seq_Array[i-1]==5){ static byte e=0; EEPROM.write(2*i-1,(total_Stp_Time[e])/1000); e++; } } } /********************************************************************************************************** This function reads the stored sequence from the EEPROM(permanent memory) ************************************************************************************************************/ void Read_Permt_Mem(){ // Read from permanent memory byte x = EEPROM.read(100); for(int i=0; i<x+1; i++){ byte r = EEPROM.read(2*i); switch(r){ case 1: movement_Inst_Fwd(); break; case 2: movement_Inst_Lft(); break; case 3: movement_Inst_Rgt(); break; case 4: movement_Inst_Bwd(); break; case 5: movement_Inst_Stp(); break; } delay((EEPROM.read(i+1))*1000); // multiplied by thousand because the original time was divided by 1000 while storing in EEPROM. } } /********************************************************************************************************** These function moves the car in a direction for the time specified/stored in the total_x_time array ************************************************************************************************************/ void go_Forward_Seq(int j) { //go in forward direction sequence movement_Inst_Fwd(); delay(total_Fwd_Time[j]); } void go_Left_Seq(int k) { //go in Left direction sequence movement_Inst_Lft(); delay(total_Lft_Time[k]); } void go_Right_Seq(int l) { //go in right direction sequence movement_Inst_Rgt(); delay(total_Rgt_Time[l]); } void go_Backward_Seq(int m) { //go in backward direction sequence movement_Inst_Bwd(); delay(total_Bwd_Time[m]); } void go_Stop_Seq(int n) { //go in Stop sequence movement_Inst_Stp(); delay(total_Stp_Time[n]); } /********************************************************************************************* These movement instruction are repeated(required) several times in the code **********************************************************************************************/ void movement_Inst_Fwd(void) { // forward movement instructions Serial.println("Going_Forward"); digitalWrite(LM_IN1, HIGH); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, HIGH); digitalWrite(RM_IN4, LOW); } void movement_Inst_Lft(void) { // Left movement instructions Serial.println("Going_Left"); digitalWrite(LM_IN1, LOW); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, HIGH); digitalWrite(RM_IN4, LOW); delay(500);// default delay for smooth rotation. digitalWrite(LM_IN1, LOW); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, LOW); digitalWrite(RM_IN4, LOW); delay(500); // NOTE: The minimum delay for RIGHT/LEFT movement is 1S(inluding .5s ON time & .5s OFF time). Hence subtract 1s before repeating this movement } void movement_Inst_Rgt(void) { // Rgt movement instructions Serial.println("Going_Right"); digitalWrite(LM_IN1, HIGH); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, LOW); digitalWrite(RM_IN4, LOW); delay(500);// default delay for smooth rotation. digitalWrite(LM_IN1, LOW); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, LOW); digitalWrite(RM_IN4, LOW); delay(500); // NOTE: The minimum delay for RIGHT/LEFT movement is 1S(inluding .5s ON time & .5s OFF time). Hence subtract 1s before repeating this movement } void movement_Inst_Bwd(void) { // Bwd movement instructions Serial.println("Going_Backward"); digitalWrite(LM_IN1, LOW); digitalWrite(LM_IN2, HIGH); digitalWrite(RM_IN3, LOW); digitalWrite(RM_IN4, HIGH); } void movement_Inst_Stp(void) { // Stp movement instructions Serial.println("Stopping"); digitalWrite(LM_IN1, LOW); digitalWrite(LM_IN2, LOW); digitalWrite(RM_IN3, LOW); digitalWrite(RM_IN4, LOW); }
Interested in buying this project?
Assembled Robo
Fully assembled car
- Works right out of the box
- Fully assembled, debugged, and tested car
- 3 support calls
Customized Robo
Have anything in mind? We will add that feature
- Add more sensors or module
- More instructions OR
- Any other feature that you want to include
From where did you buy the ir remote and receiver