for one of my projects I am looking for a method to controll a multiple amount of Ultrasonic range sensors at the same time. I am using 8x the HC-SR04 Ultrasonic sensor.
Controlling one after another in a loop would take to much time for me, so I am looking for a way to controll all 8 PINs at the same time.
I am new to arduino but I have a bit of experience with C+. Is there maybe a library which brings these functions? Or is it possible to controll all 8 PINs with an Array? Even some keywords to look and search for would be really helpfull.
Hi, even with 180deg, and I can't see how you are going to place 8 of them 180deg apart, you will have not just reflections from your target but reflections from other surfaces, all at the same time.
I agree with the earlier posters who say that there should be interference and it may no work. But if it is going to be simultaneous, you will need to use interrupts instead of pulseIn, because that function is blocking.
I don't have two HC SR04 sensors to play with, but here is an untested sketch for two sensors, using external interrupts on pin 2 and 3. It is based on a sketch I have which works for one sensor.
Try it. Let us know if you get interrupts firing off like crazy, or if you can actually get meaningful data.
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(0, EchoPinA_ISR, CHANGE); // Pin 2 interrupt on any change
attachInterrupt(1, 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(2)) // Gone HIGH
startTimeA = micros();
else // Gone LOW
LastPulseTimeA = micros() - startTimeA;
}
void EchoPinB_ISR() {
static unsigned long startTimeB;
if (digitalRead(3)) // Gone HIGH
startTimeB = micros();
else // Gone LOW
LastPulseTimeB = micros() - startTimeB;
}
If all sensors fire at the same time, each sensor will report the first echo to arrive at its location, via the shortest path. That shortest path could result from reflection by two or more different surfaces.
In some cases, people have shown that it is possible to reconstruct the reflecting environment, using very sophisticated software running on a relatively powerful computer.
However, is hard to see how you could use an Arduino to make sense out of those echos, unless you already have a very clear idea of the positions and orientations of all the surrounding, reflecting surfaces.
But I agree with cattledog, if you can figure it out, let us know!
I think the conclusion is that simultaneous firing will work for obstacle avoidance, but
might be tricky for mapping or long-range sensing.
You'll also have to check the peak current drain from modules as this will happen simultaneously (transmit uses significant power for a long range sensor).
That tutorial just supports the point that the triggering and reading of the sensors needs to be sequential and not simultaneous.
First of all, we will generate the trigger pulse for first sensor and the read its echo pin and get the distance, then we generate the trigger pulse for second sensor and read its echo pin and so on for the third.
It also uses pulseIn to read the pulse length, and since it is a blocking function the readings have be sequential.
The OP was clear that he wanted simultaneous readings.
Controlling one after another in a loop would take to much time for me, so I am looking for a way to controll all 8 PINs at the same time.
and from a follow on poster
i'm in the same situation, where I need to control two or more ultrasonic sensors simultaneously, not one after one...
cattledog:
I agree with the earlier posters who say that there should be interference and it may no work. But if it is going to be simultaneous, you will need to use interrupts instead of pulseIn, because that function is blocking.
I don't have two HC SR04 sensors to play with, but here is an untested sketch for two sensors, using external interrupts on pin 2 and 3. It is based on a sketch I have which works for one sensor.
Try it. Let us know if you get interrupts firing off like crazy, or if you can actually get meaningful data.
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(0, EchoPinA_ISR, CHANGE); // Pin 2 interrupt on any change
attachInterrupt(1, 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(2)) // Gone HIGH
startTimeA = micros();
else // Gone LOW
LastPulseTimeA = micros() - startTimeA;
}
void EchoPinB_ISR() {
static unsigned long startTimeB;
if (digitalRead(3)) // Gone HIGH
startTimeB = micros();
else // Gone LOW
LastPulseTimeB = micros() - startTimeB;
}
please, i have question
In which thing you use durationA & durationB in this code?
I made multiple models of it.
The one above was the original.
I modified it to (6) Sensors of 2x3 instead of the (5) X pattern.
I built a third model that is 3x2 - a wide UltraSonar of about 90-degree width by 60-degree height
for Front Ranging on Crawling Robots.
It processes all of the UltraSonic Sensors at Ten times per Second (10Hz).
I even use Beeps of varying Frequencies (besides the Sonar Scope Printout).
I intend to try increasing the Resolution in the next model.
PS: - I don't see the problems complained about here.
I wave my hand in front of it (anywhere from 6-inches to 5-feet) - and it returns a map
with my hand floating around the map - very accurate !
The chair next to or behind me sets it off, somebody walking by, the ceiling, etc.
But, the individual ranges returned -explain the results.
I don't have the Code in front of me; I will need to go looking for it.
But basically, I sent out all of the Triggers at the same time.
Then the Echos were read as a Port read simultaneously in a Loop (No Interrupt).
When one was received it was Flagged and put into a ReceiveSonar Array,
until it timed out.
It printed the Measured Results, then started the Trigger all over again.