I wasn't happy with the code examples which are blocking and use pulseIn for what are hopefully obvious reasons. Because of the issues with blocking I have written an interrupt based sketch for the MEGA. Consulting the datasheet should allow this to be easily converted to work on any of the 8 bit arduinos.
Trigger is pin 11
Echo is pin 12
I hope this helps someone.
#define FREQ_TRIG 15
#define PRESCALE_TRIG 64
#define PERIOD_TRIG ((F_CPU/PRESCALE_TRIG/FREQ_TRIG) - 1)
volatile uint32_t start,width;
float pingDistCentimeters,pingDistMeters;
volatile boolean newPing;
void setup(){
Serial.begin(115200);
SonarInit();//must go above detectRC or the program breaks!
}
void loop(){
if (newPing == true){
newPing = false;
pingDistCentimeters = width * 0.01724137;
pingDistMeters = pingDistCentimeters * 0.01;
Serial.println(pingDistCentimeters);
}
}
void SonarInit(){
DDRB |= (1<<PB5);
TCCR1A = (1<<WGM11)|(1<<COM1A1);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10);
ICR1 = PERIOD_TRIG;
OCR1A = 2;
DDRB &= ~(1<<PB6);
PORTK |= (1<<PB6);
PCMSK0 |= 1<<PCINT6;
PCICR |= 1<<0;
}
ISR(PCINT0_vect){
if (newPing == true){
return;
}
if (((PINB & 1<<PB6)>>PB6) == 1){
start = micros();
}
else{
width = (micros() - start);
if (width <= 17400){
newPing = true;
}
}
}
The above code has been corrected as per robtillaart's suggestion.