ultrasonic.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "ultrasonic.hpp"
  2. struct usData_t usData[2];
  3. void us_0_isr() {
  4. if(digitalRead(US_RX_0_PIN) && usData[0].state == rxPending) {
  5. usData[0].pulseStart = TCNT1;
  6. usData[0].state = counting;
  7. } else if(usData[0].state == counting) {
  8. usData[0].duration = TCNT1 - usData[0].pulseStart;
  9. usData[0].state = finished;
  10. }
  11. }
  12. void us_1_isr() {
  13. if(digitalRead(US_RX_1_PIN) && usData[1].state == rxPending) {
  14. usData[1].pulseStart = TCNT1;
  15. usData[1].state = counting;
  16. } else if(usData[1].state == counting) {
  17. usData[1].duration = TCNT1 - usData[1].pulseStart;
  18. usData[1].state = finished;
  19. }
  20. }
  21. void us_init() {
  22. attachInterrupt(digitalPinToInterrupt(US_RX_0_PIN), us_0_isr, CHANGE);
  23. attachInterrupt(digitalPinToInterrupt(US_RX_1_PIN), us_1_isr, CHANGE);
  24. //timer 1 is used as an accurate timer for measuring the TOF pulses
  25. //1:1 prescaler for timer 1
  26. TCCR1A = 0;
  27. TCCR1B = _BV(CS10);
  28. //timer 1 now runs with 16MHz, therefore overflows every (2^16 / 16MHz) = 4096 us
  29. }
  30. void us_transmit() {
  31. //disable pin interrupts
  32. EIMSK = 0;
  33. //set pin 2, 3 and 4 to output
  34. DDRD |= 0b00011100;
  35. PORTD &= 0b11100011;
  36. delayMicroseconds(2);
  37. //pull pin 2, 3 and 4 to 5V
  38. //doing this seems to lead to power supply issues and the serial interface stopps working
  39. //further testing needed!
  40. PORTD = (PORTD & 0b11100011) | 0b00000100;
  41. delayMicroseconds(5);
  42. PORTD = (PORTD & 0b11100011) | 0b00001000;
  43. delayMicroseconds(5);
  44. //pull pin 2 and 3 to GND
  45. PORTD &= 0b11110011;
  46. //set pin 2 and 3 back to input
  47. DDRD &= 0b11110011;
  48. delayMicroseconds(5);
  49. //enable pin interrupts
  50. EIMSK = _BV(INT1) | _BV(INT0);
  51. usData[0].state = rxPending;
  52. usData[1].state = rxPending;
  53. PORTD = (PORTD & 0b11100011) | 0b00010000;
  54. delayMicroseconds(5);
  55. //pull pin 4 to GND
  56. PORTD &= 0b11101111;
  57. //set pin 4 back to input
  58. DDRD &= 0b11101111;
  59. }
  60. long us_get_duration(byte sensor) {
  61. // check if there is new sensor data
  62. if(usData[sensor].state == finished) {
  63. usData[sensor].state = idle;
  64. return usData[sensor].duration;
  65. } else {
  66. return -(F_CPU / 1000000);
  67. }
  68. }