0

I have an ultrasonic distance sensor. When this sensor is measuring a distance below 25 cm, a second sensor has to be measuring a distance below 5 cm. If not, there should be a one minute timespan, after which a speaker should make noise until the second sensor is measuring a distance below 5 cm.

I am having trouble with this. The first sensor has a lot of code it should be running as well, so using a while-loop to wait out one minute for the other sensor and creating noise after that isn't a possibility.

How do I go about this dilemma? I read into interrupts in Arduino but unfortunately I don't know how I'd make this work.

1
  • look at the "blink without delay" example; you need to do the same thing while "waiting" on the sensors.
    – dandavis
    Commented Apr 9, 2017 at 21:23

2 Answers 2

5

I strongly advice you to use interrupts and make sure the sensors are in a cylindrical cone in order to prevent interference to each others as much as possible.

Here is code snippet which can give you an idea how the interrupts are set and used. I believe that you can adapt it to yours. It is from Arduino forum (link), credits to "cattledog".

volatile unsigned long LastPulseTimeA;
volatile unsigned long LastPulseTimeB;
int durationA;
int durationB;
//unsigned long startTime;
#define trigPinA 7
#define echoPinA 2
#define trigPinB 8
#define echoPinB 3
void setup() {
  Serial.begin (9600);
  pinMode(trigPinA, OUTPUT);
  pinMode(echoPinA, INPUT);
   pinMode(trigPinB, OUTPUT);
  pinMode(echoPinB, INPUT);  
attachInterrupt(digitalPinToInterrupt(echoPinA), EchoPinA_ISR, CHANGE);  // Pin 2 interrupt on any change
attachInterrupt(digitalPinToInterrupt(echoPinB),EchoPinB_ISR, CHANGE);  // Pin3 interrupt on any change
}
void loop(){
  digitalWrite(trigPinA, LOW);
  digitalWrite(trigPinB, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPinA, HIGH);
  digitalWrite(trigPinB, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPinA, LOW);
  digitalWrite(trigPinB, LOW);
  Serial.print("Sensor A  ");
  Serial.print(LastPulseTimeA);
  Serial.print('\t');
  Serial.print((LastPulseTimeA/2) / 29.1,1);
  Serial.println("cm");
  Serial.print("Sensor B  ");
  Serial.print(LastPulseTimeB);
  Serial.print('\t');
  Serial.print((LastPulseTimeB/2) / 29.1,1);
  Serial.println("cm");

  delay(1000);
}
void EchoPinA_ISR() {
    static unsigned long startTimeA;

    if (digitalRead(echoPinA)) // Gone HIGH
        startTimeA = micros();
    else  // Gone LOW
        LastPulseTimeA = micros() - startTimeA;
}
void EchoPinB_ISR() {
    static unsigned long startTimeB;

    if (digitalRead(echoPinB)) // Gone HIGH
        startTimeB = micros();
    else  // Gone LOW
        LastPulseTimeB = micros() - startTimeB;
}
2
  • Thanks, I'll try. Question though, will there be time enough for the rest of the program to run, as I assume the pins will change value all the time, interrupting the program 24/7?
    – andrew
    Commented Apr 11, 2017 at 20:15
  • 1
    As far as I can see from the specs, the echo will take some time up to 25 ms depends on the distance, maybe even more if there is no obstacle and then can take up to 38ms. So, it won't be that busy. But, of course it is also what you want to do with the echoing data. You may then consider to switch Arduino Mega or even Cortex-M0 or further.
    – Sener
    Commented Apr 12, 2017 at 0:18
1

fairly simple:

  if (time_is_up_for_sensor1()) read_sensor1(); //read sensor1 if time is up
  if (time_is_up_for_sensor2()) read_sensor2(); //read sensor2 if time is up

in time_is_up_for_sensor1/2(), update for the next round of reading:

int time_is_up_for_sensor1(void) {
  static uint32_t millis_next = 0; //next millis
  if (millis() >= millis_next) {  //time is up for sensor1
    millis_next += INTERVAL_SENSOR1; //advance to the next measurement time
    return 1;  //needs to read sensor1
  } else return 0;
}

similarly for sensor2

2
  • The millis_next += INTERVAL_SENSOR1; ... if (millis() >= millis_next)... method miscomputes when millis() overflows. To avoid that, instead write millis_prev = millis(); (or perhaps millis_prev += INTERVAL_SENSOR1;) and then test via if (millis()-millis_prev > INTERVAL_SENSOR1)... Commented Apr 10, 2017 at 5:42
  • what does static uint32_t millis_next = 0; do exactly? (I'm new to C++/Arduino)
    – andrew
    Commented Apr 10, 2017 at 9:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.