Go Down

Topic: getting hc sr04 to work with a interupt (Read 129 times) previous topic - next topic

lenny227

Hi I'm trying to get the hc sr04 to work with a interupt,
this code works fine up until ~ 250centimeters , I don't get any output further then that
Code: [Select]
#include <PinChangeInt.h>

const int trigPin = A1;
const int echoPin = A0;
float DistanceRaw, Distance;
int loopdone = 1, setlow, sethigh, setlow2, SonarStarted, SonarDone;
uint32_t SonarTimer, timer, SonarEchoTimer;



void SonarEcho() {
  if (digitalRead(echoPin) == HIGH && setlow2 == 1 && SonarStarted == 0 && SonarDone == 0) {
    SonarEchoTimer = micros();
    SonarStarted = 1;
  }
  if (digitalRead(echoPin) == LOW && setlow2 == 1 && SonarStarted == 1) {
    SonarDone = 1;
  }
}



void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  PCintPort::attachInterrupt(echoPin, SonarEcho, CHANGE);
}



void loop() {
  if (loopdone == 1 || micros() - SonarTimer > 150000) {
    SonarTimer = micros();
    SonarStarted = 0;
    loopdone = 0;
    setlow = 0;
    sethigh = 0;
    setlow2 = 0;
  }
  if (setlow == 0) {
    digitalWrite(trigPin, LOW);
    setlow = 1;
  }
  if (sethigh == 0 && micros() - SonarTimer > 5000) {
    digitalWrite(trigPin, HIGH);
    sethigh == 1;
  }
  if (setlow2 == 0 && micros() - SonarTimer > 10000) {
    digitalWrite(trigPin, LOW);
    setlow2 = 1;
  }
  if (SonarDone == 1) {
    SonarDone = 0;
    DistanceRaw = (micros() - SonarEchoTimer) * 0.034 / 2;
    loopdone = 1;
    setlow2 = 0;
    SonarStarted = 0;
    // if (DistanceRaw < 1000 && DistanceRaw > 2) {
    Distance = Distance * .90 + DistanceRaw * .1;
    Serial.println(DistanceRaw);
    //  }
  }
}

and this code (wich is almost the same but without the interupt) works perfect until 500 centimeters
Code: [Select]
const int trigPin = A1;
const int echoPin = A0;
long Duration, DistanceRaw, Distance, barometerheight;
int sonar, baroset;
int loopdone, setlow, sethigh;
uint32_t timersonar, timer;

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

void loop() {
  //Serial.println(micros() - timer);
  timer = micros();
  if (loopdone == 0) {
    timersonar = millis();
    loopdone = 1;
    setlow = 0;
    sethigh = 0;
  }
  if (setlow == 0) {
    digitalWrite(trigPin, LOW);
    setlow = 1;
  }
  if (sethigh == 0 && millis() - timersonar > 5) {
    digitalWrite(trigPin, HIGH);
    sethigh == 1;
  }
  if (millis() - timersonar > 10) {
    digitalWrite(trigPin, LOW);
    Duration = pulseIn(echoPin, HIGH);     
    DistanceRaw = (Duration * 0.034) / 2;
    loopdone = 1;

    if (DistanceRaw < 600 && DistanceRaw > 2) {
      //Serial.print("DistanceRaw: ");
      Serial.println(DistanceRaw);
      Distance = DistanceRaw;
      sonar = 1;
      baroset = 0;
    }
  }
}

Does someone knows what could be wrong (sorry for the unselfexplanitory code)

DaveEvans

Could have something to do with the fact that the variables used in your ISR and shared with your main routine haven't been declared volatile.

lenny227

So if I put my calculations in the ISR it could be fixed?

DaveEvans

#3
Oct 19, 2018, 11:01 pm Last Edit: Oct 19, 2018, 11:44 pm by DaveEvans
Doubtful, because you are also using micros() in your ISR.  Suggest you read up on interrupts in the "Resources->References" link at the top of the page.

And, why bother with interrupts?

If you are looking for better resolution, start here: https://www.davidpilling.com/wiki/index.php/HCSR04

lenny227

#4
Oct 20, 2018, 09:42 am Last Edit: Oct 20, 2018, 09:43 am by lenny227
"If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be executed after the current one finishes in an order that depends on the priority they have. millis() relies on interrupts to count, so it will never increment inside an ISR. Since delay() requires interrupts to work, it will not work if called inside an ISR. micros() works initially, but will start behaving erratically after 1-2 ms. delayMicroseconds() does not use any counter, so it will work as normal."
Okay so for me it works good enough until 14.7ms (250cm = time*0.017 => time =14705┬Ás = 14.7ms) I guess there is nothing I can do to fix this...
I want to use the hc sr04 for a drone's flight controller so I don't have time to use the pulseIn() function.

DaveEvans


Go Up