Ultrasonic Sensor - Is this 'delay' instruction necessary?

Hello

I am using mBlock to generate an Arduino project. It consists in using Motor shield L293D and HC-SR04 Ultrasonic Sensor PCM libraries for an Arduino UNO car of 4 motors.

The problem states:

Move the Arduino car forward and when faced with an obstacle less than 30 cm away, stop for 5 seconds and go back.

The generated Arduino code is:

// generated by mBlock5 for <your product>
// codes make you happy

#include "Adafruit_Motor_Shield_library/AFMotor.h"

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

float distancia = 0;

#define echoPin 12
#define trigPin 13

long duration;
long distance;

AF_DCMotor motor_1(1, MOTOR12_1KHZ);
AF_DCMotor motor_2(2, MOTOR12_1KHZ);
AF_DCMotor motor_3(3, MOTOR12_1KHZ);
AF_DCMotor motor_4(4, MOTOR12_1KHZ);

void _delay(float seconds) {
  long endTime = millis() + seconds * 1000;
  while(millis() < endTime) _loop();
}

void setup() {
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
  distancia = 0;
  while(1) {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = duration/58.2;
      delay(50);
      distancia = distance;
      if(distancia < 50){

        motor_1.run(RELEASE);
        _delay(5);

        motor_1.run(BACKWARD);
        motor_1.setSpeed(map(constrain(100, 0, 100), 0, 100, 0, 255));
        _delay(3); // <-----------------------------------------------------

      }else{

        motor_1.run(FORWARD);
        motor_1.setSpeed(map(constrain(100, 0, 100), 0, 100, 0, 255));

      }

      _loop();
  }

}

void _loop() {
}

void loop() {
  _loop();
}

My question is: Is the _delay(3) necessary for the purpose of the exercise?

I think we want to move backward as long as we are near the object (< 30 cm); then go forward to, again, enter the proximity. So the delay of 3 seconds is not necessary.

Is that correct?

Thank you!

P.S. This is the block based solution:

inertia. spinning motor generate electricity, it must dissipate before will apply opposite voltage. remove delay and watch the change.

but:

guess which two lines are not necessary

What do you mean by 'inertia'?

I forgot to mention it at the beginning, I can't access the Arduino car these days, so I'm programming blind. I wanted to record a video tutorial explaining the programming to have the class ready, and that delay makes me hesitate whether to include it or not. That's why I'm asking for help, because at the moment I don't have a way to test it working.

Thank you for pointing it out. For sure it is not optimized (it is generated by mBlock), but we are focusing on another aspect.

As stated before, at the moment I am unable to test. If we have to dissipate the motor (for each one of four motors), do we need to add a 'Stop motor' with a delay after the backward movement? Sorry, I am not specialized in electronics.

oh yeah, so true

void _delay(float seconds) {
  long endTime = millis() + seconds * 1000;
  while(millis() < endTime) _loop();
}

void setup() {
  ...
  while(1) {
     ....

      _loop();
  }

}

void _loop() {
}

void loop() {
  _loop();
}

yes.

Bit of a worry.

What generated the Arduino code?

I hope it wasn't some sort of AI, in general AI is a bit rubbish at generating code, and is apt you just make things up. So If you can't read and understand what it has made up then you are up the creak without a paddle.

A basic property of the way forces at a distance moves. So its Physics.

See:-

2 Likes

mBlock software

I don't know why you are saying I don't understand the code.

I understand the code, but I am not sure if the _delay(3) is strictly necessary for electronic/physics purposes or we can get rid of that.

Is the solution correct without that delay considering the original problem?:

I am saying what generated the code.
You said:- mBlock software, what on earth is this?

Did you copy it from somewhere?
Or did you ask Chat GPT or some other AI program to write it?

From https://ide.mblock.cc/ you start a new project, program with blocks and then you can preview the generated Arduino code from it:

But this topic is not about optimizing code. It is intended for an introductory course of high school students, and my question is about a small part of the code.

If the delay command was inserted by the program that translated the mBlock diagram to Arduino code, ask the developers of that software whether the delay has a purpose.

