#include "ultrasonic.hpp" struct usData_t usData[2]; void us_0_isr() { if(digitalRead(US_RX_0_PIN) && usData[0].state == rxPending) { usData[0].pulseStart = TCNT1; usData[0].state = counting; } else if(usData[0].state == counting) { usData[0].duration = TCNT1 - usData[0].pulseStart; usData[0].state = finished; } } void us_1_isr() { if(digitalRead(US_RX_1_PIN) && usData[1].state == rxPending) { usData[1].pulseStart = TCNT1; usData[1].state = counting; } else if(usData[1].state == counting) { usData[1].duration = TCNT1 - usData[1].pulseStart; usData[1].state = finished; } } void us_init() { attachInterrupt(digitalPinToInterrupt(US_RX_0_PIN), us_0_isr, CHANGE); attachInterrupt(digitalPinToInterrupt(US_RX_1_PIN), us_1_isr, CHANGE); //timer 1 is used as an accurate timer for measuring the TOF pulses //1:1 prescaler for timer 1 TCCR1A = 0; TCCR1B = _BV(CS10); //timer 1 now runs with 16MHz, therefore overflows every (2^16 / 16MHz) = 4096 us } void us_transmit() { //disable pin interrupts EIMSK = 0; //set pin 2, 3 and 4 to output DDRD |= 0b00011100; PORTD &= 0b11100011; delayMicroseconds(2); //pull pin 2, 3 and 4 to 5V //doing this seems to lead to power supply issues and the serial interface stopps working //further testing needed! PORTD = (PORTD & 0b11100011) | 0b00000100; delayMicroseconds(5); PORTD = (PORTD & 0b11100011) | 0b00001000; delayMicroseconds(5); //pull pin 2 and 3 to GND PORTD &= 0b11110011; //set pin 2 and 3 back to input DDRD &= 0b11110011; delayMicroseconds(5); //enable pin interrupts EIMSK = _BV(INT1) | _BV(INT0); usData[0].state = rxPending; usData[1].state = rxPending; PORTD = (PORTD & 0b11100011) | 0b00010000; delayMicroseconds(5); //pull pin 4 to GND PORTD &= 0b11101111; //set pin 4 back to input DDRD &= 0b11101111; } long us_get_duration(byte sensor) { // check if there is new sensor data if(usData[sensor].state == finished) { usData[sensor].state = idle; return usData[sensor].duration; } else { return -(F_CPU / 1000000); } }