Record Distance Reading From HC-SR04

Hello,

I'm looking for some help to modify a code I am using to suit my project requirements. I am working on project where I would like to record, remember, and replace a distance reading from an HC-SR04 ultra sonic sensor. I'm using an Arduino Nano.

The code I am working with is:

/*
 Code with LED:    
    Ultrasonic sensor Pins:
        VCC: +5VDC
        Trig : Trigger (INPUT) - Pin11
        Echo: Echo (OUTPUT) - Pin 12
        GND: GND
 */
 
int trigPin = 11;    //Trig - Yellow Jumper
int echoPin = 12;    //Echo - Brown Jumper
int led_r=10;        //Red LED-Red Jumper
                     //Active Buzzer share connection
                     //With Red LED
int led_b=9;        //Blue LED-Black Jumper
int led_g=8;        //Green LED-Green Jumper

long duration, cm, inches;
 
void setup() {
  //Serial Port begin
  Serial.begin (9600);
  //Define inputs and outputs
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(led_r,OUTPUT);
  pinMode(led_g,OUTPUT);
  pinMode(led_b,OUTPUT);
}
 
void loop()
{
  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  cm = (duration/2) / 29.1;
  inches = (duration/2) / 74; 

  if (cm <= 200)
  {
    digitalWrite(led_r,HIGH);
    digitalWrite(led_b,LOW);
    digitalWrite(led_g,LOW);
    
  }

  else if (cm <=25)
  {
    digitalWrite(led_b,HIGH);
    digitalWrite(led_r,LOW);
    digitalWrite(led_g,LOW);
    
  }

  else
 {
  digitalWrite(led_g,HIGH);
  digitalWrite(led_b,LOW);
  digitalWrite(led_r,LOW);
      
 
 }
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  
  delay(300);
}

I want the "if cm <=200" to be replaced with the current distance reading when I press a button connected to pin 7 and ground.

For example, I place an object in front of the HC-SR04 and the distance reading is 134 cm. I press the pin 7 button and the "if cm <=200" changes to "if cm<=134" Now every time something is 134 cm or less the led_r will light up.

I hope that makes sense. I am new to this forum and Arduino so please let me know if I am not posting properly or making any other mistakes.

One karma for using the code tags on your first post!

Do you know how to read a button? There are tons of tutorials for that.
Once you have this going in the setup wait for the button to be pressed and when it is read the distance and store that in a global variable that you use in the main loop for the comparison.

unsigned int keyDistance;

void setup()
{
  Initialize stuff
  Wait for button press
  keyDistance = mesureDistance();
}

void loop()
{
  unsigned int distance = mesureDistance();
  if (distance <= keyDistance) {
     // we are too close
  } else {
     // we are OK
  }
}

If this needs to survive powering off the Arduino you need to read about EEPROM

I did not know about the read a button. I will look into tuts on that topic. Thank you for pointing me in the right direction.

You can start with this tutorial And then Read that one for PULLUP

With the help of those links, google-fu, and a former professor, I was able to revise the code to do what I want with just one exception.

When I remove power the loop does not recall the saved value from the eeprom.

Can you tell me what I am missing?

#include <EEPROM.h>

//#define DEBUG 0
#define DEBUG 1
/*
 Code with LED:    
    Ultrasonic sensor Pins:
        VCC: +5VDC
        Trig : Trigger (INPUT) - Pin11
        Echo: Echo (OUTPUT) - Pin 12
        GND: GND
 */
 
int trigPin = 11;    //Trig - Yellow Jumper
int echoPin = 12;    //Echo - Brown Jumper
int led_r=10;        //Red LED-Red Jumper
uint8_t addr=100;    //Eeprom location
int button1 = 2;        //Distance set button

long duration, cm, car_dist;
 
void setup() {
  //Serial Port begin
  Serial.begin (9600);
  //Define inputs and outputs
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(led_r,OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), Interrupt,FALLING);    //button press to store distance
 
  car_dist = EEPROM.read(addr=100);       //recall last stored distance reading
 
}
 
void loop()
{
  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  EEPROM.read(addr=100);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  cm = (duration/2) / 29.1;

  if (cm <= car_dist)
  {
    digitalWrite(led_r,HIGH);
    if(DEBUG){
      Serial.print("The car is in the carport : ");
      Serial.println();
    }
    
  }
  else{
    digitalWrite(led_r,LOW);
    Serial.print("No Car In Port : ");
      Serial.println();
    
  }

  if(DEBUG){
    Serial.print("The current distance is : ");
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();
  }

 
  delay(400);
 
}

long SampleSonar(){
  long rtn_duration;
 
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  rtn_duration = pulseIn(echoPin, HIGH);
  return rtn_duration;
}

void Interrupt()
{
    duration = SampleSonar();
  cm = (duration/2) / 29.1;       // convert the time into a distance
  car_dist = cm;
  EEPROM.write(car_dist, cm);   //write distance to eeprom
  if(DEBUG){
    Serial.print("The current car distance is stored at : ");
    Serial.print(cm);
    Serial.print("cm");
    Serial.println();
  }
    
}

this will do something weird...  EEPROM.write(car_dist, cm);  //write distance to eeprom
The EEPROM.write() call expects the first parameter to be the address in EEPROM and the next one the value (one byte) to store there... Just looking at the name of your variable, I have big doubts that car_dist is a memory address.. :slight_smile:

The second issue is that write or read only get 1 byte out of the EEPROM. You want to store a long...

--> have a look at the put() and get() and update() methods which can deal with arbitrary data types. (only write ONCE when you press the button, your arduino EEPROM can be written only 100,000 times.. so don't save stuff there in the loop spinning at full speed or you'll kill your EEPROM quickly)

also remember that you can't trigger your HC-SR04 too often (usually 15/16Hz max to avoid mis-reads due to echo) --> needs to be implement using millis() technique to not lock your code in a delay()

You should not use interrupts to read the state of a button. Not only it's overkill but in the interrupt many things won't work, like printing... so just check the tutorials I shared above and use that to check the button status....


side note:

if you initialize addr to 100 as a global constant, there is no need to redefine it inEEPROM.read(addr=100);

if you take the trouble to define a pin for the buttonint button1 = 2;        //Distance set buttonwhy don't you use it later in   attachInterrupt(digitalPinToInterrupt(2), Interrupt,FALLING);    //button press to store distance

Wow! Thanks so much for the detailed response. I will look into the notes you made and report back.