Hello,
Long winded, but I gather people on this forum like a good amount of information.
As part of and Army military career course (Electronics Engineering Degree), we have built a sound source triangulation system based on Angle of Arrival for our project. The system operates with two nodes, each with two microphones, which return a bearing to a central unit via RF, and the central unit calculates the distance to source, and bearing from its known position in relation to the two nodes.
The system operates well, with good accuracy from 20-160 degrees. The only issues in it are the interrupts which take the time delays not quite being fast enough at the acute angle <20 & > 160 degrees. Otherwise we have tested strong results for bearings with results being correct, or +-5 degrees, and reasonable results for distance +-0.5m at short range. Long range tests are still TBC.
My requests is mainly to do with the interrupt side, and creating low level ISR's via the register. I have made attempts to get it done, but I will not lie that I am capable, and due it being that layer deeper, the examples available are not very often. We've done 4 weeks Zero to Hero Arduino coding, and are hobbyists at best.
We are using Arduino Mega 2650's, on pins 2, & 3 (INT4, INT5) attachInterrupts on changing state to catch the first rise out of Schmitt trigger which works off the analogue input. The results are good in the goldilocks zoon 20-260deg due to the lesser requirement for accurate time delay measurements
The code below is the parts that matter.
#include <eRCaGuy_Timer2_Counter.h>
bool mic1trigger = 0;
bool mic2trigger = 0;
volatile int mic1substate = 0;
volatile int mic2substate = 0;
const int soundmic1pin = 2;
const int soundmic2pin = 3;
int unsigned long mic1soundtimemic;
int unsigned long mic2soundtimemic;
void setup(){
pinMode(soundmic1pin, INPUT_PULLUP);
pinMode(soundmic2pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(soundmic1pin), mic1listen, CHANGE);
attachInterrupt(digitalPinToInterrupt(soundmic2pin), mic2listen, CHANGE);
}
Void loop (){
anglesolution(); //runs the triangulation
}
void mic1listen()
{
if (!mic1substate) {
mic1soundtimemic = timer2.get_count();
mic1substate = 1;
mic1trigger = 1;
}
}
void mic2listen()
{
if (!mic2substate) {
mic2soundtimemic = timer2.get_count();
mic2substate = 1;
mic2trigger = 1;
}
}
I have had minimal success getting INT4 to interrupt via the below code, but I am afraid I don't understand the ATMEGA2560 datasheet enough to make progress on INT5. It seems so simple, yet far away.
#include <avr/interrupt.h>
#include <avr/io.h>
#include <eRCaGuy_Timer2_Counter.h>
bool mic1trigger = 0;
bool mic2trigger = 0;
volatile int mic1substate = 0;
volatile int mic2substate = 0;
const int soundmic1pin = 2;
const int soundmic2pin = 3;
int unsigned long mic1soundtimemic;
int unsigned long mic2soundtimemic;
void setup() {
// put your setup code here, to run once:
pinMode(soundmic1pin, INPUT_PULLUP);
pinMode(soundmic2pin, INPUT_PULLUP);
EICRB = 0x0A;
EIMSK = 0x10;
sei();
}
Void loop (){
anglesolution(); //runs the triangulation
}
ISR(INT4_vect)
{
if (!mic1substate) {
mic1soundtimemic = timer2.get_count();
mic1substate = 1;
mic1trigger = 1;
}
}
ISR(INT5_vect)
{
if (!mic2substate) {
mic2soundtimemic = timer2.get_count();
mic2substate = 1;
mic2trigger = 1;
}
}
My request is simple. Is there anyone who can help us with low level ISR code for INT4, and INT5 on CHANGING state? Our project works, and is fully presentable, this would just be an added bonus if we could refine the Interrupts ever so slightly more.
I am also aware of using input capture to take a reading from Timer1 of the exact moment the interrupt happened, but that also proved unsuccessful, again, being limited to very few examples make it more challenging. Nick Gammon's forum has proven educational, and informative, but I can't take the time right now to fully get my head around the deeper level of understanding required to achieve an input capture.
Any help is obviously fully appreciated.