mirror of https://github.com/arendst/Tasmota.git
Add command Buzzer
Add command Buzzer with optional parameters <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps> enabled when a buzzer is configured (#5988)
This commit is contained in:
parent
9152aad6f2
commit
23ec00a452
|
@ -5,6 +5,7 @@
|
|||
* See DEBUG_CORE_LOG example in sonoff.ino and DEBUG_DRIVER_LOG example in xdrv_09_timers.ino
|
||||
* Add support for Solax X1 inverter by Pablo Zerón
|
||||
* Add ZigBee support phase 1 - low level MQTT ZNP messages for CC2530 devices
|
||||
* Add command Buzzer with optional parameters <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps> enabled when a buzzer is configured (#5988)
|
||||
*
|
||||
* 6.6.0.3 20190725
|
||||
* Change filename of configuration backup from using FriendlyName1 to Hostname solving diacritic issues (#2422)
|
||||
|
|
|
@ -304,6 +304,7 @@
|
|||
// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code)
|
||||
|
||||
// -- Optional modules ----------------------------
|
||||
#define USE_BUZZER // Add support for a buzzer (+0k6 code)
|
||||
#define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code)
|
||||
#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer
|
||||
#define TUYA_DIMMER_ID 0 // Default dimmer Id
|
||||
|
|
|
@ -246,7 +246,7 @@ enum LightTypes { LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT
|
|||
|
||||
enum LightSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX};
|
||||
|
||||
enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_MODULE_INIT, FUNC_PRE_INIT, FUNC_INIT,
|
||||
enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_MODULE_INIT, FUNC_PRE_INIT, FUNC_INIT,
|
||||
FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND,
|
||||
FUNC_SAVE_AT_MIDNIGHT, FUNC_SAVE_BEFORE_RESTART,
|
||||
FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER,
|
||||
|
|
|
@ -132,7 +132,6 @@ uint8_t leds_present = 0; // Max number of LED supported
|
|||
uint8_t led_inverted = 0; // LED inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t led_power = 0; // LED power state
|
||||
uint8_t ledlnk_inverted = 0; // Link LED inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t buzzer_inverted = 0; // Buzzer inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t pwm_inverted = 0; // PWM inverted flag (1 = inverted)
|
||||
uint8_t counter_no_pullup = 0; // Counter input pullup flag (1 = No pullup)
|
||||
uint8_t energy_flg = 0; // Energy monitor configured
|
||||
|
@ -144,7 +143,6 @@ uint8_t seriallog_level; // Current copy of Settings.seriallo
|
|||
uint8_t syslog_level; // Current copy of Settings.syslog_level
|
||||
uint8_t my_module_type; // Current copy of Settings.module or user template type
|
||||
uint8_t my_adc0; // Active copy of Module ADC0
|
||||
uint8_t buzzer_count = 0; // Number of buzzes
|
||||
//uint8_t mdns_delayed_start = 0; // mDNS delayed start
|
||||
bool serial_local = false; // Handle serial locally;
|
||||
bool fallback_topic_flag = false; // Use Topic or FallbackTopic
|
||||
|
@ -816,16 +814,6 @@ void Every100mSeconds(void)
|
|||
if (backlog_pointer >= MAX_BACKLOG) { backlog_pointer = 0; }
|
||||
}
|
||||
}
|
||||
|
||||
if ((pin[GPIO_BUZZER] < 99) && (Settings.flag3.buzzer_enable)) {
|
||||
if (buzzer_count) {
|
||||
buzzer_count--;
|
||||
uint8_t state = buzzer_count & 1;
|
||||
digitalWrite(pin[GPIO_BUZZER], (buzzer_inverted) ? !state : state);
|
||||
}
|
||||
} else {
|
||||
buzzer_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
|
@ -1256,6 +1244,8 @@ void GpioInit(void)
|
|||
DEBUG_CORE_LOG(PSTR("INI: gpio pin %d, mpin %d"), i, mpin);
|
||||
|
||||
if (mpin) {
|
||||
XdrvMailbox.index = mpin;
|
||||
|
||||
if ((mpin >= GPIO_SWT1_NP) && (mpin < (GPIO_SWT1_NP + MAX_SWITCHES))) {
|
||||
SwitchPullupFlag(mpin - GPIO_SWT1_NP);
|
||||
mpin -= (GPIO_SWT1_NP - GPIO_SWT1);
|
||||
|
@ -1285,10 +1275,6 @@ void GpioInit(void)
|
|||
ledlnk_inverted = 1;
|
||||
mpin -= (GPIO_LEDLNK_INV - GPIO_LEDLNK);
|
||||
}
|
||||
else if (mpin == GPIO_BUZZER_INV) {
|
||||
buzzer_inverted = 1;
|
||||
mpin -= (GPIO_BUZZER_INV - GPIO_BUZZER);
|
||||
}
|
||||
else if ((mpin >= GPIO_PWM1_INV) && (mpin < (GPIO_PWM1_INV + MAX_PWMS))) {
|
||||
bitSet(pwm_inverted, mpin - GPIO_PWM1_INV);
|
||||
mpin -= (GPIO_PWM1_INV - GPIO_PWM1);
|
||||
|
@ -1307,6 +1293,12 @@ void GpioInit(void)
|
|||
}
|
||||
}
|
||||
#endif // USE_DHT
|
||||
else if (XdrvCall(FUNC_PIN_STATE)) {
|
||||
mpin = XdrvMailbox.index;
|
||||
}
|
||||
else if (XsnsCall(FUNC_PIN_STATE)) {
|
||||
mpin = XdrvMailbox.index;
|
||||
};
|
||||
}
|
||||
if (mpin) pin[mpin] = i;
|
||||
}
|
||||
|
@ -1422,10 +1414,6 @@ void GpioInit(void)
|
|||
pinMode(pin[GPIO_LEDLNK], OUTPUT);
|
||||
digitalWrite(pin[GPIO_LEDLNK], ledlnk_inverted);
|
||||
}
|
||||
if (pin[GPIO_BUZZER] < 99) {
|
||||
pinMode(pin[GPIO_BUZZER], OUTPUT);
|
||||
digitalWrite(pin[GPIO_BUZZER], buzzer_inverted); // Buzzer Off
|
||||
}
|
||||
|
||||
ButtonInit();
|
||||
SwitchInit();
|
||||
|
|
|
@ -488,8 +488,10 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_CNTR4,
|
||||
GPIO_CNTR4_NP,
|
||||
#endif
|
||||
#ifdef USE_BUZZER
|
||||
GPIO_BUZZER, // Buzzer
|
||||
GPIO_BUZZER_INV, // Inverted buzzer
|
||||
#endif
|
||||
GPIO_TXD, // Serial interface
|
||||
GPIO_RXD, // Serial interface
|
||||
#ifdef USE_I2C
|
||||
|
|
|
@ -124,7 +124,9 @@ void SonoffIfanReceived(void)
|
|||
if (action != GetFanspeed()) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_FANSPEED " %d"), action);
|
||||
ExecuteCommand(svalue, SRC_REMOTE);
|
||||
buzzer_count = 2; // Beep once
|
||||
#ifdef USE_BUZZER
|
||||
BuzzerEnabledBeep(1); // Beep once
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// AA 55 01 04 00 01 04 0A - Light
|
||||
|
@ -137,7 +139,9 @@ void SonoffIfanReceived(void)
|
|||
}
|
||||
if (7 == mode) {
|
||||
// AA 55 01 07 00 01 01 0A - Rf long press - forget RF codes
|
||||
buzzer_count = 6; // Beep three times
|
||||
#ifdef USE_BUZZER
|
||||
BuzzerEnabledBeep(3); // Beep three times
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send Acknowledge - Copy first 5 bytes, reset byte 6 and store crc in byte 7
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
xdrv_24_buzzer.ino - buzzer support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2019 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_BUZZER
|
||||
/*********************************************************************************************\
|
||||
* Buzzer support
|
||||
\*********************************************************************************************/
|
||||
#define XDRV_24 24
|
||||
|
||||
struct BUZZER {
|
||||
uint32_t tune = 0;
|
||||
bool active = true;
|
||||
bool enable = false;
|
||||
uint8_t inverted = 0; // Buzzer inverted flag (1 = (0 = On, 1 = Off))
|
||||
uint8_t count = 0; // Number of buzzes
|
||||
uint8_t set[2];
|
||||
uint8_t duration;
|
||||
uint8_t state = 0;
|
||||
} buzzer;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
//void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0);
|
||||
void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune)
|
||||
{
|
||||
buzzer.set[0] = off;
|
||||
buzzer.set[1] = on;
|
||||
buzzer.duration = 1; // Start buzzer on first step
|
||||
buzzer.tune = tune;
|
||||
buzzer.count = count * 2; // Start buzzer
|
||||
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BUZ: %d,%d,%d,0x%08X"), count, on, off, tune);
|
||||
|
||||
buzzer.enable = true;
|
||||
}
|
||||
|
||||
void BuzzerBeep(uint32_t count) {
|
||||
BuzzerBeep(count, 1, 1, 0);
|
||||
}
|
||||
|
||||
void BuzzerEnabledBeep(uint32_t count)
|
||||
{
|
||||
if (Settings.flag3.buzzer_enable) { // SetOption67
|
||||
BuzzerBeep(count);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
bool BuzzerPinState()
|
||||
{
|
||||
if (XdrvMailbox.index == GPIO_BUZZER_INV) {
|
||||
buzzer.inverted = 1;
|
||||
XdrvMailbox.index -= (GPIO_BUZZER_INV - GPIO_BUZZER);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BuzzerInit(void)
|
||||
{
|
||||
if (pin[GPIO_BUZZER] < 99) {
|
||||
pinMode(pin[GPIO_BUZZER], OUTPUT);
|
||||
digitalWrite(pin[GPIO_BUZZER], buzzer.inverted); // Buzzer Off
|
||||
} else {
|
||||
buzzer.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BuzzerEvery100mSec(void)
|
||||
{
|
||||
if (buzzer.enable) {
|
||||
if (buzzer.count) {
|
||||
uint8_t state = buzzer.count & 1;
|
||||
if (buzzer.duration) {
|
||||
buzzer.duration--;
|
||||
if (!buzzer.duration) {
|
||||
buzzer.count--;
|
||||
state = buzzer.count & 1;
|
||||
buzzer.duration = buzzer.set[state];
|
||||
}
|
||||
}
|
||||
digitalWrite(pin[GPIO_BUZZER], (buzzer.inverted) ? !state : state);
|
||||
} else {
|
||||
buzzer.enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
||||
const char kBuzzerCommands[] PROGMEM = "|" // No prefix
|
||||
"Buzzer" ;
|
||||
|
||||
void (* const BuzzerCommand[])(void) PROGMEM = {
|
||||
&CmndBuzzer };
|
||||
|
||||
void CmndBuzzer(void)
|
||||
{
|
||||
// Buzzer <number of beeps>,<duration of beep in 100mS steps>,<duration of silence in 100mS steps>
|
||||
// All parameters are optional
|
||||
//
|
||||
// Buzzer = Buzzer 1,1,1 = Beep once with both duration and pause set to 100mS
|
||||
// Buzzer 2 = Beep twice with duration 200mS and pause 100mS
|
||||
// Buzzer 2,3 = Beep twice with duration 300mS and pause 100mS
|
||||
// Buzzer 2,3,4 = Beep twice with duration 300mS and pause 400mS
|
||||
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
char *p;
|
||||
uint32_t i = 0;
|
||||
uint32_t parm[4] = { 0 };
|
||||
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 4; str = strtok_r(nullptr, ", ", &p)) {
|
||||
parm[i] = strtol(str, nullptr, 0);
|
||||
i++;
|
||||
}
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
if (i < 3) {
|
||||
if (parm[i] < 1) { parm[i] = 1; } // Default Count, On time, Off time
|
||||
} else {
|
||||
if (parm[3] < 0) { parm[3] = 0; } // Default Tune bitmap
|
||||
}
|
||||
}
|
||||
BuzzerBeep(parm[0], parm[1], parm[2], parm[3]);
|
||||
} else {
|
||||
BuzzerBeep(1);
|
||||
}
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xdrv24(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (buzzer.active) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_100_MSECOND:
|
||||
BuzzerEvery100mSec();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = DecodeCommand(kBuzzerCommands, BuzzerCommand);
|
||||
break;
|
||||
case FUNC_PRE_INIT:
|
||||
BuzzerInit();
|
||||
break;
|
||||
case FUNC_PIN_STATE:
|
||||
result = BuzzerPinState();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_BUZZER
|
|
@ -237,6 +237,7 @@ bool XdrvCall(uint8_t Function)
|
|||
(FUNC_SERIAL == Function) ||
|
||||
(FUNC_MODULE_INIT == Function) ||
|
||||
(FUNC_SET_CHANNELS == Function) ||
|
||||
(FUNC_PIN_STATE == Function) ||
|
||||
(FUNC_SET_DEVICE_POWER == Function)
|
||||
)) {
|
||||
break;
|
||||
|
|
|
@ -469,6 +469,7 @@ bool XsnsCall(uint8_t Function)
|
|||
#endif // PROFILE_XSNS_SENSOR_EVERY_SECOND
|
||||
|
||||
if (result && ((FUNC_COMMAND == Function) ||
|
||||
(FUNC_PIN_STATE == Function) ||
|
||||
(FUNC_COMMAND_SENSOR == Function)
|
||||
)) {
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue