On my mini car, I have a ultrasonic Arduino sensor (HC-SR04). I also have a LED that needs 3.0V. What I am trying to do is make the LED blink when the car moves closer to a wall. Basically, if the distance between the wall and the ultrasonic sensor distance is decreasing, I want the LED to blink. If the distance between them is increasing or unchanging, I want it to do nothing. What is the code to write this? (Feel free to use any pin for the LED in your code, preferably one that doesn't interfere with the ultrasonic pins I used in the code below.).
This is the code I have right now that just reads distance from the sensor.
Every pass of loop you read a distance, compare to the last distance you read in an if statement. If it is less then inside that if statement you blink your led blink without delay style. Remember to save the new value to the old value before loop exits so you have an updated old value on the next loop.
Feel free to use whatever pin you want for the LED since you'll be the one writing the code. At least give it a try. If it doesn't work we can help you get it right. But it's not for us to just write it all for you if you don't at least try.
Alright, this is my attempt at the code. Do you see any problems with it? I think the distance=distancetwo is in the wrong location:
const int trigPin = 9;
const int echoPin = 10;
const int ledPin = 7;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000; // interval at which to blink (milliseconds)
long duration;
int distance;
int distancetwo;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
if (distance < distancetwo) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
distancetwo = distance;
Serial.print("Distance: ");
Serial.println(distance);
}
const int trigPin = 9;
const int echoPin = 10;
const int ledPin = 7;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000; // interval at which to blink (milliseconds)
long duration;
int distance;
int distancetwo;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
if (distance < distancetwo) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
distancetwo = distance;
Serial.print("Distance: ");
Serial.println(distance);
}
It works, except the problem is that the ultrasonic sensor is very inaccurate, so a single number that is less than before triggers the blink. I think i might switch to an accelerometer instead.
sanjiv2001:
It works, except the problem is that the ultrasonic sensor is very inaccurate, so a single number that is less than before triggers the blink. I think i might switch to an accelerometer instead.
You're taking measurements too rapidly.
You should be making no more than about twenty measurements per second.
This is an old topic, so no worries if it's not relevant anymore to the original author.
But I've been messing around with a similar use case. I found it helpful to have a function that aggregates the distances up to a maximum of about 10 per second. I can govern that with using a delay to specify how many times a second I want the loop to run. Then I can use a function to average up to all ten of those distances which were aggregated, and return the average. (And, of course, shift all of the distance values in the array one position so the 10 elements of the array always have the most recent 10 distance reads.)
This helps eliminate the erratic nature of the reads which was mentioned in this thread, and, in my experience seems to produce a more accurate assessment of the movement of objects as long as the objects aren't moving too fast.