In general when reversing motor direction, the code should first brake or coast, and wait for the motor to stop completely, before starting out in the reverse direction. Otherwise the motor driver can be overloaded and damaged.

The Arduino code was generated because of I block-coded the solution. I attached you the source code, but the purpose of the question has nothing to do with source code, only the block-code solution. Thank you for pointing it out.

I understand! Is this a good solution?:

Or it would be better to wait 1 second on the else clause?

Please post the resulting Arduino code. The block diagram is not very informative.

Ok. I thought for the scope of the question the block-based solution would be enough, but here it goes:

// generated by mBlock5 for <your product>
// codes make you happy

#include "Adafruit_Motor_Shield_library/AFMotor.h"

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

float distancia = 0;

#define echoPin 12
#define trigPin 13

long duration;
long distance;

AF_DCMotor motor_1(1, MOTOR12_1KHZ);
AF_DCMotor motor_2(2, MOTOR12_1KHZ);
AF_DCMotor motor_3(3, MOTOR12_1KHZ);
AF_DCMotor motor_4(4, MOTOR12_1KHZ);

void _delay(float seconds) {
  long endTime = millis() + seconds * 1000;
  while(millis() < endTime) _loop();
}

void setup() {
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
  distancia = 0;
  while(1) {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = duration/58.2;
      delay(50);
      distancia = distance;
      if(distancia < 30){

        motor_1.run(RELEASE);
        _delay(5);

        motor_1.run(BACKWARD);
        motor_1.setSpeed(map(constrain(100, 0, 100), 0, 100, 0, 255));
        _delay(3);

        motor_1.run(RELEASE);
        _delay(1);

      }else{

        motor_1.run(FORWARD);
        motor_1.setSpeed(map(constrain(100, 0, 100), 0, 100, 0, 255));

      }

      _loop();
  }

}

void _loop() {
}

void loop() {
  _loop();
}

Idea:

Define 'distance' variable and set to 0. Define the pins where the ultrasonic sensor is connected to Arduino.

Loop over obtaining the distance from the object, and:

  • If the distance is less than 30 cm, stop 5 seconds, move away from the object by moving backward for 3 seconds and stop 1 second to avoid damaging.
  • If the distance is 30 cm or above, keep moving forward.

Is the logic correct? Or can it be improved?

Evidently, whoever wrote the program to translate the block diagram to Arduino code likes to insert arbitrary delays.

However, I don't see anything in the generated Arduino code that performs a command corresponding to "wait 5 seconds", for example.

Any means of ensuring that motor rotation is zero, before the direction of rotation is changed, will avoid creating above mentioned problem for the motor driver.

does wire.h have motor code?

why is software serial library in there?

does that code compile?

tell those kids that that code is full of unnecessary parts and they should not think it's needed to code like that!

Here:

Ok, I will consider that, thank you.

What about the last question?

The kids don't code with Arduino, they use blocks. That's why it's irrelevant to consider the source code. If I had to program in Arduino, I would never use what mBlock produces because it is a mess, I would write it by hand, but that is not what is relevant to this topic.

Thanks, I didn't notice the underscore.

Thank you for explaining this, it makes it a lot more clear what is going on.

However, I must say that the Arduino code generated is absoloutly appalling. Both in structure and implementation.

I have used many sorts of block code implementation, Scratch, Lego, DF robotics, and a few other that I can't recall, but I have never used one that shows you the translation into C code, although they all must do it. I wonder if they are all so bad?

No I think not. It will only delay the detection of the new distance measurement and you don't want to do that.

On the face of it, then it looks acquitted, and the delays you have put into it are needed.

In the Arduino code (real life) you need a delay between pulsing the send in the ultrasonic sensor and waiting for the echo to return, the time it takes to return a signal back to the receiver part of the ultra sonic sensor. But you need a delay first to make sure that the ultrasonic signal has died down so you don't receive your own transmission and so record a distance of zero.

1 Like

The ultrasonic sensors have that signal conditioning already built in: