Hi, jaysonragasa.
Impressive work! I've implemented it on a Crius AIO and expect to test in field shortly.
I observe that in your ISR for the echo pulse you use 32 bits arithmetic. The problem is in the division. If you inspect the resultant assembly code ('avr-objdump -dS sensors.cpp.o') you get the following:
Code: Select all
tempSonarAlt = SONAR_GEP_echoTime / SONAR_GENERIC_SCALE;
86: 60 91 00 00 lds r22, 0x0000
8a: 70 91 00 00 lds r23, 0x0000
8e: 80 91 00 00 lds r24, 0x0000
92: 90 91 00 00 lds r25, 0x0000
96: 2a e3 ldi r18, 0x3A ; 58
98: 30 e0 ldi r19, 0x00 ; 0
9a: 40 e0 ldi r20, 0x00 ; 0
9c: 50 e0 ldi r21, 0x00 ; 0
9e: 0e 94 00 00 call 0 ; 0x0 <__vector_9>
a2: c9 01 movw r24, r18
a4: da 01 movw r26, r20
a6: 00 c0 rjmp .+0 ; 0xa8 <__vector_9+0xa8>
else
There appears, as expected, a 'call' to a 32 bits division in a library. Probably it is reentrant, but is going to consume time (and intrrupts are not enabled).
There is a simple workaround: move the division away from the ISR, to SonarUpdate():
Code: Select all
void Sonar_update() {
sonarAlt = 1 + tempSonarAlt / SONAR_GENERIC_SCALE; // moved 32 bits division here away from ISR below
SONAR_GEP_TriggerPin_PIN_LOW;
delayMicroseconds(2);
SONAR_GEP_TriggerPin_PIN_HIGH;
delayMicroseconds(10);
SONAR_GEP_TriggerPin_PIN_LOW;
}
ISR(SONAR_GEP_EchoPin_PCINT_vect) {
if (SONAR_GEP_EchoPin_PIN & (1 << SONAR_GEP_EchoPin_PCINT)) {
SONAR_GEP_startTime = micros();
}
else {
SONAR_GEP_echoTime = micros() - SONAR_GEP_startTime;
if (SONAR_GEP_echoTime <= SONAR_GENERIC_MAX_RANGE*SONAR_GENERIC_SCALE)
tempSonarAlt = SONAR_GEP_echoTime; // avoid 32 bits division in ISR
else
tempSonarAlt = -1;
}
}