So, as a part of a school project I'm working with a teammate on using these neat ultrasonic rangefinders to find the location of an object and use it as mouse input. We're basically making a pseudo-touchscreen with three sensors and trilateration. The sensors will be placed around the edge of a screen and then when an object is in their range the Arduino will do a little bit of magic and interpret your intent as a click or select, and then send that to the computer. Right now we're at the very first stage of implementation. We have an Arduino mega and 3 SRF05 Ultrasonic Rangefinders. We're having trouble getting input from more than one sensor at a time, though. We found a great website online that's using our exact sensor and we started doing basic tests with his code. This is code that we pilfered from his tutorial and modified slightly. The website is here.
const int numOfReadings = 10;
int readings[numOfReadings];
int arrayIndex = 0;
int total = 0;
int averageDistance = 0;
int echoPin = 22;
int initPin = 24;
unsigned long pulseTime = 0;
unsigned long distance = 0;
void setup() {
pinMode(initPin, OUTPUT);
pinMode(echoPin, INPUT);
for (int thisReading = 0; thisReading < numOfReadings; thisReading++)
{
readings[thisReading] = 0;
}
Serial.begin(9600);
}
void loop() {
digitalWrite(initPin, HIGH);
delayMicroseconds(10);
digitalWrite(initPin, LOW);
pulseTime = pulseIn(echoPin, HIGH);
distance = pulseTime/58;
total= total - readings[arrayIndex];
readings[arrayIndex] = distance;
total= total + readings[arrayIndex];
arrayIndex = arrayIndex + 1;
if (arrayIndex >= numOfReadings)
{
arrayIndex = 0;
}
averageDistance = total / numOfReadings;
Serial.println(averageDistance, DEC);
delay(100);
}
So, this code takes readings on a single digital pin and averages a set of ten of them to remove jitter, as luckylarry terms it. It works great as is, but when we try and modify it to work with multiple sensors, it still only does the first sensor we define. Here's our hacked code:
// written at: luckylarry.co.uk
// variables to take x number of readings and then average them
// to remove the jitter/noise from the SRF05 sonar readings
const int numOfReadings = 3; // number of readings to take/ items in the array
int readings[numOfReadings]; // stores the distance readings in an array
int readings2[numOfReadings];
int readings3[numOfReadings];
int arrayIndex = 0; // arrayIndex of the current item in the array
int total = 0; // stores the cumlative total
int total2 = 0;
int total3 = 0;
int averageDistance = 0; // stores the average value
int averageDistance2 = 0;
int averageDistance3 = 0;
// setup pins and variables for SRF05 sonar device
int echoPin = 22; // SRF05 echo pin (digital 2)
int initPin = 24; // SRF05 trigger pin (digital 3)
int echoPin2 = 28;
int initPin2 = 30;
int echoPin3 = 34;
int initPin3 = 36;
unsigned long pulseTime = 0; // stores the pulse in Micro Seconds
unsigned long distance = 0; // variable for storing the distance (cm)
unsigned long pulseTime2 = 0;
unsigned long distance2 = 0;
unsigned long pulseTime3 = 0;
unsigned long distance3 = 0;
//setup
void setup()
{
pinMode(initPin, OUTPUT); // set init pin 3 as output
pinMode(echoPin, INPUT); // set echo pin 2 as input
pinMode(initPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(initPin3, OUTPUT);
pinMode(echoPin3, INPUT);
// create array loop to iterate over every item in the array
for (int thisReading = 0; thisReading < numOfReadings; thisReading++)
{
readings[thisReading] = 0;
}
// initialize the serial port, lets you view the
// distances being pinged if connected to computer
Serial.begin(9600);
}
// execute
void loop()
{
digitalWrite(initPin, HIGH); // send 10 microsecond pulse
digitalWrite(initPin2, HIGH);
digitalWrite(initPin3, HIGH);
delayMicroseconds(10); // wait 10 microseconds before turning off
digitalWrite(initPin, LOW); // stop sending the pulse
digitalWrite(initPin2, LOW);
digitalWrite(initPin3, LOW);
pulseTime = pulseIn(echoPin, HIGH); // Look for a return pulse, it should be high as the pulse goes low-high-low
pulseTime2 = pulseIn(echoPin2, HIGH);
pulseTime3 = pulseIn(echoPin3, HIGH);
distance = pulseTime/58; // Distance = pulse time / 58 to convert to cm.
distance2 = pulseTime2/58;
distance3 = pulseTime3/58;
total= total - readings[arrayIndex]; // subtract the last distance
total2 = total2 - readings2[arrayIndex];
total3 = total3 - readings3[arrayIndex];
readings[arrayIndex] = distance; // add distance reading to array
readings2[arrayIndex] = distance2;
readings3[arrayIndex] = distance3;
total = total + readings[arrayIndex]; // add the reading to the total
total2 = total + readings2[arrayIndex];
total3 = total + readings3[arrayIndex];
arrayIndex = arrayIndex + 1; // go to the next item in the array
// At the end of the array (10 items) then start again
if (arrayIndex >= numOfReadings)
{
arrayIndex = 0;
}
averageDistance = total / numOfReadings; // calculate the average distance
averageDistance2 = total2 / numOfReadings;
averageDistance3 = total3 / numOfReadings;
// if the distance is less than 255cm then change the brightness of the LED
Serial.print(averageDistance, DEC); // print out the average distance to the debugger
Serial.print(", ");
Serial.print(averageDistance2, DEC);
Serial.print(", ");
Serial.print(averageDistance3, DEC);
Serial.println();
delay(100); // wait 100 milli seconds before looping again
}
I left Larry's comments in on this one, sorry if it's a little too much. So, we get garbage readings using that code (zeros, basically). I'm just wondering what the underlying problem is. We got it to work previously by breaking up the digitalWrite and pulseIn sections among the three sensors, letting each one do its business before trying to mess with another sensor. What's the difference? I'm really curious about what's going on underneath the hood here.