I am currently busy with a project and urgently need help in the right direction. I am a total newbie so please bear with me. I am trying to develop a device to triangulate a sound source. The final project will have multiple sensors the same as the the one I am busy with. The final triangulation will be done by the combined data from 2 or more sensors. The current sensor will only provide a compass bearing to the detected sound.
I have three microphones in an equal triangle formation, each spaced 1 meter apart. I numbered them 1 to 3 with number 1 at the point which will point north 0/360 degrees, number 2 at 120 degrees and three at 240 degrees. they are connected to Analog input pins 1,2 and 3 on an Arduino Mega 2560. Incorporated in this design is also a DS18B20 Thermometer to calculate the correct speed of sound at any given time. Please see the attached Fritzing image for the current setup.
I have used FASTADC as to do faster analog reads (currently reading at 18 microseconds). When the threshold of a microphone is exceeded, I check the remaining mics for a 2nd detection from where the bearing can be calculated.
I will probably add sound analyzing at a later stage, maybe on another microprocessor.
As I said, I am a newbie, please have a look at the code and give me comments on how to improve on the coding and design. When connecting an Xbee I realized that the analog Read values are pushed up quite a lot, normal quiet environment reads will be in the range of 500 to 600, with the Xbee they are pushed to 900 or more. Is it an issue with power distribution or something affecting the RX/TX ports on the Arduino?
Below is my current working code version
#include <OneWire.h>
#include <DallasTemperature.h>
// Detection Order Vars
int S1; // Var to hold 1st detection Mic number
int S2; // Var to hold 2nd detection Mic number
// Analog Read Values
int sensorCheck; // Var to hold Audio Value
int sensorValue1; // Var to hold detected Audio Value of Mic 1
int sensorValue2; // Var to hold detected Audio Value of Mic 2
int sensorValue3; // Var to hold detected Audio Value of Mic 3
// Timing Vars
double detectTime; // Var for detection time out
double time1; // Var to hold 1st detection time, time when 1st mic exceeded the set threshold
double time2; // Var to hold 2nd detection time, time when 2nd mic exceeded the set threshold
// Timing Calculation Vars
double calculatedMS1; // 2nd detection time - 1st detection time micro second value
double calculatedSeconds1= 0.0000000000; // Var to convert microseconds to seconds for angle calculation of 1st detection
// Distance, angle and bearing vars
double DistA = 0; // Calculated sound wave distance between 1st mic detection and 2nd mic detection in meter
double BearingResult1 =0; // Bearing result from 1st detection
double FinalBearing1 =0; // Adjusted and final compass bearing of 1st detection
// Constant Values
double LengthOfSide = 1; // Constant for Mic Array triangle side value in meter
double RadToDegrees = (360/(2*3.1415)); // Radians to degrees function
double temp =0; // Var to hold current temeprature Deg Celsius
double SpeedOfSound = 0; // Var to hold calculated speed of sound value for angle calculation
int micThreshold = 600; // Detection Threshold
// DS18B20 Temperature Sensor defined
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// Fast ADC defined
#define FASTADC 1
// Fast ADC defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup()
{
Serial.begin(57600);
sensors.begin();
}
void loop()
{
// Zero All Variables
// Analaog read vars
sensorValue1 =0;
sensorValue2 =0;
sensorValue3 =0;
sensorCheck =0;
// Timing Vars
detectTime =0;
time1=0;
time2=0;
calculatedMS1 = 0;
calculatedSeconds1=0;
// Distance, angle and bearing vars
DistA = 0;
BearingResult1 = 0;
FinalBearing1 = 0;
sensors.requestTemperatures(); // get current Temp
Serial.print("Current Temperature: ");
Serial.println(sensors.getTempCByIndex(0)); // print current temp
Serial.println("Waiting...................."); // show we are ready for detection
// Set the ADC for fast clock speed (18 microsecond per analogRead)
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
// Start the detection Sequence
// Check Mic 1
//------------------------------
while (sensorCheck<micThreshold)
{
sensorCheck =0;
sensorCheck = analogRead(1);
if (sensorCheck>=micThreshold){ // Check If Mic 1 exceeded the threshold, save S1 Var to 1, time1 to current micros()
time1= micros();
sensorValue1 = sensorCheck;
sensorCheck=0; // Reset sensorCheck Var
S1=1;
while (sensorValue1>micThreshold && sensorCheck<micThreshold){
detectTime = micros()-time1;
if (detectTime >5880) // check if 1st detection is timed out 1 -
{
NoDetect();
}
sensorCheck =0;
sensorCheck = analogRead(2);
if (sensorCheck>=micThreshold){ // While Mic 1 exceed threshold is true Check If Mic 2 exceeded the threshold
time2= micros();
sensorValue2 = sensorCheck;
sensorCheck =0;
S2=2;
Action();
}
}
sensorCheck =0;
sensorCheck = analogRead(3);
if (sensorCheck>=micThreshold){ // While Mic 1 exceed threshold is true Check If Mic 3 exceeded the threshold
time2= micros();
sensorValue3 = sensorCheck;
sensorCheck =0;
S2=3;
Action();
}
}
// Check Mic 2
//------------------------------
sensorCheck =0;
sensorCheck = analogRead(2);
if (sensorCheck>=micThreshold){ // Check If Mic 2 exceeded the threshold, save S1 Var to 2, time1 to current micros()
time1= micros();
sensorValue2 = sensorCheck;
sensorCheck=0;
S1=2;
while (sensorValue2>micThreshold && sensorCheck<micThreshold){
detectTime = micros()-time1;
if (detectTime >5880)// check if 1st detection is timed out 2 -
{
NoDetect();
}
sensorCheck =0;
sensorCheck = analogRead(1);
if (sensorCheck>=micThreshold){ // While Mic 2 exceed threshold is true Check If Mic 1 exceeded the threshold
time2= micros();
sensorValue1 = sensorCheck;
sensorCheck =0;
S2=1;
Action();
}
sensorCheck =0;
sensorCheck = analogRead(3);
if (sensorCheck>=micThreshold){ // While Mic 2 exceed threshold is true Check If Mic 3 exceeded the threshold
time2= micros();
sensorValue3 = sensorCheck;
sensorCheck =0;
S2=3;
Action();
}
}
}
// Check Mic 3
//------------------------------
sensorCheck =0;
sensorCheck = analogRead(3);
if (sensorCheck>=micThreshold){ // Check If Mic 3 exceeded the threshold, save S1 Var to 3, time1 to current micros()
time1= micros();
sensorValue3 = sensorCheck;
sensorCheck=0;
S1=3;
while (sensorValue3>micThreshold && sensorCheck<micThreshold){
detectTime = micros()-time1;
if (detectTime >5880)// check if 1st detection is timed out 3 -
{
NoDetect();
}
sensorCheck =0;
sensorCheck = analogRead(1);
if (sensorCheck>=micThreshold){ // While Mic 3 exceed threshold is true Check If Mic 1 exceeded the threshold
time2= micros();
sensorValue1 = sensorCheck;
sensorCheck =0;
S2=1;
Action();
}
sensorCheck =0;
sensorCheck = analogRead(2);
if (sensorCheck>=micThreshold){ // While Mic 3 exceed threshold is true Check If Mic 2 exceeded the threshold
time2= micros();
sensorValue2 = sensorCheck;
sensorCheck =0;
S2=2;
Action();
}
}
}
}
}
void Action()
{
sensors.requestTemperatures();
temp = sensors.getTempCByIndex(0);
SpeedOfSound = (331.3 + (.606*temp));
// Do 1st Triangulation between 1st and 2nd detection
calculatedMS1 = time2 - time1;
calculatedSeconds1=calculatedMS1 / 1000000;
DistA=(calculatedSeconds1 * SpeedOfSound);
BearingResult1 = (acos(DistA / LengthOfSide)*RadToDegrees)-30;
if (S1==1 && S2==2){
FinalBearing1 = 0 + BearingResult1;
}
if (S1==1 && S2==3){
FinalBearing1 = 360 - BearingResult1;
}
if (S1==2 && S2==1){
FinalBearing1 = 120 - BearingResult1;
}
if (S1==2 && S2==3){
FinalBearing1 = 120 + BearingResult1;
}
if (S1==3 && S2==1){
FinalBearing1 = 240 + BearingResult1;
}
if (S1==3 && S2==2){
FinalBearing1 = 240 - BearingResult1;
}
Serial.print("Mics");
Serial.print(S1);
Serial.print("-");
Serial.print(S2);
Serial.print("; Seconds between detections:");
Serial.print(calculatedSeconds1,10);
Serial.print("; Measured Distance:");
Serial.print(DistA,10);
Serial.print("; Calculated Bearing:");
Serial.print(BearingResult1,2);
Serial.print("; Compass Bearing:");
Serial.println(FinalBearing1,2);
sensorCheck=0;
delay(1000);
loop();
}
void NoDetect()
{
Serial.println("Not enough detection data, detection timed-out. At least 2 of the 3 microphones must detect the event");
loop();
}