RBE1001Lib
Rangefinder.cpp
Go to the documentation of this file.
1 #include "Rangefinder.h"
2 #include "Timer.h"
3 
4 static TaskHandle_t complexHandlerTaskUS;
5 
9 bool Rangefinder::forceFire = false;
11 
12 static long threadTimeout;
13 /*
14  * The procedure is to send a 10us pulse on the trigger line to
15  * cause the ultrasonic burst to be sent out the speaker. When
16  * that happens, the echo line will go high. When the echo from
17  * the sound returns, the echo line will go low. This pulse length
18  * is measured using the pulseIn function that returns the round-trip
19  * time in microseconds which is then converted to centimeters and
20  * returned.
21  * The timer interrupt routine will send the 10us pulse every 100ms and
22  * the sensor ISR will time from the rising edge to the falling edge.
23  * This time is saved in "roundTripTime" and used to compute the distance.
24  */
25 void onTimer(void *param) {
26  Serial.println("Starting the Ultrasonic loop thread");
27  threadTimeout = millis();
28  while (1) {
29  vTaskDelay(10); //sleep 10ms
32  else
34  }
35  Serial.println("ERROR Pid thread died!");
36 
37 }
38 
39 
41  return millis() - threadTimeout;
42 }
43 
45  // check to see if an ultrasonic timed out
46  bool run = false;
47  run = Rangefinder::getTimeoutState() > 100;
48  if (run) {
49  //Serial.println("Ultrasonic thread timeout!");
50  fire();
51  }
52 }
53 
54 void IRAM_ATTR sensorISR0() {
55  Rangefinder::list[0]->sensorISR();
56 }
57 void IRAM_ATTR sensorISR1() {
58  Rangefinder::list[1]->sensorISR();
59 }
60 void IRAM_ATTR sensorISR2() {
61  Rangefinder::list[2]->sensorISR();
62 }
63 void IRAM_ATTR sensorISR3() {
64  Rangefinder::list[3]->sensorISR();
65 }
67  threadTimeout = millis();
68  forceFire = false;
70  // round robin all of the sensors to prevent cross talk
74  digitalWrite(Rangefinder::list[Rangefinder::pingIndex]->triggerPin,
75  HIGH); // 10us pulse to start the process
76  delayMicroseconds(10);
77  digitalWrite(Rangefinder::list[Rangefinder::pingIndex]->triggerPin,
78  LOW);
79  }
80 
81 }
83  portENTER_CRITICAL(&synch);
84  if (digitalRead(echoPin)) {
85  startTime = micros();
86  } else {
87  roundTripTime = micros() - startTime;
88  forceFire = true;
89  }
90  portEXIT_CRITICAL(&synch);
91 }
92 void Rangefinder::attach(int trigger, int echo) {
93  triggerPin = trigger;
94  echoPin = echo;
95  pinMode(triggerPin, OUTPUT);
96  pinMode(echoPin, INPUT);
97  if (Rangefinder::timoutThreadStarted == false) {
98  Serial.println("Spawing rangefinder timeout thread");
100  xTaskCreatePinnedToCore(onTimer, "Rangefinder Thread", 8192, NULL, 2, // low priority timout thread
102  }
103  for (int i = 0; i < MAX_POSSIBLE_INTERRUPT_RANGEFINDER; i++) {
104  if (Rangefinder::list[i] == NULL) {
105  digitalWrite(triggerPin, LOW); // be sure to start from low
106  delayMicroseconds(2);
107  Rangefinder::list[i] = this;
109  switch (i) {
110  case 0:
111  attachInterrupt(digitalPinToInterrupt(echoPin), sensorISR0,
112  CHANGE);
113  break;
114  case 1:
115  attachInterrupt(digitalPinToInterrupt(echoPin), sensorISR1,
116  CHANGE);
117  break;
118  case 2:
119  attachInterrupt(digitalPinToInterrupt(echoPin), sensorISR2,
120  CHANGE);
121  break;
122  case 3:
123  attachInterrupt(digitalPinToInterrupt(echoPin), sensorISR3,
124  CHANGE);
125  break;
126  }
127  return;
128  }
129  }
130 
131 }
132 /*
133  * Initialize the rangefinder with the trigger pin and echo pin
134  * numbers.
135  */
137 }
144  long time;
145  portENTER_CRITICAL(&synch);
146  time=roundTripTime;
147  portEXIT_CRITICAL(&synch);
148  return time;
149 }
150 /*
151  * Get the distance from the rangefinder
152  */
154  float distance;
155  distance = (getRoundTripTimeMicroSeconds() * 0.0343) / 2.0;
156  return distance;
157 }
static int pingIndex
Definition: Rangefinder.h:43
float getDistanceCM()
get the distance of an object from the sensor in centimeters
static int getTimeoutState()
Function used by the timeout check thread to determine if this object has timed out.
Definition: Rangefinder.cpp:40
static Rangefinder * list[MAX_POSSIBLE_INTERRUPT_RANGEFINDER]
list of attached rangefinders
Definition: Rangefinder.h:80
int triggerPin
Definition: Rangefinder.h:59
void sensorISR()
The method called from the ISR indicating the echo pin changed state.
Definition: Rangefinder.cpp:82
void IRAM_ATTR sensorISR0()
Definition: Rangefinder.cpp:54
void IRAM_ATTR sensorISR3()
Definition: Rangefinder.cpp:63
static bool timoutThreadStarted
Definition: Rangefinder.h:39
long getRoundTripTimeMicroSeconds()
get the time of latest round trip in microseconds
Rangefinder objects wrap a FreeRTOS thread with pin change interrupts to read trigger/echo style ultr...
Definition: Rangefinder.h:21
void IRAM_ATTR sensorISR2()
Definition: Rangefinder.cpp:60
#define MAX_POSSIBLE_INTERRUPT_RANGEFINDER
Definition: Rangefinder.h:6
static bool forceFire
Definition: Rangefinder.h:47
void onTimer(void *param)
Definition: Rangefinder.cpp:25
volatile unsigned long startTime
Definition: Rangefinder.h:63
static void checkTimeout()
check the current state of timeout and fire if its time to do so
Definition: Rangefinder.cpp:44
static int numberOfFinders
Definition: Rangefinder.h:35
static TaskHandle_t complexHandlerTaskUS
Definition: Rangefinder.cpp:4
void attach(int trigger, int echo)
Attach 2 pins to be used as triger and echo.
Definition: Rangefinder.cpp:92
static void fire()
fire a strobe of the trig pin
Definition: Rangefinder.cpp:66
volatile unsigned long roundTripTime
Definition: Rangefinder.h:67
static long threadTimeout
Definition: Rangefinder.cpp:12
void IRAM_ATTR sensorISR1()
Definition: Rangefinder.cpp:57
portMUX_TYPE synch
Definition: Rangefinder.h:51