1

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();
    }
}
  • 1
    you need to clean up your code before you do anything else ... there is no reason for repeated commands in setup() .... you define functions for left(), right(), forward(), etc. but you do not use the functions in square() – jsotola Oct 16 at 1:26
  • Your problem is, that you use blocking code for square() and obstacleavoidance(). Nothing else can happen during a delay() call, not even checking for a button (unless you use interrupts). You should rewrite your code without any delay() 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 the BlinkWithoutDelay example, that comes with the Arduino IDE. It explains how to use millis() as a time source. – chrisl Oct 16 at 9:10
  • Also you should look into Finite State Machines (FSM). That's a rather simple programming technique, that will help you odering the your code and giving it a good structure to work with. For both mentioned coding styles there are tutorials on the web. – chrisl Oct 16 at 9:12
  • @sempaiscuba Could you possibly help me rewrite the code in the way you are explaining? I am completely new to Arduino programming. – Hannah Oct 16 at 20:28
  • Start with learning how to use 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. – chrisl Oct 24 at 12:50
1

Hannah, people that write software are inherently lazy, so because your code does the same thing over and over its quite alien to most people on here :) As a rule of thumb if you copy and paste it more than once it should be a function.

You have functions at the top of the code to move the car, but you don't seem to use them. Using them will make the code shorter, but also much more readable.

In your setup() function you are repeatedly setting the pinMode of pins. Group all your pinMode() call and then use the pins. Again this will make the code easier to read and less likely to break when you change it.

So back to your question, how to you make the bot run around in squares until you press a button? Well it will be something like this:

void square ()
{
  while (condition)
  {
    for (int side = 0; side < 4 && condition; ++side)
    {
      forward ();
      delay (1000);
      stop ();
      right ();
      delay (660);
      stop();
    }
  }
}

You need to work out a way to tie make condition be updated by your stop button, I don't want to do everything for you.

Hope that helps, if not shout out.

  • 2
    As chrisl points out in their answer, if you use delay then you won't be able to detect button presses (or anything else) while the delay is running. The OPs code really need to be refactored using millis(). – Duncan C Oct 16 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.