Kevin Gilbert
/
Alarm-Example
Basic alarm using low power interrupts
main.cpp@0:d31de7b879e3, 2018-10-03 (annotated)
- Committer:
- kgilbert
- Date:
- Wed Oct 03 21:25:47 2018 +0000
- Revision:
- 0:d31de7b879e3
- Child:
- 1:aa3c38eaaeff
First pass at alarm example
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kgilbert | 0:d31de7b879e3 | 1 | #include "mbed.h" |
kgilbert | 0:d31de7b879e3 | 2 | |
kgilbert | 0:d31de7b879e3 | 3 | // Use buttons to select alarm time. Cycle through hours in an incrementing |
kgilbert | 0:d31de7b879e3 | 4 | // fashion using button1, hit select and increment through minutes. Hit |
kgilbert | 0:d31de7b879e3 | 5 | // select one more time to begin the alarm timer. |
kgilbert | 0:d31de7b879e3 | 6 | // |
kgilbert | 0:d31de7b879e3 | 7 | // The Time LEDs will blink in time with the button inputs to show the |
kgilbert | 0:d31de7b879e3 | 8 | // currently selected alarm time. Once select is hit a second time to begin |
kgilbert | 0:d31de7b879e3 | 9 | // the timer, the LEDs will blink out the configured delay in hours and |
kgilbert | 0:d31de7b879e3 | 10 | // minutes before going into a low power sleep mode. |
kgilbert | 0:d31de7b879e3 | 11 | // |
kgilbert | 0:d31de7b879e3 | 12 | // Once the alarm fires, hitting the select button will turn the alarm off |
kgilbert | 0:d31de7b879e3 | 13 | // until the next time it fires. |
kgilbert | 0:d31de7b879e3 | 14 | //__________________________________________________________________________ |
kgilbert | 0:d31de7b879e3 | 15 | // You may also use the RTC (hardware or software through the Time API) to |
kgilbert | 0:d31de7b879e3 | 16 | // set a real world time and set an alarm for a specific timestamp rather |
kgilbert | 0:d31de7b879e3 | 17 | // than on a delay. This would require manually setting the time on each |
kgilbert | 0:d31de7b879e3 | 18 | // reset however, or an internet connection to automatically collect the |
kgilbert | 0:d31de7b879e3 | 19 | // time. See Example <TODO>[HERE] for how to do that. |
kgilbert | 0:d31de7b879e3 | 20 | |
kgilbert | 0:d31de7b879e3 | 21 | // Time constants in seconds |
kgilbert | 0:d31de7b879e3 | 22 | #define HOUR 60 * 60 |
kgilbert | 0:d31de7b879e3 | 23 | #define MINUTE 60 |
kgilbert | 0:d31de7b879e3 | 24 | |
kgilbert | 0:d31de7b879e3 | 25 | // Globals |
kgilbert | 0:d31de7b879e3 | 26 | DigitalOut alarm_out(D0); |
kgilbert | 0:d31de7b879e3 | 27 | DigitalOut alarm_led(LED_RED, 1); |
kgilbert | 0:d31de7b879e3 | 28 | DigitalOut hour_led(LED_GREEN, 1); |
kgilbert | 0:d31de7b879e3 | 29 | DigitalOut min_led(LED_BLUE, 1); |
kgilbert | 0:d31de7b879e3 | 30 | |
kgilbert | 0:d31de7b879e3 | 31 | InterruptIn inc_time(BUTTON1); |
kgilbert | 0:d31de7b879e3 | 32 | InterruptIn select(BUTTON2); |
kgilbert | 0:d31de7b879e3 | 33 | |
kgilbert | 0:d31de7b879e3 | 34 | LowPowerTicker alarm_event; |
kgilbert | 0:d31de7b879e3 | 35 | |
kgilbert | 0:d31de7b879e3 | 36 | volatile uint64_t delay = 0; |
kgilbert | 0:d31de7b879e3 | 37 | volatile uint8_t hour_count = 0; |
kgilbert | 0:d31de7b879e3 | 38 | volatile uint8_t min_count = 0; |
kgilbert | 0:d31de7b879e3 | 39 | volatile uint8_t select_state = 0; |
kgilbert | 0:d31de7b879e3 | 40 | |
kgilbert | 0:d31de7b879e3 | 41 | // Timer Callbacks |
kgilbert | 0:d31de7b879e3 | 42 | void inc_select(void) { |
kgilbert | 0:d31de7b879e3 | 43 | if (select_state < 2) { |
kgilbert | 0:d31de7b879e3 | 44 | select_state++; |
kgilbert | 0:d31de7b879e3 | 45 | } else { |
kgilbert | 0:d31de7b879e3 | 46 | // Use select button to disable alarm |
kgilbert | 0:d31de7b879e3 | 47 | alarm_out = !alarm_out; |
kgilbert | 0:d31de7b879e3 | 48 | alarm_led = !alarm_led; |
kgilbert | 0:d31de7b879e3 | 49 | } |
kgilbert | 0:d31de7b879e3 | 50 | } |
kgilbert | 0:d31de7b879e3 | 51 | |
kgilbert | 0:d31de7b879e3 | 52 | void set_time_leds(void) { |
kgilbert | 0:d31de7b879e3 | 53 | if (select_state == 0) { |
kgilbert | 0:d31de7b879e3 | 54 | hour_led = !hour_led; |
kgilbert | 0:d31de7b879e3 | 55 | } else { |
kgilbert | 0:d31de7b879e3 | 56 | min_led = !min_led; |
kgilbert | 0:d31de7b879e3 | 57 | } |
kgilbert | 0:d31de7b879e3 | 58 | } |
kgilbert | 0:d31de7b879e3 | 59 | |
kgilbert | 0:d31de7b879e3 | 60 | void inc_delay(void) { |
kgilbert | 0:d31de7b879e3 | 61 | if (select_state == 0) { |
kgilbert | 0:d31de7b879e3 | 62 | delay += HOUR; |
kgilbert | 0:d31de7b879e3 | 63 | hour_count++; |
kgilbert | 0:d31de7b879e3 | 64 | hour_led = !hour_led; |
kgilbert | 0:d31de7b879e3 | 65 | } else { |
kgilbert | 0:d31de7b879e3 | 66 | delay += MINUTE; |
kgilbert | 0:d31de7b879e3 | 67 | min_count++; |
kgilbert | 0:d31de7b879e3 | 68 | min_led = !min_led; |
kgilbert | 0:d31de7b879e3 | 69 | } |
kgilbert | 0:d31de7b879e3 | 70 | } |
kgilbert | 0:d31de7b879e3 | 71 | |
kgilbert | 0:d31de7b879e3 | 72 | void trigger_alarm_out(void) { |
kgilbert | 0:d31de7b879e3 | 73 | alarm_out = 0; |
kgilbert | 0:d31de7b879e3 | 74 | alarm_led = 0; |
kgilbert | 0:d31de7b879e3 | 75 | } |
kgilbert | 0:d31de7b879e3 | 76 | |
kgilbert | 0:d31de7b879e3 | 77 | // Main thread |
kgilbert | 0:d31de7b879e3 | 78 | int main() { |
kgilbert | 0:d31de7b879e3 | 79 | // Configure interrupt-in pins (button controls) |
kgilbert | 0:d31de7b879e3 | 80 | select.rise(inc_select); |
kgilbert | 0:d31de7b879e3 | 81 | inc_time.fall(set_time_leds); |
kgilbert | 0:d31de7b879e3 | 82 | inc_time.rise(inc_delay); |
kgilbert | 0:d31de7b879e3 | 83 | |
kgilbert | 0:d31de7b879e3 | 84 | // Sleep while waiting for user input to set the desired delay |
kgilbert | 0:d31de7b879e3 | 85 | while (select_state < 2) { __WFI(); } |
kgilbert | 0:d31de7b879e3 | 86 | |
kgilbert | 0:d31de7b879e3 | 87 | // Once the delay has been input, blink back the configured hours and |
kgilbert | 0:d31de7b879e3 | 88 | // minutes selected |
kgilbert | 0:d31de7b879e3 | 89 | for (uint8_t i = 0; i < hour_count * 2; i++) { |
kgilbert | 0:d31de7b879e3 | 90 | hour_led = !hour_led; |
kgilbert | 0:d31de7b879e3 | 91 | wait(0.25f); |
kgilbert | 0:d31de7b879e3 | 92 | } |
kgilbert | 0:d31de7b879e3 | 93 | |
kgilbert | 0:d31de7b879e3 | 94 | for (uint8_t i = 0; i < min_count * 2; i++) { |
kgilbert | 0:d31de7b879e3 | 95 | min_led = !min_led; |
kgilbert | 0:d31de7b879e3 | 96 | wait(0.25f); |
kgilbert | 0:d31de7b879e3 | 97 | } |
kgilbert | 0:d31de7b879e3 | 98 | |
kgilbert | 0:d31de7b879e3 | 99 | // Attach the low power ticker with the configured alarm delay |
kgilbert | 0:d31de7b879e3 | 100 | alarm_event.attach(&trigger_alarm_out, delay); |
kgilbert | 0:d31de7b879e3 | 101 | |
kgilbert | 0:d31de7b879e3 | 102 | // Sleep while waiting for the lowpower ticker interrupt to fire the alarm |
kgilbert | 0:d31de7b879e3 | 103 | while (true) { __WFI(); } |
kgilbert | 0:d31de7b879e3 | 104 | } |