I am currently working on the elegoo uno r3 smart car kit that uses arduino. I have written some code and it works for the most part but I could use some help. I am trying to figure out what i need to do to get my square program to loop and continue to until the stop button is pressed. Can anyone help me out please? Also, I have 2 programs in it. One is for obstacle avoidance which is controlled by button 2 and the square program which is controlled by button 3. The stop button will be used to stop either program. I will put the code below.
#include <Servo.h>
//#include <ArduinoJson.h>
// Left motor truth table
//Here are some handy tables to show the various modes of operation.
// ENB IN1 IN2 Description
// LOW Not Applicable Not Applicable Motor is off
// HIGH LOW LOW Motor is stopped (brakes)
// HIGH HIGH LOW Motor is on and turning forwards
// HIGH LOW HIGH Motor is on and turning backwards
// HIGH HIGH HIGH Motor is stopped (brakes)
#include <IRremote.h>
//#include <Servo.h>
Servo myservo; // create servo object to control servo
//Servo servo; // Create a DC motor drive object
//#include <stdio.h>
//#include "HardwareSerial.h"
int Echo = A4;
int Trig = A5;
//ir remote button values/ data sheet===========================
#define f 16736925 // FORWARD
#define b 16754775 // BACK
#define l 16720605 // LEFT
#define r 16761405 // RIGHT
#define s 16712445 // STOP
#define KEY2 16750695 //obstacle avoidance mode
#define KEY3 16756815 //square mode
#define KEY_STAR 16728765
#define KEY_HASH 16732845
// define IO pin
#define ENB 5
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define ENA 6
#define RECV_PIN 12
#define ECHO_PIN A4
#define TRIG_PIN A5
#define LED_Pin 13
#define carSpeed 250
int rightDistance = 0, leftDistance = 0, middleDistance = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;
void forward(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println("Forward");
}
void stop_r() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
/* digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);*/
Serial.println("Stop!");
}
void back() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println("Back");
}
void left() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println("Left");
}
void right() {
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
Serial.println("Right");
}
void stop_() {
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
/* digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);*/
Serial.println("Stop!");
}
//Ultrasonic distance measurement Sub function
int getDistance() {
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
return (int)pulseIn(Echo, HIGH) / 58;
}
//--------------------ZIG ZAG----------------------------------------------------
//init the car
void setup() {
//pinMode(IN1, OUTPUT); //set IO pin mode OUTPUT
//pinMode(IN2, OUTPUT);
// pinMode(ENB, OUTPUT);
// digitalWrite(ENB, HIGH); //Enable left motor
myservo.attach(3); // attach servo on pin 3 to servo object
Serial.begin(9600);
pinMode(Echo, INPUT);
pinMode(Trig, OUTPUT);
pinMode(IN1, OUTPUT); //set IO pin mode OUTPUT
pinMode(IN2, OUTPUT);
pinMode(ENB, OUTPUT);
digitalWrite(ENB, HIGH); //Enable left motor
pinMode(ENB, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
digitalWrite(ENA, HIGH);//forward
digitalWrite(ENB, HIGH);
pinMode(IN3, OUTPUT); //set IO pin mode OUTPUT
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
digitalWrite(ENA, HIGH); //Enable right motor
//attachInterrupt(0,CHECK_IR,CHANGE);
irrecv.enableIRIn(); // Start the receiver
stop_r();
//pinMode(IN3, OUTPUT); //set IO pin mode OUTPUT
//pinMode(IN4, OUTPUT);
//pinMode(ENA, OUTPUT);
//digitalWrite(ENA, HIGH); //Enable right motor
}
//main loop============================================================================================================================
void loop() {
if(irrecv.decode(&results)){
Serial.println(results.value);
irrecv.resume();
}
delay(100);
//square();
if (results.value == KEY2){
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
obstacleavoidance();
//irrecv.resume();
} else if (results.value == s){
stop_r();
results.value = 12;
//irrecv.resume();
}
if(results.value == KEY3){
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
square();
//irrecv.resume();
}else if (results.value == s){
stop_r();
results.value = 12;
//irrecv.resume();
}
/* if(results.value == KEY3){
square();
} else if (results.value == s){
stop_r();
}*/
/*if (key_pressed == KEY2){
obstacleavoidance();
}
while (key_pressed == s){
stop_r();
}*/
}
void get_keys(){
}
void CHECK_IR(){
if(irrecv.decode(&results)){
Serial.println(results.value);
//key_pressed = results.value;
irrecv.resume();
}
delay(100);
}
void square (){
Serial.println("square");
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH); //go forward
delay(1000);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW); //stop
delay(1000);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
delay(660); //right wheel turning forward
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW); //stop
delay(1000);
}
void obstacleavoidance(){
myservo.write(90); //setservo position according to scaled value
delay(500);
middleDistance = getDistance();
//delay(100);
if(middleDistance <= 20) {
stop_r();
delay(500);
myservo.write(10);
delay(1000);
rightDistance = getDistance();
delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
leftDistance = getDistance();
delay(500);
myservo.write(90);
delay(1000);
if(rightDistance > leftDistance) {
right();
delay(360);
}
else if(rightDistance < leftDistance) {
left();
delay(360);
}
else if((rightDistance <= 20) || (leftDistance <= 20)) {
back();
delay(180);
}
else {
forward();
}
}
else {
forward();
}
}
square()
andobstacleavoidance()
. Nothing else can happen during adelay()
call, not even checking for a button (unless you use interrupts). You should rewrite your code without anydelay()
calls, so that the Arduino can do this, like changing outputs, when the time has come, and check the buttons inbetween. To do that look at theBlinkWithoutDelay
example, that comes with the Arduino IDE. It explains how to usemillis()
as a time source.millis()
. There are tons od tutorials for that on the web. After you understood that, you can search for FSM implementation. There should be enough material, that can be googled. I remember, that I already wrote answers about FSMs on this site.