Hi everyone!
I'm doing a project for Biomedical Signal Acquisition, with a friend.
The goal is to localize sound inside a hospital room with, for example, 6 sleeping people.
WHY? During night, people with respiratory diseases might cough. Monitoring their cough history might help in diagnostics and therapy success assessment. BUT, in order to achieve proper monitoring, the monitoring system should be able to attribute sounds to the specific patient that coughed. Thus, it is need to estimate the angle of arrival of a given sound.
To achieve that, an electronic circuit to acquire signals from 2 microphones into the arduino was built.
In summary, the two microphone signals are: 1) amplified and then 2) compared. (I will get graphics of the circuit for anyone interested in this.)
In the end, what the circuit achieves is: each time there is some sound in the room, a transient square wave spanning the time the sound is being made is fed into the arduino - this happens for each microphone, of course. Because both microphones' circuits are built exactly the same, and they're only 10cm apart, they should have virtually the same properties in terms of time-frequency responses each time some sound is made. Thus, the two signals should only differ in their phase, since sound will arrive at different times at each microphone.
Having these two digital signals going into two digital pins in arduino, I can simply record times of activation of each mic and calculate their difference time of arrival. EZ, right?
So, right now, my friend already has the two signals going great in the oscilloscope (it's either 0V when it's silence, or 5V when someone coughs, claps, etc.), but I'll be only able to test things Wednesday, when I arrive to the lab.
Here's the code I have.
/////ARDUINO SCRIPT FOR DIFFERENCE TIME OF ARRIVAL CALCULATION (USING 2 MICROPHONES) ON MEGA2560/////
//// Loop time-control variables
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long halfPeriod = 50; // in microseconds
unsigned long elapsedMicros;
//// Signal processing variables
double value1; // records value in mic1
double value2; // records value in mic2
boolean state = false; // records whether an ongoing transient is happening (be it either on mic1 or mic2)
unsigned long firstTime; // records the time of the first transient (in any mic)
int firstMic; // records which mic is activated first
unsigned long timeDiff; // records timeDifference between arrival of signals
double angle; // records angle of arrival
//// SETUP
void setup() {
// set pins DIGITAL53 & DIGITAL51 as inputs (for ATmega2560: D53->PB0, D51->PB2)
DDRB=B11111010;
// initialize serial communication at 9600 bits per second [debugging purposes]
Serial.begin(9600);
// start control loop variable
previousMicros = micros();
}
//// LOOP
void loop() {
while(1){ // eliminate loop jitter
currentMicros = micros();
elapsedMicros = currentMicros - previousMicros;
// this imposes the desired loop speed
if (elapsedMicros >= halfPeriod){
value1 = PINB&B00000001;
value2 = PINB&B00000100;
// if one of the mics is activated
if(state) {
// check which mic is activated
switch (firstMic) {
case 1:
if(value2>0.9) {
timeDiff = firstTime - micros();
state=false;
}
break;
case 2:
if(value1>0.9) {
timeDiff = micros() - firstTime;
state=false;
}
break;
}
// if we had activation (state is true) and we had a subsequent second transient (state goes to false) and thus we can calculate the angle
if(state==false) {
angle = (57.29578*timeDiff*0.000001*343)/(0.1);
delay(0.2);
}
// resets 'state' variable after some time (1 second) without identifying second transient (this avoids stupid situations)
if(micros()-firstTime>1000) {
state = false;
}
} else { // if we're not in activated state
// we check for mic1
if(value1>0.9) {
firstTime = micros();
state = true;
firstMic = 1;
}
// we check for mic2
if(value2>0.9) {
firstTime = micros();
state = true;
firstMic = 2;
}
}
previousMicros = micros();
}
}
}
As is obvious from the code, I try to sample the input signals at some specified rate (right now, I'm thinking of reading up values from the pins each 50microseconds), so I can have some sort of a systematic reading error in both microphones. But I'm not sure whether I'll accomplish what I want with this code.
Basically, although I already read through some posts and tested myself some aspects of this issue, I'm still insecure regarding some options made: 1) the way I read the digital values (type of variables used and port manipulation), 2) the way I control the loop to read values and do things (previousMicros, elapsed, etc) and 3) other general aspects of the code that I might not have thought of.
If this project turns out nicely, I would very much appreciate to share the full report and code here on the forum.
Stay cool, and thanks so much to the whole forum staff and community!
Great work! ![]()