Go Down

Topic: Read 2 HC-SR04 (Read 5694 times) previous topic - next topic


Hi I am trying to read 2 ultrasonic sensors together, so i have used the pulsein function and modified it in my code to read both sensor,it works but the problem is that i`m not sure if the code is correct because i haven't understood the "// cache the port and bit of the pin in order to speed up the pulse width measuring loop"
and just multiplied it to work for 2 sensors, if someone can explain that to me, will be grateful.

attached is the code:
My attempt for multiple sensors read 29/06/2012
#include "wiring_private.h"
#include "pins_arduino.h"

//define HC-SR04 pins
#define trigPin 22
#define echoPin1 24
#define echoPin2 26

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(echoPin2, INPUT);

  //main program
void loop() {
  //define parameters
  int duration[2], distance[2];
  // send out a ping
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin, HIGH);
  digitalWrite(trigPin, LOW);
  // measure the returned signal.

  /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
        // cache the port and bit of the pin in order to speed up the
   // pulse width measuring loop and achieve finer resolution.  calling
   // digitalRead() instead yields much coarser resolution.
        uint8_t state=HIGH;
        unsigned long timeout=5000;
        uint8_t bit1 = digitalPinToBitMask(echoPin1);
        uint8_t bit2 = digitalPinToBitMask(echoPin2);
   uint8_t port1 = digitalPinToPort(echoPin1);
        uint8_t port2 = digitalPinToPort(echoPin2);
   uint8_t stateMask1 = (state ? bit1 : 0);
        uint8_t stateMask2 = (state ? bit2 : 0);

   unsigned long width[2] ={0, 0}; // keep initialization out of time critical area
   // convert the timeout from microseconds to a number of times through
   // the initial loop; it takes 16 clock cycles per iteration.
   unsigned long numloops = 0;
   unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
   // wait for any previous pulse to end
   while ((((*portInputRegister(port1) & bit1) == stateMask1) || ((*portInputRegister(port2) & bit2) == stateMask2)) && (numloops< maxloops))
   // wait for the pulse to start
   while (((((*portInputRegister(port1) & bit1) != stateMask1) || ((*portInputRegister(port2) & bit2) != stateMask2))&& (numloops< maxloops)) && (numloops< maxloops))

   // wait for the pulse to stop
   while (((((*portInputRegister(port1) & bit1) == stateMask1) || ((*portInputRegister(port2) & bit2) == stateMask2))) && (numloops< maxloops)){
                if ((*portInputRegister(port1) & bit1) == stateMask1)
                if ((*portInputRegister(port2) & bit2) == stateMask2)

    Serial.print(" - ");

//   // convert the reading to microseconds. The loop has been determined
//   // to be 20 clock cycles long and have about 16 clocks between the edge
//   // and the start of the loop. There will be some error introduced by
//   // the interrupt handlers.
//   duration[0]=clockCyclesToMicroseconds(width[0] * 21 + 16);
//  // convert to distance and display
//  distance[0] = (duration[0]/2) / 29.1;
//  if (distance[0] >= 100 || distance[0] <= 0){
//    Serial.println("Out of range");
//  }
//  else {
//    Serial.print(distance[0]);
//    Serial.println(" cm");
//  }


Changed the code so the returned signal measured in a function. (easier to view)
Attached code for whoever wants to use and modify.


Changed the code so the returned signal measured in a function. (easier to view)
Attached code for whoever wants to use and modify.

For reading 2 or more ultrasonic sensors, you may want to try using the NewPing library as it supports timer interrupts for an event-driving programming style.  While NewPing doesn't ping two sensors at the same time, it allows you to ping sensors very quickly (less than 30ms apart), which should almost always give the same result.  As a bonus, your sketch can be doing something else while it is in the ping process as it uses a timer interrupt while waiting for the ping echo.

Using NewPing, one user has 15 sensors connected to a single project and with the event-driven method there's time to process this information.  Below is a link to the NewPing library as well as the 15 sensor example sketch (which could be easily adjusted to just ping 2 or any number of sensors).


15 Sensor Example Sketch

My hardware: Arduino, Teensy 2.0, Teensy 3.2 & custom ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My Projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

Go Up