From f083233b0932ff53bf057ec7fbd9135603642a30 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:09:56 +0100 Subject: [PATCH] Support trailing silence in buzzer tune Support trailing silence in buzzer tune (#10694) --- CHANGELOG.md | 1 + RELEASENOTES.md | 5 ++- tasmota/xdrv_24_buzzer.ino | 91 ++++++++++++++++---------------------- 3 files changed, 41 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4f18abeb..beceb6d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Commands ``ChannelRemap``, ``MultiPWM``, ``AlexaCTRange``, ``PowerOnFade``, ``PWMCT``, ``WhiteBlend``, ``VirtualCT`` as synonyms for ``SetOption37, 68, 82, 91, 92, 105 and 106`` respectively - Commands ``ZbNameKey``, ``ZbDeviceTopic``, ``ZbNoPrefix``, ``ZbEndpointSuffix``, ``ZbNoAutoBind``, ``ZbNameTopic`` as synonyms for ``SetOption83, 89, 100, 101, 110 and 112`` respectively - Support for ESP32 ``Module 5`` Wireless Tag Eth01 (#9496) +- Support trailing silence in buzzer tune (#10694) ### Changed - Maximum chars in ``AddLog_P`` logging restored from 128 to 700 (MAX_LOGSZ) to solve broken error messages diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7e528d190..3f0c0a46f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -85,11 +85,12 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for 24/26/32/34 bit RFID Wiegand interface (D0/D1) by Sigurd Leuther [#3647](https://github.com/arendst/Tasmota/issues/3647) - Support for SM2135 current selection using GPIO ``SM2135 DAT`` index [#10634](https://github.com/arendst/Tasmota/issues/10634) - Support for Sugar Valley NeoPool Controller by Norbert Richter [#10637](https://github.com/arendst/Tasmota/issues/10637) -- Support rotary encoder on Shelly Dimmer [#10407](https://github.com/arendst/Tasmota/issues/10407#issuecomment-756240920) -- Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) - Support for ESP32 ``Module 3`` Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630) - Support for ESP32 ``Module 5`` Wireless Tag Eth01 [#9496](https://github.com/arendst/Tasmota/issues/9496) - Support for ESP32 ``Module 7`` M5stack core2 16MB binary tasmota32-core2.bin [#10635](https://github.com/arendst/Tasmota/issues/10635) +- Support rotary encoder on Shelly Dimmer [#10407](https://github.com/arendst/Tasmota/issues/10407#issuecomment-756240920) +- Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) +- Support trailing silence in buzzer tune [#10694](https://github.com/arendst/Tasmota/issues/10694) - Rule trigger string comparisons for EndsWith ``$>``, StartsWith ``$<`` and Contains ``$|`` [#10538](https://github.com/arendst/Tasmota/issues/10538) - SPI display driver SSD1331 Color oled by Jeroen Vermeulen [#10376](https://github.com/arendst/Tasmota/issues/10376) - Compile time option ``USE_MQTT_TLS_DROP_OLD_FINGERPRINT`` to drop old (less secure) TLS fingerprint diff --git a/tasmota/xdrv_24_buzzer.ino b/tasmota/xdrv_24_buzzer.ino index 868c1d84a..973799095 100644 --- a/tasmota/xdrv_24_buzzer.ino +++ b/tasmota/xdrv_24_buzzer.ino @@ -32,44 +32,39 @@ struct BUZZER { uint8_t inverted = 0; // Buzzer inverted flag (1 = (0 = On, 1 = Off)) uint8_t count = 0; // Number of buzzes uint8_t mode = 0; // Buzzer mode (0 = regular, 1 = infinite, 2 = follow LED) - uint8_t freq_mode = 0; // Output mode (0 = regular, 1 = using frequency output) uint8_t set[2]; uint8_t duration; uint8_t state = 0; + uint8_t tune_size = 0; + uint8_t size = 0; } Buzzer; /*********************************************************************************************/ -void BuzzerSet(uint8_t state) -{ +void BuzzerSet(uint32_t state) { if (Buzzer.inverted) { state = !state; } - if (Buzzer.freq_mode == 1) { + if (Settings.flag4.buzzer_freq_mode) { // SetOption111 - Enable frequency output mode for buzzer static uint8_t last_state = 0; if (last_state != state) { - if (state) { - analogWrite(Pin(GPIO_BUZZER, 0), Settings.pwm_range / 2); // set 50% duty cycle for frequency output - } - else { - analogWrite(Pin(GPIO_BUZZER, 0), 0); // set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way - } + // Set 50% duty cycle for frequency output + // Set 0% (or 100% for inverted PWM) duty cycle which turns off frequency output either way + analogWrite(Pin(GPIO_BUZZER), (state) ? Settings.pwm_range / 2 : 0); // set duty cycle for frequency output last_state = state; } + } else { + DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off } - else { - DigitalWrite(GPIO_BUZZER, 0, state); // Buzzer On/Off - } - } //void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0, uint32_t mode = 0); -void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32_t mode) -{ - Buzzer.set[0] = off; // off duration in 100 mSec steps - Buzzer.set[1] = on; // on duration in 100 mSec steps - Buzzer.duration = 1; // Start buzzer on first step +void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32_t mode) { + Buzzer.set[0] = off; // Off duration in 100 mSec steps + Buzzer.set[1] = on; // On duration in 100 mSec steps + Buzzer.duration = 1; // Start buzzer on first step + Buzzer.tune_size = 0; Buzzer.tune_reload = 0; Buzzer.mode = mode; @@ -78,65 +73,55 @@ void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune, uint32 uint32_t tune2 = tune; for (uint32_t i = 0; i < 32; i++) { if (!(tune2 & 0x80000000)) { - tune2 <<= 1; // Skip leading silence + tune2 <<= 1; // Skip leading silence } else { - Buzzer.tune_reload <<= 1; // Add swapped tune + Buzzer.tune_size++; // Allow trailing silence + Buzzer.tune_reload <<= 1; // Add swapped tune Buzzer.tune_reload |= tune1 & 1; tune1 >>= 1; } } + Buzzer.size = Buzzer.tune_size; Buzzer.tune = Buzzer.tune_reload; } - Buzzer.count = count * 2; // Start buzzer + Buzzer.count = count * 2; // Start buzzer - // We can use PWM mode for buzzer output if enabled. - if (Settings.flag4.buzzer_freq_mode) { // SetOption111 - Enable frequency output mode for buzzer - Buzzer.freq_mode = 1; - } - else { - Buzzer.freq_mode = 0; - } - - AddLog(LOG_LEVEL_DEBUG, PSTR("BUZ: %d(%d),%d,%d,0x%08X(0x%08X),%d"), count, Buzzer.count, on, off, tune, Buzzer.tune, Buzzer.freq_mode); + AddLog(LOG_LEVEL_DEBUG, PSTR("BUZ: Count %d(%d), Time %d/%d, Tune 0x%08X(0x%08X), Size %d, Mode %d"), + count, Buzzer.count, on, off, tune, Buzzer.tune, Buzzer.tune_size, Settings.flag4.buzzer_freq_mode); Buzzer.enable = (Buzzer.count > 0); if (Buzzer.enable) { if (Settings.sleep > PWM_MAX_SLEEP) { - TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate + TasmotaGlobal.sleep = PWM_MAX_SLEEP; // Set a maxumum value of 10 milliseconds to ensure that buzzer periods are a bit more accurate } else { - TasmotaGlobal.sleep = Settings.sleep; // or keep the current sleep if it's lower than 10 + TasmotaGlobal.sleep = Settings.sleep; // Or keep the current sleep if it's lower than 10 } - } - else { - TasmotaGlobal.sleep = Settings.sleep; // restore original sleep + } else { + TasmotaGlobal.sleep = Settings.sleep; // Restore original sleep BuzzerSet(0); } } -void BuzzerSetStateToLed(uint32_t state) -{ +void BuzzerSetStateToLed(uint32_t state) { if (Buzzer.enable && (2 == Buzzer.mode)) { Buzzer.state = (state != 0); BuzzerSet(Buzzer.state); } } -void BuzzerBeep(uint32_t count) -{ +void BuzzerBeep(uint32_t count) { BuzzerBeep(count, 1, 1, 0, 0); } -void BuzzerEnabledBeep(uint32_t count, uint32_t duration) -{ - if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available +void BuzzerEnabledBeep(uint32_t count, uint32_t duration) { + if (Settings.flag3.buzzer_enable) { // SetOption67 - Enable buzzer when available BuzzerBeep(count, duration, 1, 0, 0); } } /*********************************************************************************************/ -bool BuzzerPinState(void) -{ +bool BuzzerPinState(void) { if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) { Buzzer.inverted = 1; XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER)); @@ -145,8 +130,7 @@ bool BuzzerPinState(void) return false; } -void BuzzerInit(void) -{ +void BuzzerInit(void) { if (PinUsed(GPIO_BUZZER)) { pinMode(Pin(GPIO_BUZZER), OUTPUT); BuzzerSet(0); @@ -155,17 +139,18 @@ void BuzzerInit(void) } } -void BuzzerEvery100mSec(void) -{ +void BuzzerEvery100mSec(void) { if (Buzzer.enable && (Buzzer.mode != 2)) { if (Buzzer.count) { if (Buzzer.duration) { Buzzer.duration--; if (!Buzzer.duration) { - if (Buzzer.tune) { + if (Buzzer.size) { + Buzzer.size--; Buzzer.state = Buzzer.tune & 1; Buzzer.tune >>= 1; } else { + Buzzer.size = Buzzer.tune_size; Buzzer.tune = Buzzer.tune_reload; Buzzer.count -= (Buzzer.tune_reload) ? 2 : 1; Buzzer.state = Buzzer.count & 1; @@ -193,8 +178,7 @@ const char kBuzzerCommands[] PROGMEM = "|" // No prefix void (* const BuzzerCommand[])(void) PROGMEM = { &CmndBuzzer }; -void CmndBuzzer(void) -{ +void CmndBuzzer(void) { // Buzzer ,,, // All parameters are optional // @@ -233,8 +217,7 @@ void CmndBuzzer(void) * Interface \*********************************************************************************************/ -bool Xdrv24(uint8_t function) -{ +bool Xdrv24(uint8_t function) { bool result = false; if (Buzzer.active) {