From 50b96f75442b1d10aaca4b2cf47a328d416fecec Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Tue, 16 Jul 2024 21:18:48 +0100 Subject: [PATCH] Add buzzer functionality & ability to toggle buzzer via button --- Boards.h | 15 +++++++++++++++ Buzzer.h | 38 ++++++++++++++++++++++++++++++++++++++ Config.h | 8 ++++++++ Input.h | 6 +++--- Radio.h | 7 +++++++ Utilities.h | 4 ++++ freeNode_Firmware.ino | 37 ++++++++++++++++++------------------- 7 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 Buzzer.h diff --git a/Boards.h b/Boards.h index 137d6be..2cedcf1 100644 --- a/Boards.h +++ b/Boards.h @@ -634,6 +634,21 @@ #define BLE_MANUFACTURER "RAK Wireless" #define BLE_MODEL "RAK4640" + #define HAS_BUZZER true + #define PIN_BUZZER WB_IO2 + + // todo, I would much rather these be in Buzzer.h + #define RX_LO_TONE 400 + #define RX_HI_TONE 500 + #define TX_LO_TONE 450 + #define TX_HI_TONE 550 + #define MAX_BUZZER_DELAY 100 + + #define HAS_BUZZER_CTRL true + + #define HAS_INPUT false + #define PIN_BUTTON WB_SW1 + #define INTERFACE_COUNT 1 // first interface in list is the primary diff --git a/Buzzer.h b/Buzzer.h new file mode 100644 index 0000000..edd87a6 --- /dev/null +++ b/Buzzer.h @@ -0,0 +1,38 @@ +#ifndef BUZZER_H + #define BUZZER_H + + extern bool buzzer_enabled; + extern unsigned long last_tone_toggle; + extern uint16_t buzzer_delay; + extern uint16_t last_buzzer_tone; + + void update_buzzer_tone(uint16_t hi_tone, uint16_t lo_tone) { + if (buzzer_enabled) { + if (millis() - last_tone_toggle >= buzzer_delay) { + if (last_buzzer_tone == RX_HI_TONE) { + tone(PIN_BUZZER, RX_LO_TONE); + last_buzzer_tone = RX_LO_TONE; + } else { + tone(PIN_BUZZER, RX_HI_TONE); + last_buzzer_tone = RX_HI_TONE; + } + buzzer_delay = ::random(MAX_BUZZER_DELAY); + last_tone_toggle = millis(); + } + } + } + + void update_buzzer_notone() { + if (buzzer_enabled) { + if (millis() - last_tone_toggle >= buzzer_delay) { + noTone(PIN_BUZZER); + digitalWrite(PIN_BUZZER, LOW); + } + } + } + + void toggle_buzzer_enable() { + buzzer_enabled = !buzzer_enabled; + update_buzzer_notone(); + } +#endif diff --git a/Config.h b/Config.h index aa862ba..cef991f 100644 --- a/Config.h +++ b/Config.h @@ -133,4 +133,12 @@ RadioInterface* selected_radio; RadioInterface* interface_obj[INTERFACE_COUNT]; RadioInterface* interface_obj_sorted[INTERFACE_COUNT]; + + #if HAS_BUZZER + // Buzzer + bool buzzer_enabled = true; + unsigned long last_tone_toggle = 0; + uint16_t buzzer_delay = 0; + uint16_t last_buzzer_tone = 0; + #endif #endif diff --git a/Input.h b/Input.h index 996a09c..c9e6f03 100644 --- a/Input.h +++ b/Input.h @@ -15,12 +15,12 @@ #ifndef INPUT_H #define INPUT_H - - #define PIN_BUTTON pin_btn_usr1 #define PRESSED LOW #define RELEASED HIGH + #define BUTTON_MIN_DURATION 50 + #define EVENT_ALL 0x00 #define EVENT_CLICKS 0x01 #define EVENT_BUTTON_DOWN 0x11 @@ -92,4 +92,4 @@ } } -#endif \ No newline at end of file +#endif diff --git a/Radio.h b/Radio.h index 13bb0da..495cd1f 100644 --- a/Radio.h +++ b/Radio.h @@ -59,6 +59,10 @@ void led_indicate_airtime_lock(); extern portMUX_TYPE update_lock; #endif +#if HAS_BUZZER +extern void update_buzzer_tone(uint16_t, uint16_t); +#endif + class RadioInterface : public Stream { public: // todo: in the future define _spiModem and _spiSettings from here for inheritence by child classes @@ -237,6 +241,9 @@ public: _last_dcd = _last_status_update; _dcd_led = true; _dcd = true; + #if HAS_BUZZER + update_buzzer_tone(RX_HI_TONE, RX_LO_TONE); + #endif } } } else { diff --git a/Utilities.h b/Utilities.h index 99e051a..4f3dcd7 100644 --- a/Utilities.h +++ b/Utilities.h @@ -58,6 +58,10 @@ uint8_t eeprom_read(uint32_t mapped_addr); #include "Input.h" #endif +#if HAS_BUZZER + #include "Buzzer.h" +#endif + #if MCU_VARIANT == MCU_ESP32 || MCU_VARIANT == MCU_NRF52 #include "Device.h" #endif diff --git a/freeNode_Firmware.ino b/freeNode_Firmware.ino index d9e1446..3e3f0db 100644 --- a/freeNode_Firmware.ino +++ b/freeNode_Firmware.ino @@ -87,7 +87,7 @@ void setup() { Serial.begin(serial_baudrate); - #if BOARD_MODEL != BOARD_RAK4631 && BOARD_MODEL != BOARD_RNODE_NG_22 + #if BOARD_MODEL != BOARD_FREENODE && BOARD_MODEL != BOARD_RNODE_NG_22 // Some boards need to wait until the hardware UART is set up before booting // the full firmware. In the case of the RAK4631, the line below will wait // until a serial connection is actually established with a master. Thus, it @@ -100,6 +100,10 @@ void setup() { input_init(); #endif + #if HAS_BUZZER + pinMode(PIN_BUZZER, OUTPUT); + #endif + #if HAS_NP == false pinMode(pin_led_rx, OUTPUT); pinMode(pin_led_tx, OUTPUT); @@ -465,6 +469,9 @@ void flushQueue(RadioInterface* radio) { uint8_t data_byte; while (!fifo16_isempty(&packet_starts[index])) { + #if HAS_BUZZER + update_buzzer_tone(TX_HI_TONE, TX_LO_TONE); + #endif uint16_t start = fifo16_pop(&packet_starts[index]); uint16_t length = fifo16_pop(&packet_lengths[index]); @@ -1153,7 +1160,6 @@ void loop() { } } - // If at least one radio is online then we can continue if (ready) { if (packet_ready) { @@ -1274,6 +1280,10 @@ void loop() { #if HAS_INPUT input_read(); #endif + + #if HAS_BUZZER + update_buzzer_notone(); + #endif } void process_serial() { @@ -1281,26 +1291,15 @@ void process_serial() { if (!fifo_isempty(&serialFIFO)) serial_poll(); } -void sleep_now() { - #if HAS_SLEEP == true - #if BOARD_MODEL == BOARD_RNODE_NG_22 - display_intensity = 0; - update_display(true); - #endif - #if PIN_DISP_SLEEP >= 0 - pinMode(PIN_DISP_SLEEP, OUTPUT); - digitalWrite(PIN_DISP_SLEEP, DISP_SLEEP_LEVEL); - #endif - esp_sleep_enable_ext0_wakeup(PIN_WAKEUP, WAKEUP_LEVEL); - esp_deep_sleep_start(); - #endif -} - +#if HAS_INPUT void button_event(uint8_t event, unsigned long duration) { - if (duration > 2000) { - sleep_now(); + if (duration > BUTTON_MIN_DURATION) { + #if HAS_BUZZER_CTRL + toggle_buzzer_enable(); + #endif } } +#endif void poll_buffers() { process_serial();