Actuate a servo once an object is detected with an ultrasonic sensor

Hello everyone, I hope that y'all are doing great.

As you may know, i tried to do a servo actuation program with a color sensor, it worked, but the detection range was poor, and an ultrasonic sensor could do the job as well.

I now have my ultrasonic sensor, my code done, and my wiring done, it works BUT ...

I have 3 cases in my program, and one need to be time driven, and I don't know how to do it, lemme explain:

If we detect an object in a distance =< 10 cms
wait c secs
if the object is still =< 10 cms
actuate the servo to go to pos a
else
actuate the servo to go to pos b
else
actuate the servo to go to pos b

The program:


// Breadboard +5 to Arduino Vin
// Breadboard GND to Arduino GND
// Breadboard +5 to DS3225 Red
// Breadboard GND to DS3225 Black
// Breadboard +5 to HY-SRF05 Vcc
// Breadboard GND to HY-SRF05 GND
// Arduino D8 to HY-SRF05 Echo
// Arduino D9 to HY-SRF05 trigger
// Arduino D10 to DS3225 Orange

//-----------------------------------------------------------------------------------------------------

float duration = 0; // Intitialize the echo duration at 0 (ms)
float distance = 0; // Initialize the distance at 0 (cms)

//-----------------------------------------------------------------------------------------------------

#include <Servo.h> // Include the Servo library

//-----------------------------------------------------------------------------------------------------

#define trigger 9 // Define the HY-SRF05 trigger pin on the Arduino pin 9
#define echo 8 // Define the HY-SRF05 trigger pin on the Arduino pin 8

//-----------------------------------------------------------------------------------------------------

Servo Servo1; // Assign the name Servo1 to the servo

//-----------------------------------------------------------------------------------------------------

void setup() // Initialization of the code
{
  pinMode(trigger, OUTPUT); // Define the trigger pin as an Output
  pinMode(echo, INPUT); // Define the echo pin as an Input
  Serial.begin(9600); // Initialize the Serial monitor at 9600 Bauds
  Servo1.attach(10); // Attach the Servo1 to the pin 10
}

//-----------------------------------------------------------------------------------------------------

void loop() // Code run repetadly
{

  digitalWrite(trigger, LOW); // Set the trigger pin as a low state
  delayMicroseconds(2); // For 2 seconds to ensure that the trigger is always at low at each loop

  digitalWrite(trigger, HIGH); // Set the trigger pin as an high state
  delayMicroseconds(10); // For 10 mandatory seconds to initialize the mesurement by sending a wave

  digitalWrite(trigger, LOW); // Set the trigger pin as a low state to stop the wave emission

  duration = pulseIn(echo, HIGH); // Read the high state pulse on the echo pin
  distance = duration * 0.034 / 2; // Calculates the distance from the sensor using the celerity of a wave

  if ((distance > 3) && (distance < 10))) //If the distance object-sensor is between 3 and 10 cms
  {
    while ((distance > 3) && (distance < 10) && ("time condition not met"))
    {
      Servo1.write(0); // Write the position value on the variable pos
      delayMicroseconds(5); // Give Servo1 10ms to actuate itself
      Serial.print("Distance: "); // Print on the serial monitor the word Distance :
      Serial.println(distance); // Print on the serial monitor the distance sensor-object
    }
    if (("time condition met"))
    {
      Servo1.write(90); // Write the position value on the variable pos
      delayMicroseconds(5); // Give Servo1 5ms to actuate itself
      Serial.print("Distance: "); // Print on the serial monitor the word Distance :
      Serial.println(distance); // Print on the serial monitor the distance sensor-object
    }
  }
  else
  {
    if (distance > 10) //If the distance object-sensor is superior to 10 cms
    {
      Servo1.write(180); // Write the position value on the variable pos
      delayMicroseconds(5); // Give Servo1 5ms to actuate itself
      Serial.print("Distance: "); // Print on the serial monitor the word Distance :
      Serial.println(distance); // Print on the serial monitor the distance sensor-object
    }
  }
}

Thanks for y'all answers

Not sure I quite understand your requirements?

You seem to have 2 else statement that are the same? Does the first one need a condition (else if)?

Also, in the code you refer to distance > 3 and < 10, and also to the distance > 10... but no where do you consider distance < 3 ?

Can you clarify what you would like to happen more clearly.

1 Like

Hello, thanks for your answer.
Sorry, I am a total beginner.

So:

I am not interested in what is measured between 0 and 3 cm, but if this complicates the code, then I'll include it in the conditions.

In fact, I want to actuate the servo to hold something in place, by the means of a rod on a position b.

Thing is, as the the thing that I want to maintain will not be the one detected by the sensor, I have to include a delay between the moment when something is passing in front of the sensor, and if it is in front of the sensor for more than x seconds (corresponding to a displacement time) then I actuate the servo to make the rod go in pos b.

If after the x secs the object is not detected anymore, i do not actuate the sensor, and it stays in pos a

Also, if the sensor was actuated to go to pos b and that the object is not anymore in front of the sensor (nothing has to be held anymore) the servo has to go to pos a again.

So there are three cases to me, or maybe they can be merged in two, but I am clueless.

You need to code this as a state machine. You states could be NO_OBJECT, OBJECT_DETECTED, and ROD_ENGAGED.

Every time through loop(), you see what state you are in and act accordingly. If you are in the NO_OBJECT state and you detect something, take note of the current time and transition to OBJECT_DETECTED.

The next time through loop(), you will be in the OBJECT_DETECTED state so you check to see how much time has elapsed and if an object is still present. If both are true, engage your rod and change your state. If no object is detected change your state back to NO_OBJECT.

In the ROD_ENGAGED state, if no object is detected, retract the rod and change to the NO_OBJECT state.

Hi I am confused
why this, please explain:

Hello,

Thanks for the idea, state machine could be great yes.

But how to assess the elapsed time ?

Thanks !

I have to assess 3 different cases, one have to be when after a certain time, the object is still in front of the sensor and another one, when the object is not anymore in front of the sensor after a certain time (that have to be assessed but dunno how.)

Hi im sorry if this question came up before i just didnt know where on the forum to post it.
im looking for a sensor that i can use with the arduino nano to measure "z" depth of work pieces on a cnc router. i want to be able to measure at least 1 micron. the work piece is fixed and i want to measure peaks and valleys on the work piece to check depth diferences. i will appreciate any help. Thanks

That's not the place to ask this. May you create your own topic, thanks.

Use millis()/micros() for timing. When the MCU starts up a cycle count starts. The cycle count can be used to determine elapsed time.

Look at File|Examples|02.Digital|BlinkWithoutDelay to use millis() for timing instead of delay().

Thanks, I tought that it was at each arduino power on

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.