1
+ #include < Arduino.h>
2
+
1
3
#include < avr/sleep.h>
2
4
#include < TimerOne.h>
3
5
#include < MsTimer2.h>
@@ -13,16 +15,15 @@ COBD obd;
13
15
volatile state_t state;
14
16
volatile speed_t target_read_speed;
15
17
16
- float modifier;
17
- volatile bool should_display_imperial;
18
- volatile bool should_display_metric;
18
+ volatile float modifier;
19
+ volatile int unit_select;
19
20
20
21
void setup () {
21
22
state = STATE_DISCONNECTED;
22
23
target_read_speed = 0 ;
23
24
24
- pinMode (PIN_USE_IMPERIAL , INPUT);
25
- pinMode (PIN_USE_METRIC , INPUT);
25
+ pinMode (PIN_UNIT_SELECT , INPUT);
26
+ pinMode (PIN_SLEEP_ENABLE , INPUT);
26
27
27
28
// Read speed modifier (1.0 keeps raw speed read from OBD)
28
29
// OBD speed can be a bit different from real life speed, so play with
@@ -39,8 +40,9 @@ void setup() {
39
40
setup_timers ();
40
41
setup_interrupts ();
41
42
42
- // Initialize display unit switch interrupt
43
- isr_read_display_unit ();
43
+ // Initialize display unit switch and sleep mode interrupts
44
+ isr_check_display_unit ();
45
+ isr_check_sleep_mode ();
44
46
}
45
47
46
48
void setup_timers () {
@@ -55,9 +57,9 @@ void setup_timers() {
55
57
}
56
58
57
59
void setup_interrupts () {
58
- // When switching kph/OFF/mph, update the switch states in memory
59
- attachInterrupt (digitalPinToInterrupt (PIN_USE_IMPERIAL ), isr_read_display_unit , CHANGE);
60
- attachInterrupt (digitalPinToInterrupt (PIN_USE_METRIC ), isr_read_display_unit , CHANGE);
60
+ // Update the switch states in memory when they're changed
61
+ attachInterrupt (digitalPinToInterrupt (PIN_UNIT_SELECT ), isr_check_display_unit , CHANGE);
62
+ attachInterrupt (digitalPinToInterrupt (PIN_SLEEP_ENABLE ), isr_check_sleep_mode , CHANGE);
61
63
}
62
64
63
65
void setup_display () {
@@ -118,26 +120,25 @@ void setup_obd_connection() {
118
120
}
119
121
120
122
void loop () {
121
- // In the main loop, we'll read the car's speed.
122
- // It's easier to do that here, because the UART connection uses interrupts
123
-
124
123
noInterrupts ();
125
124
state_t loc_state = state;
126
125
interrupts ();
127
-
128
- if (loc_state == STATE_DISCONNECTED) {
129
- // If we got disconnected (or on first loop), try reconnecting
130
- setup_obd_connection ();
131
- }
132
126
133
- if (loc_state == STATE_SLEEPING) {
134
- // If we switched the switch to OFF, time for sleepies
135
- enter_sleep_mode ();
136
- return ;
127
+ // Yay, finite state machine!
128
+ switch (loc_state) {
129
+ case STATE_DISCONNECTED:
130
+ // If we got disconnected (or on first loop), try reconnecting
131
+ setup_obd_connection ();
132
+ break ;
133
+ case STATE_SLEEPING:
134
+ // If we switched the switch to OFF, time for sleepies
135
+ enter_sleep_mode ();
136
+ break ;
137
+ case STATE_CONNECTED:
138
+ // We should be connected. PROBE!
139
+ probe_current_speed ();
140
+ break ;
137
141
}
138
-
139
- // We should be connected. PROBE!
140
- probe_current_speed ();
141
142
}
142
143
143
144
// INTERRUPTS
@@ -147,7 +148,7 @@ void isr_display() {
147
148
static speed_t curr_disp_speed = 0 ;
148
149
149
150
if (state != STATE_CONNECTED) {
150
- return ;
151
+ return ;
151
152
}
152
153
153
154
// Make copy of target speed
@@ -184,27 +185,31 @@ void isr_refresh_display() {
184
185
sevseg.refreshDisplay ();
185
186
}
186
187
187
- void isr_read_display_unit () {
188
+ void isr_check_display_unit () {
189
+ // Read unit mode from switch
190
+ unit_select = digitalRead (PIN_UNIT_SELECT);
191
+ }
192
+
193
+ void isr_check_sleep_mode () {
194
+ // Check if we've enabled the sleep switch
195
+ int sleep_enable = digitalRead (PIN_SLEEP_ENABLE);
196
+
188
197
// If we were sleeping, wake up
189
- if (state == STATE_SLEEPING) {
198
+ if (state == STATE_SLEEPING && !sleep_enable ) {
190
199
leave_sleep_mode ();
191
200
state = STATE_DISCONNECTED;
192
201
}
193
202
194
- // Read display mode from switch
195
- should_display_imperial = digitalRead (PIN_USE_IMPERIAL);
196
- should_display_metric = digitalRead (PIN_USE_METRIC);
197
-
198
- if (!should_display_imperial && !should_display_metric) {
203
+ // Go to sleep
204
+ if (sleep_enable) {
199
205
state = STATE_SLEEPING;
200
- sevseg.blank ();
201
206
}
202
207
}
203
208
204
209
speed_t adjust_speed (speed_t speed) {
205
210
// Adjust read speed using modifier (set via potentiometer) and take
206
211
// unit into account
207
- if (should_display_imperial ) {
212
+ if (unit_select == UNIT_MPH ) {
208
213
// Convert from km/h to mph
209
214
return round (modifier * (float )speed * 0.621371 );
210
215
}
@@ -262,6 +267,8 @@ int analog_read_avg(const int sensor_pin, const int nb_samples, const long time_
262
267
}
263
268
264
269
void enter_sleep_mode () {
270
+ sevseg.blank ();
271
+
265
272
#ifndef MODE_SIMULATION
266
273
obd.enterLowPowerMode ();
267
274
#endif
0 commit comments