Kaynağa Gözat

use timer1 for counting us

subDesTagesMitExtraKaese 3 yıl önce
ebeveyn
işleme
cae7dcca08

+ 10 - 4
arduino/include/ultrasonic.hpp

@@ -8,11 +8,17 @@
 #define US_RX_1_PIN 3
 #define US_TX_0_PIN 4
 
+enum usState_t {
+  idle,
+  rxPending,
+  counting,
+  finished
+};
+
 struct usData_t {
-  uint32_t pulseStart;
-  long duration;
-  bool rxPending;
-  bool newData;
+  uint16_t pulseStart;
+  uint16_t duration;
+  enum usState_t state;
 };
 
 void us_init();

+ 1 - 1
arduino/src/main.cpp

@@ -35,7 +35,7 @@ void setup() {
 }
 
 unsigned long loopStart = 0;
-char outputBuffer[128];
+char outputBuffer[256];
 
 void loop() {
 

+ 29 - 20
arduino/src/ultrasonic.cpp

@@ -3,32 +3,41 @@
 struct usData_t usData[2];
 
 void us_0_isr() {
-  if(digitalRead(US_RX_0_PIN)) {
-    usData[0].pulseStart = micros();
-  } else if(usData[0].rxPending) {
-    usData[0].duration   = micros() - usData[0].pulseStart;
-    usData[0].rxPending = 0;
-    usData[0].newData   = 1;
+  if(digitalRead(US_RX_0_PIN) && usData[1].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].pulseStart = micros();
-  } else if(usData[1].rxPending) {
-    usData[1].duration   = micros() - usData[1].pulseStart;
-    usData[1].rxPending = 0;
-    usData[1].newData   = 1;
+  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() {
-  noInterrupts();
+  //disable pin interrupts
+  EIMSK = 0;
 
   pinMode(US_RX_0_PIN, OUTPUT);
   pinMode(US_RX_1_PIN, OUTPUT);
@@ -48,19 +57,19 @@ void us_transmit() {
   pinMode(US_RX_1_PIN, INPUT);
   pinMode(US_TX_0_PIN, INPUT);
 
-  interrupts();
+  //enable pin interrupts
+  EIMSK = _BV(INT1) | _BV(INT0);
 
-  usData[0].rxPending = 1;
-  usData[1].rxPending = 1;
+  usData[0].state = rxPending;
+  usData[1].state = rxPending;
 } 
 
 long us_get_duration(byte sensor) {
   // check if there is new sensor data
-  if(usData[sensor].newData) {
-    usData[sensor].newData = 0;
+  if(usData[sensor].state == finished) {
+    usData[sensor].state = idle;
     return usData[sensor].duration;
   } else {
-    return usData[sensor].duration;
-    //return -1;
+    return -(F_CPU / 1000000);
   }
 }

+ 2 - 2
raspberry-pi/connection.py

@@ -93,8 +93,8 @@ class ArduinoSlave(SerialConnection):
 
   def getAcusticRTTs(self): # in microseconds
     return [
-      int(self.sensorData[0]),
-      int(self.sensorData[1])
+      int(self.sensorData[0]) / 16,
+      int(self.sensorData[1]) / 16
     ]
 
   def getMagneticField(self): # in mT