mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 17:42:48 +00:00
Toggle up to 3 pins after output_ms till nag_timeout or user button press happens
This commit is contained in:
parent
60e6dc1134
commit
32d9a397aa
@ -1 +1 @@
|
||||
Subproject commit c85791a8543a5210786dc3579e099cb5ffbf72b9
|
||||
Subproject commit 737d1fc01bd7f57e48e9b8cd53b780b314b09c5b
|
@ -4,6 +4,7 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "power.h"
|
||||
#include <OneButton.h>
|
||||
|
||||
@ -114,6 +115,10 @@ class ButtonThread : public concurrency::OSThread
|
||||
{
|
||||
// DEBUG_MSG("press!\n");
|
||||
#ifdef BUTTON_PIN
|
||||
// If a nag notification is running, stop it
|
||||
if (externalNotificationModule->nagCycleCutoff != UINT32_MAX) {
|
||||
externalNotificationModule->nagCycleCutoff = 0;
|
||||
}
|
||||
if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
|
@ -151,7 +151,7 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define LocalConfig_size 387
|
||||
#define LocalModuleConfig_size 378
|
||||
#define LocalModuleConfig_size 376
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -93,12 +93,13 @@ typedef struct _ModuleConfig_ExternalNotificationConfig {
|
||||
bool alert_message;
|
||||
bool alert_bell;
|
||||
bool use_pwm;
|
||||
uint32_t output_vibra;
|
||||
uint32_t output_buzzer;
|
||||
uint8_t output_vibra;
|
||||
uint8_t output_buzzer;
|
||||
bool alert_message_vibra;
|
||||
bool alert_message_buzzer;
|
||||
bool alert_bell_vibra;
|
||||
bool alert_bell_buzzer;
|
||||
uint16_t nag_timeout;
|
||||
} ModuleConfig_ExternalNotificationConfig;
|
||||
|
||||
typedef struct _ModuleConfig_MQTTConfig {
|
||||
@ -193,7 +194,7 @@ extern "C" {
|
||||
#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0}
|
||||
#define ModuleConfig_AudioConfig_init_default {0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||
#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
||||
#define ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0}
|
||||
@ -202,7 +203,7 @@ extern "C" {
|
||||
#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0}
|
||||
#define ModuleConfig_AudioConfig_init_zero {0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||
#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
||||
#define ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0}
|
||||
@ -240,6 +241,7 @@ extern "C" {
|
||||
#define ModuleConfig_ExternalNotificationConfig_alert_message_buzzer_tag 11
|
||||
#define ModuleConfig_ExternalNotificationConfig_alert_bell_vibra_tag 12
|
||||
#define ModuleConfig_ExternalNotificationConfig_alert_bell_buzzer_tag 13
|
||||
#define ModuleConfig_ExternalNotificationConfig_nag_timeout_tag 14
|
||||
#define ModuleConfig_MQTTConfig_enabled_tag 1
|
||||
#define ModuleConfig_MQTTConfig_address_tag 2
|
||||
#define ModuleConfig_MQTTConfig_username_tag 3
|
||||
@ -341,7 +343,8 @@ X(a, STATIC, SINGULAR, UINT32, output_buzzer, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_message_vibra, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_message_buzzer, 11) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_bell_vibra, 12) \
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13)
|
||||
X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13) \
|
||||
X(a, STATIC, SINGULAR, UINT32, nag_timeout, 14)
|
||||
#define ModuleConfig_ExternalNotificationConfig_CALLBACK NULL
|
||||
#define ModuleConfig_ExternalNotificationConfig_DEFAULT NULL
|
||||
|
||||
@ -409,7 +412,7 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ModuleConfig_AudioConfig_size 19
|
||||
#define ModuleConfig_CannedMessageConfig_size 49
|
||||
#define ModuleConfig_ExternalNotificationConfig_size 42
|
||||
#define ModuleConfig_ExternalNotificationConfig_size 40
|
||||
#define ModuleConfig_MQTTConfig_size 169
|
||||
#define ModuleConfig_RangeTestConfig_size 10
|
||||
#define ModuleConfig_SerialConfig_size 26
|
||||
|
@ -11,41 +11,9 @@
|
||||
#define PIN_BUZZER false
|
||||
#endif
|
||||
|
||||
//#include <assert.h>
|
||||
|
||||
/*
|
||||
|
||||
Documentation:
|
||||
https://github.com/meshtastic/firmware/blob/master/docs/software/modules/ExternalNotificationModule.md
|
||||
|
||||
This module supports:
|
||||
https://github.com/meshtastic/firmware/issues/654
|
||||
|
||||
|
||||
Quick reference:
|
||||
|
||||
moduleConfig.external_notification.enabled
|
||||
0 = Disabled (Default)
|
||||
1 = Enabled
|
||||
|
||||
moduleConfig.external_notification.active
|
||||
0 = Active Low (Default)
|
||||
1 = Active High
|
||||
|
||||
moduleConfig.external_notification.alert_message
|
||||
0 = Disabled (Default)
|
||||
1 = Alert when a text message comes
|
||||
|
||||
moduleConfig.external_notification.alert_bell
|
||||
0 = Disabled (Default)
|
||||
1 = Alert when the bell character is received
|
||||
|
||||
moduleConfig.external_notification.output
|
||||
GPIO of the output. (Default = 13)
|
||||
|
||||
moduleConfig.external_notification.output_ms
|
||||
Amount of time in ms for the alert. Default is 1000.
|
||||
|
||||
https://meshtastic.org/docs/settings/moduleconfig/external-notification
|
||||
*/
|
||||
|
||||
// Default configurations
|
||||
@ -58,8 +26,11 @@
|
||||
|
||||
#define ASCII_BELL 0x07
|
||||
|
||||
bool externalCurrentState = 0;
|
||||
uint32_t externalTurnedOn = 0;
|
||||
ExternalNotificationModule *externalNotificationModule;
|
||||
|
||||
bool externalCurrentState[3] = {};
|
||||
|
||||
uint32_t externalTurnedOn[3] = {};
|
||||
|
||||
int32_t ExternalNotificationModule::runOnce()
|
||||
{
|
||||
@ -76,38 +47,89 @@ int32_t ExternalNotificationModule::runOnce()
|
||||
// moduleConfig.external_notification.output_ms = 1000;
|
||||
// moduleConfig.external_notification.output = 13;
|
||||
|
||||
if (externalCurrentState && !moduleConfig.external_notification.use_pwm) {
|
||||
if (moduleConfig.external_notification.use_pwm || !moduleConfig.external_notification.enabled) {
|
||||
return INT32_MAX; // we don't need this thread here...
|
||||
} else {
|
||||
|
||||
// If the output is turned on, turn it back off after the given period of time.
|
||||
if (externalTurnedOn + (moduleConfig.external_notification.output_ms
|
||||
if (nagCycleCutoff != UINT32_MAX) {
|
||||
if (externalTurnedOn[0] + (moduleConfig.external_notification.output_ms
|
||||
? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
|
||||
millis()) {
|
||||
DEBUG_MSG("Turning off external notification\n");
|
||||
setExternalOff();
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
|
||||
getExternal(0) ? setExternalOff(0) : setExternalOn(0);
|
||||
}
|
||||
if (externalTurnedOn[1] + (moduleConfig.external_notification.output_ms
|
||||
? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
|
||||
getExternal(1) ? setExternalOff(1) : setExternalOn(1);
|
||||
}
|
||||
if (externalTurnedOn[2] + (moduleConfig.external_notification.output_ms
|
||||
? moduleConfig.external_notification.output_ms
|
||||
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) < millis()) {
|
||||
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (nagCycleCutoff < millis()) {
|
||||
nagCycleCutoff = UINT32_MAX;
|
||||
DEBUG_MSG("Turning off external notification: ");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (getExternal(i)) {
|
||||
setExternalOff(i);
|
||||
externalTurnedOn[i] = 0;
|
||||
DEBUG_MSG("%d ", i);
|
||||
}
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
return INT32_MAX; // save cycles till we're needed again
|
||||
}
|
||||
}
|
||||
if (moduleConfig.external_notification.use_pwm)
|
||||
return INT32_MAX; // we don't need this thread here...
|
||||
else
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::setExternalOn()
|
||||
void ExternalNotificationModule::setExternalOn(uint8_t index)
|
||||
{
|
||||
externalCurrentState = 1;
|
||||
externalTurnedOn = millis();
|
||||
externalCurrentState[index] = 1;
|
||||
externalTurnedOn[index] = millis();
|
||||
|
||||
digitalWrite(output,
|
||||
(moduleConfig.external_notification.active ? true : false));
|
||||
switch(index) {
|
||||
case 1:
|
||||
if(moduleConfig.external_notification.output_vibra)
|
||||
digitalWrite(moduleConfig.external_notification.output_vibra, true);
|
||||
break;
|
||||
case 2:
|
||||
if(moduleConfig.external_notification.output_buzzer)
|
||||
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
|
||||
break;
|
||||
default:
|
||||
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalNotificationModule::setExternalOff()
|
||||
void ExternalNotificationModule::setExternalOff(uint8_t index)
|
||||
{
|
||||
externalCurrentState = 0;
|
||||
externalCurrentState[index] = 0;
|
||||
externalTurnedOn[index] = millis();
|
||||
|
||||
digitalWrite(output,
|
||||
(moduleConfig.external_notification.active ? false : true));
|
||||
switch(index) {
|
||||
case 1:
|
||||
if(moduleConfig.external_notification.output_vibra)
|
||||
digitalWrite(moduleConfig.external_notification.output_vibra, false);
|
||||
break;
|
||||
case 2:
|
||||
if(moduleConfig.external_notification.output_buzzer)
|
||||
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
|
||||
break;
|
||||
default:
|
||||
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool ExternalNotificationModule::getExternal(uint8_t index)
|
||||
{
|
||||
return externalCurrentState[index];
|
||||
}
|
||||
|
||||
// --------
|
||||
@ -141,8 +163,20 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
// Set the direction of a pin
|
||||
DEBUG_MSG("Using Pin %i in digital mode\n", output);
|
||||
pinMode(output, OUTPUT);
|
||||
// Turn off the pin
|
||||
setExternalOff();
|
||||
setExternalOff(0);
|
||||
externalTurnedOn[0] = 0;
|
||||
if(moduleConfig.external_notification.output_vibra) {
|
||||
DEBUG_MSG("Using Pin %i for vibra motor\n", moduleConfig.external_notification.output_vibra);
|
||||
pinMode(moduleConfig.external_notification.output_vibra, OUTPUT);
|
||||
setExternalOff(1);
|
||||
externalTurnedOn[1] = 0;
|
||||
}
|
||||
if(moduleConfig.external_notification.output_buzzer) {
|
||||
DEBUG_MSG("Using Pin %i for buzzer\n", moduleConfig.external_notification.output_buzzer);
|
||||
pinMode(moduleConfig.external_notification.output_buzzer, OUTPUT);
|
||||
setExternalOff(2);
|
||||
externalTurnedOn[2] = 0;
|
||||
}
|
||||
} else {
|
||||
config.device.buzzer_gpio = config.device.buzzer_gpio
|
||||
? config.device.buzzer_gpio
|
||||
@ -163,17 +197,53 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
|
||||
|
||||
if (getFrom(&mp) != nodeDB.getNodeNum()) {
|
||||
|
||||
// TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will.
|
||||
// Need to know if and how this could be a problem.
|
||||
// Check if the message contains a bell character. Don't do this loop for every pin, just once.
|
||||
auto &p = mp.decoded;
|
||||
bool containsBell = false;
|
||||
for (int i = 0; i < p.payload.size; i++) {
|
||||
if (p.payload.bytes[i] == ASCII_BELL) {
|
||||
containsBell = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleConfig.external_notification.alert_bell) {
|
||||
auto &p = mp.decoded;
|
||||
DEBUG_MSG("externalNotificationModule - Notification Bell\n");
|
||||
for (int i = 0; i < p.payload.size; i++) {
|
||||
if (p.payload.bytes[i] == ASCII_BELL) {
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
setExternalOn();
|
||||
if (containsBell) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Bell\n");
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
setExternalOn(0);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
playBeep();
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
// run_once now
|
||||
} else {
|
||||
playBeep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
if (moduleConfig.external_notification.alert_bell_vibra) {
|
||||
if (containsBell) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Bell (Vibra)\n");
|
||||
setExternalOn(1);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleConfig.external_notification.alert_bell_buzzer) {
|
||||
if (containsBell) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Bell (Buzzer)\n");
|
||||
setExternalOn(2);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,11 +252,39 @@ ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
|
||||
if (moduleConfig.external_notification.alert_message) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Module\n");
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
setExternalOn();
|
||||
setExternalOn(0);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
} else {
|
||||
playBeep();
|
||||
}
|
||||
}
|
||||
|
||||
if (!moduleConfig.external_notification.use_pwm) {
|
||||
if (moduleConfig.external_notification.alert_message_vibra) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Module (Vibra)\n");
|
||||
setExternalOn(1);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleConfig.external_notification.alert_message_buzzer) {
|
||||
DEBUG_MSG("externalNotificationModule - Notification Module (Buzzer)\n");
|
||||
setExternalOn(2);
|
||||
if (moduleConfig.external_notification.nag_timeout) {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.nag_timeout * 1000;
|
||||
} else {
|
||||
nagCycleCutoff = millis() + moduleConfig.external_notification.output_ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
setIntervalFromNow(0); // run once so we know if we should do something
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -17,18 +17,19 @@ class ExternalNotificationModule : public SinglePortModule, private concurrency:
|
||||
public:
|
||||
ExternalNotificationModule();
|
||||
|
||||
void setExternalOn();
|
||||
void setExternalOff();
|
||||
void getExternal();
|
||||
uint32_t nagCycleCutoff = UINT32_MAX;
|
||||
|
||||
void setExternalOn(uint8_t index = 0);
|
||||
void setExternalOff(uint8_t index = 0);
|
||||
bool getExternal(uint8_t index = 0);
|
||||
|
||||
protected:
|
||||
// virtual MeshPacket *allocReply();
|
||||
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
|
||||
|
||||
virtual int32_t runOnce() override;
|
||||
};
|
||||
|
||||
extern ExternalNotificationModule *externalNotificationModule;
|
||||
|
@ -69,7 +69,7 @@ void setupModules()
|
||||
#ifdef ARCH_ESP32
|
||||
// Only run on an esp32 based device.
|
||||
audioModule = new AudioModule();
|
||||
new ExternalNotificationModule();
|
||||
externalNotificationModule = new ExternalNotificationModule();
|
||||
|
||||
storeForwardModule = new StoreForwardModule();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user