After many tests, I am now trying to determine the length of an echo using an at2313/at4323 piggybacked on a hc-sr04 in order to process the output of detected echos using the analog comparator.
Detecting the start of one or more echos is not a problem using interrupts.
The timer1 is set to run at 2 Mhz, giving 0.5 us resolution and is only active after the transmitter rises the echo signal.
To be able to watch the output on a scope, a pin was toggled for each pulse giving a 20 Khz square wave(in theory).
As there is around 20 us (16Mhz clock) within the isr to do processing, first step was to count the pulses within the first echo.
Finally, the timer ticks for start and end of the echo is now recorded.
Using interrupts, the end is not detected, it is only possible to store the timer ticks for each pulse over and over until a gap appears and a new echo starts.
Seems to be cutting the time fine as is.
Essentially casting a shadow the width of the echo across the field of view where another object might hide.
Knowing the length of the echo makes it possible to detect another object beyond the shadow.
Makes for a very low resolution sonar.
Is there an easier way to obtain the length of an echo than shown in the isr code below?
#define ROUNDTRIP_CM 57 //Sonar centimeter round trip in us
#define MAX_ECHOS 4
#ifdef USE_16MHZXTAL
#define PULSEWIDTH 58 //Just above 25 usec, 2 Mhz
#else
#define PULSEWIDTH 28
#endif
#ifdef USE_16MHZXTAL
#define MIN_ECHO_DISTANCE ROUNDTRIP_CM * 2
#else
#define MIN_ECHO_DISTANCE ROUNDTRIP_CM
#endif
volatile uint16_t distance[MAX_ECHOS]; //Store up to 4 echos
volatile uint16_t echo_end[MAX_ECHOS]; //Store end time of echos
volatile int8_t distcount;
volatile uint16_t old_clock;
volatile byte state; // 0-= idle, 1 = store echo time, 2 = send result(s)
volatile uint16_t lastPulse;
//Store start ticks and update end ticks for each pulse.
ISR(ANA_COMP_vect) {
//Always catch timer count?
uint16_t clocks = TCNT1; //16 bits, 1 mhz 64K ms = 64K us, 2mhz 32K ms no overflow
ACSR &= ~(1 << ACIE);
if ( distcount < MAX_ECHOS) {
//Store start of echo only, ignore pulses until long gap
if ( clocks > old_clock ) {
distance[distcount++] = clocks; //Ticks from timer start
lastPulse = clocks + PULSEWIDTH; //Start saving end ticks
}
//Store timer count of last pulse within echo.
if (clocks < lastPulse ) {
//https://forum.arduino.cc/t/maximum-pin-toggle-speed/4378
PIND = (1 << PD6);
echo_end[distcount -1] = clocks; //Store ticks of current pulse
lastPulse = clocks + PULSEWIDTH;
}
old_clock = clocks + MIN_ECHO_DISTANCE; //Avoid restart within a pulse train.
}
ACSR |= (1 << ACIE);
}