Adding speed code to distance

Hi, I have the following code and want to add that it reads the speed of the object as well. Can someone help please. thanks.
here is the code I use:

const int trigPin = 9;
const int echoPin = 10;

int maximumRange = 119; // Maximum range needed
int minimumRange = 12; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() {
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
}

void loop() {
 
readDistance();

if(distance>minimumRange && distance < maximumRange)
{
 Serial.println(distance);
}else
{
  Serial.println("0");
}
 delay(500);
}

int readDistance()
{
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 distance = duration/58.2;
}

Hello rickbowl
That is quite easy.
Velocity=delta-Distance/delta-Time :nerd_face:
Have a nice day and enjoy coding in C++.

2 Likes

Let me rephrase your solution:
Velocity = deltaDistance / deltaTime;
Required is the last distance and time for calculating the difference to the current distance and time.

1 Like

the readDistance() function would be better declared as void or return the distance …

1 Like

Ok, so how will the code look like in total?
Thanks for your help.

We would love for you to try and propose something. The purpose of the forum is to help you, not do it for you (esp. as it looks like a school homework)

lol, I am 62, so no homework project. Just been trying and getting stuck on the coding of the speed. I am new to this.

To calculate speed you will need to take 2 separate distance readings and know the time between them. Then (reading1 - reading2) / time gives you a speed.

So make a start by saving 2 distance readings with a known time between them. What sort of speeds are you dealing with?

Steve

You promised the compiler that your readDistance function would return an int, but it doesn't.
(And if it did, neither duration not distance would require global scope.)

Hi,
Is this the same?

Tom.... :grinning: :+1: :coffee: :australia:

Yes, but I managed to get a zero reading with an if statement if the distance is larger than 3

The code is working very well, but cannot add (able) to write the code so that it reads the speed as well of the object.

School is open for all ages :slight_smile:

Declare a global unsigned long variable called lastTime And another for lastDistance

In the loop, using millis(), you calculate the elapsed time delatT and the distance change deltaD. The instantaneous speed is deltaD / deltaT

Then update the lastTime And lastDistance With the current one

1 Like

Most helpers here probably have you beat, on that one.

Here is an example of one way to do it. By measuring distance every tenth of a second (100 milliseconds) we can easily calculate speed in centimeters per second by multiplying the change in the distance by 10.

const int TriggerPin = 9;
const int EchoPin = 10;

unsigned maximumRange = 119; // Maximum range needed
unsigned minimumRange = 12; // Minimum range needed

void setup()
{
  Serial.begin (9600);
  pinMode(TriggerPin, OUTPUT);
  pinMode(EchoPin, INPUT);
}

void loop()
{
  unsigned long currentTime = millis();
  static unsigned long lastReadingTime = 0;

  // Let's take 10 samples per second
  if (currentTime - lastReadingTime >= 100)
  {
    lastReadingTime = currentTime;

    unsigned distance = readDistance();
    static unsigned oldDistance = 0;

    if (distance > minimumRange && distance < maximumRange)
    {
      Serial.print(distance);
      Serial.print(" cm,  ");
      if (distance > oldDistance)
      {
        Serial.print((distance - oldDistance) * 10);
        Serial.println(" cm/s away");
      }
      else if (distance < oldDistance)
      {
        Serial.print((oldDistance - distance) * 10);
        Serial.println(" cm/s toward");
      }
      oldDistance = distance;
    }
  }
}

unsigned readDistance()
{
  digitalWrite(TriggerPin, LOW);
  delayMicroseconds(2);

  digitalWrite(TriggerPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(TriggerPin, LOW);

  // 10 millisecond timeout. 119 cm 
  // is about 7 milliseconds echo time
  unsigned long duration = pulseIn(EchoPin, HIGH, 10000); 

  return duration / 58.2;
}

I would recommend to move to the newPing library to avoid locking the distance ranging for 1s if the target is out of range and all other benefits

https://bitbucket.org/teckel12/arduino-new-ping/

1 Like

Good morning, this version is installed. Thanks

That's why I set a timeout of 30,000 microseconds (about 5 meters) on pulseIn(), or a smaller value if a smaller maximum range is desired.

Thanks, I change the project to 3 sensors and dropped the speed. I could not work it out.
The code with the 3 sensors and data on one line to import it on a data sheet in excel seems to work okay.
You have any recommendations?

#include <NewPing.h>

#define TRIGGER_PIN  4
#define ECHO_PIN     5
#define TRIGGER_PIN2  8
#define ECHO_PIN2     9
#define TRIGGER_PIN3  12
#define ECHO_PIN3     13
#define MAX_DISTANCE 150 // Maximum distance we want to measure (in centimeters).


NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
NewPing sonar2(TRIGGER_PIN2, ECHO_PIN2, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
NewPing sonar3(TRIGGER_PIN3, ECHO_PIN3, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(500);                    // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.

  int distance = sonar.ping_cm(); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.print(distance);
  
  
  Serial.print(',');

  int distance2 = sonar2.ping_cm();

  Serial.print(distance2);
  Serial.print(',');
  int distance3 = sonar3.ping_cm(); 
  
  
  Serial.println(distance3);
  
}

Two things:

That is 500 milliseconds,not 50.

That delay is only between the third and the first. The second sensor is likely to pick up late echoes from the first and the third is likely to pick up late echoes from the second. Put delays between each:

void loop()
{
  int distance = sonar.ping_cm(); // Send ping, get distance in cm and print result (0 = outside set distance range)
  Serial.print(distance);
  Serial.print(',');

  // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  delay(50);
  int distance2 = sonar2.ping_cm();
  Serial.print(distance2);
  Serial.print(',');

  // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  delay(50);
  int distance3 = sonar3.ping_cm();
  Serial.println(distance3);

  // Wait another 400 milliseconds (500 total) to slow down the serial output
  delay(400);
}