I have an HC-SR04 sensor and I need to get the distance from it. I use this code:
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration=pulseIn(echo, HIGH, 24000L);
cm=duration/2/29.1;
Pulsein takes too much time and I would like to use interrupts to prevent code from being blocked. From the beginning, I had no idea how to do it. I did not want to ask this question without trying on my own so here is my miserable attempt:
while(digitalRead(echo)==LOW){
}
if(digitalRead(echo)==HIGH){
lowTimer=millis();
}
while(digitalRead(echo)==HIGH){
}
if(digitalRead(echo)==LOW){
duration=millis()-lowTimer;
}
Obviously, this does not work. I don't know if I am on the right track, but I do know that even if this worked, it would still block my code for a long time. Can someone help me, point me in the right direction? Please don't just write it for me - I want to learn. I would like someone to point me to the right direction till I get it. Thank you!
EDIT:
I tried on of the suggestions:
unsigned long duration;
int cm;
const int echo = 24;
const int trig = 22;
bool doPing=true;
void setup()
{
pinMode(echo, INPUT);
pinMode(trig, OUTPUT);
Serial.begin(9600);
}
void loop()
{
if(doPing){
ping();
doPing=false;
}
read_pulse();
if(duration!=0){
cm=duration/29.1/2;
Serial.println("cm: "+cm);
doPing=true;
}
delay(2);
}
void ping(){
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
}
void read_pulse()
{
static unsigned long rising_time; // time of the rising edge
static int last_state; // previous pin state
int state = digitalRead(echo); // current pin state
duration = 0; // default return value
// On rising edge: record current time.
if (last_state == LOW && state == HIGH) {
rising_time = micros();
}
// On falling edge: report pulse length.
if (last_state == HIGH && state == LOW) {
unsigned long falling_time = micros();
duration = falling_time - rising_time;
}
last_state = state;
}
This does not print anything to my serial monitor. Is there something I am missing?
delay()
from your code. The whole purpose of all this is to make the thing non-blocking, and you are completely defeating this withdelay()
: Not only will you have a terrible resolution of only 2 ms, you may miss the pulse altogether. Second, your pin assignments look dubious: you tagged the question “arduino-uno”, but there are no pins 22 nor 24 on the Uno.