Skip to content

Commit 54823b1

Browse files
committed
add SR04 ultrasonic sensor
1 parent 7f2dc18 commit 54823b1

File tree

5 files changed

+105
-1
lines changed

5 files changed

+105
-1
lines changed

src/madflight.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ void madflight_setup() {
188188
rdr.config.gizmo = (Cfg::rdr_gizmo_enum)cfg.rdr_gizmo; //the gizmo to use
189189
rdr.config.ser_bus_id = cfg.rdr_ser_bus; //serial bus
190190
rdr.config.baud = cfg.rdr_baud; //baud rate
191+
rdr.config.pin_trig = cfg.pin_rdr_trig;
192+
rdr.config.pin_echo = cfg.pin_rdr_echo;
191193
rdr.setup();
192194

193195
// GPS

src/madflight/cfg/cfg.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,13 @@ SOFTWARE.
229229
MF_PARAM( rcl_deadband, 0, int32_t, 'i') \
230230
\
231231
/*RDR - Radar*/ \
232-
MF_PARAM( rdr_gizmo, 0, int32_t, 'e', mf_NONE,mf_LD2411S,mf_LD2413,mf_USD1) \
232+
MF_PARAM( rdr_gizmo, 0, int32_t, 'e', mf_NONE,mf_LD2411S,mf_LD2413,mf_USD1,mf_SR04) \
233233
MF_PARAM( rdr_ser_bus, -1, int32_t, 'i') \
234234
MF_PARAM( rdr_baud, 0, int32_t, 'i') \
235+
\
236+
/*v2.0.1 additions */ \
237+
MF_PARAM( pin_rdr_trig, -1, int32_t, 'p') \
238+
MF_PARAM( pin_rdr_echo, -1, int32_t, 'p') \
235239
//end MF_PARAM_LIST
236240

237241

src/madflight/rdr/RdrGizmoSR04.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//https://uglyduck.vajn.icu/ep/archive/2014/01/Making_a_better_HC_SR04_Echo_Locator.html
2+
3+
// HC-SR04 driver (single instance only)
4+
// range: 2-6m (depending on variant)
5+
// reporting rate: 100ms
6+
// trigger pin high pulse >= 8us --> echo high pulse
7+
8+
#pragma once
9+
10+
#include "rdr.h"
11+
#include "../hal/hal.h"
12+
#include <Arduino.h> //micros, pinMode, digitalWrite, attachInterrupt
13+
14+
#define SR04_TRIG_US 100 // minimum length of trigger pulse
15+
#define SR04_TIMEOUT_US 60000 // echo timeout 60 ms ~= 10 meter, this is also the appoximate sample rate
16+
17+
static uint8_t _RdrGizmoSR04_irq_pin_echo = 0;
18+
static volatile uint32_t _RdrGizmoSR04_irq_echo_ts1 = 0;
19+
static volatile uint32_t _RdrGizmoSR04_irq_echo_ts2 = 0;
20+
21+
static void _RdrGizmoSR04_irq() {
22+
if(digitalRead(_RdrGizmoSR04_irq_pin_echo) == HIGH) {
23+
_RdrGizmoSR04_irq_echo_ts1 = micros();
24+
}else{
25+
_RdrGizmoSR04_irq_echo_ts2 = micros();
26+
}
27+
}
28+
29+
30+
class RdrGizmoSR04: public RdrGizmo {
31+
protected:
32+
enum class state_enum { TRIG_START, TRIG_END, ECHO_WAIT, INTERVAL_WAIT};
33+
state_enum state = state_enum::TRIG_START;
34+
uint8_t pin_trig = 0;
35+
uint32_t state_ts = 0;
36+
int *dist = nullptr;
37+
38+
RdrGizmoSR04() {} //private constructor
39+
40+
public:
41+
static RdrGizmoSR04* create(int* dist, int pin_trig, int pin_echo) {
42+
if(!dist || pin_trig < 0 || pin_echo < 0) return nullptr;
43+
pinMode(pin_trig, OUTPUT);
44+
digitalWrite(pin_trig, LOW);
45+
pinMode(pin_echo, INPUT);
46+
attachInterrupt(digitalPinToInterrupt(pin_echo), _RdrGizmoSR04_irq, CHANGE);
47+
48+
//setup gizmo
49+
auto gizmo = new RdrGizmoSR04();
50+
_RdrGizmoSR04_irq_pin_echo = pin_echo;
51+
gizmo->pin_trig = pin_trig;
52+
gizmo->dist = dist;
53+
return gizmo;
54+
}
55+
56+
bool update() override {
57+
switch(state) {
58+
case state_enum::TRIG_START:
59+
//note: send trigger pulse regardless of echo pin state, is this wise???
60+
digitalWrite(pin_trig, HIGH);
61+
state_ts = micros();
62+
state = state_enum::TRIG_END;
63+
break;
64+
case state_enum::TRIG_END:
65+
if(micros() - state_ts > SR04_TRIG_US) {
66+
_RdrGizmoSR04_irq_echo_ts1 = 0;
67+
_RdrGizmoSR04_irq_echo_ts2 = 0;
68+
digitalWrite(pin_trig, LOW);
69+
state_ts = micros();
70+
state = state_enum::ECHO_WAIT;
71+
}
72+
break;
73+
case state_enum::ECHO_WAIT:
74+
if(_RdrGizmoSR04_irq_echo_ts2 && _RdrGizmoSR04_irq_echo_ts1) {
75+
//got echo
76+
*dist = (_RdrGizmoSR04_irq_echo_ts2 - _RdrGizmoSR04_irq_echo_ts1) * 171 / 1000; // integer math echo_us -> dist_mm with speed of sound 342 m/s
77+
state = state_enum::INTERVAL_WAIT;
78+
//Serial.printf("ECHO %d\n",*dist);
79+
return true;
80+
}
81+
//fall thru
82+
case state_enum::INTERVAL_WAIT:
83+
if(micros() - state_ts > SR04_TIMEOUT_US) {
84+
//if(state == state_enum::ECHO_WAIT) Serial.printf("SR04 TIMEOUT\n");
85+
state = state_enum::TRIG_START;
86+
}
87+
break;
88+
}
89+
return false;
90+
}
91+
92+
};

src/madflight/rdr/rdr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SOFTWARE.
3131
#include "RdrGizmoLD2411S.h"
3232
#include "RdrGizmoLD2413.h"
3333
#include "RdrGizmoUSD1.h"
34+
#include "RdrGizmoSR04.h"
3435

3536
//create global module instance
3637
Rdr rdr;
@@ -53,6 +54,9 @@ int Rdr::setup() {
5354
case Cfg::rdr_gizmo_enum::mf_USD1 :
5455
gizmo = RdrGizmoUSD1::create(&dist, config.ser_bus_id, config.baud);
5556
break;
57+
case Cfg::rdr_gizmo_enum::mf_SR04 :
58+
gizmo = RdrGizmoSR04::create(&dist, config.pin_trig, config.pin_echo);
59+
break;
5660
}
5761

5862
//check gizmo

src/madflight/rdr/rdr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct RdrConfig {
3636
Cfg::rdr_gizmo_enum gizmo = Cfg::rdr_gizmo_enum::mf_NONE;
3737
int ser_bus_id = -1; //Serial bus id
3838
int baud = 0; //baud rate. 0=autobaud
39+
int pin_trig = -1; //trigger pulse output pin
40+
int pin_echo = -1; //echo pulse input pin
3941
};
4042

4143
class RdrGizmo {

0 commit comments

Comments
 (0)