Add SPM yellow error led support

This commit is contained in:
Theo Arends 2021-12-06 15:11:59 +01:00
parent 1a448ae364
commit 41e63321f1

View File

@ -28,6 +28,8 @@
* {"NAME":"Sonoff SPM (POC1)","GPIO":[1,1,1,1,3200,1,1,1,1,1,1,1,3232,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1} * {"NAME":"Sonoff SPM (POC1)","GPIO":[1,1,1,1,3200,1,1,1,1,1,1,1,3232,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1}
* Add ethernet support: * Add ethernet support:
* {"NAME":"Sonoff SPM (POC2)","GPIO":[1,0,1,0,3200,5536,0,0,1,1,1,0,3232,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1} * {"NAME":"Sonoff SPM (POC2)","GPIO":[1,0,1,0,3200,5536,0,0,1,1,1,0,3232,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1}
* Remove all user selectable GPIOs:
* {"NAME":"Sonoff SPM (POC2)","GPIO":[0,0,0,0,3200,5536,0,0,0,0,0,0,3232,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,544,0,0,32,0,0,0,0],"FLAG":0,"BASE":1}
* *
* Things to know: * Things to know:
* Bulk of the action is handled by ARM processors present in every unit communicating over modbus RS-485. * Bulk of the action is handled by ARM processors present in every unit communicating over modbus RS-485.
@ -45,15 +47,21 @@
* Tasmota POC2: * Tasmota POC2:
* Ethernet support. * Ethernet support.
* Gui optimized for energy display. * Gui optimized for energy display.
* Yellow led lights if no ARM connection can be made.
* Yellow led blinks 2 seconds if an ARM-ESP comms CRC error is detected.
* Supported commands:
* SspmDisplay 0|1 - Select alternative GUI rotating display either all or powered on only
* SspmIAmHere<relay> - Blink ERROR in SPM-4Relay where relay resides
* SspmScan - Rescan ARM modbus taking around 20 seconds
* SspmReset 1 - Reset ARM and restart ESP
* *
* Todo: * Todo:
* Gui for Overload Protection entry (is handled by ARM processor). * Gui for Overload Protection entry (is handled by ARM processor).
* Gui for Scheduling entry (is handled by ARM processor). * Gui for Scheduling entry (is handled by ARM processor).
* Yellow led functionality.
* SPI master to ARM (ARM firmware upload from ESP using EasyFlash). * SPI master to ARM (ARM firmware upload from ESP using EasyFlash).
* *
* Nice to have: * Nice to have:
* Support for all 32 SPM4Relay units equals 128 relays * Support for all 32 SPM-4Relay units equals 128 relays (restricted due to internal Tasmota register use)
* *
* GPIO's used: * GPIO's used:
* GPIO00 - Bootmode / serial flash * GPIO00 - Bootmode / serial flash
@ -126,6 +134,7 @@
#define SSPM_FUNC_SCAN_DONE 25 // 0x19 #define SSPM_FUNC_SCAN_DONE 25 // 0x19
#define SSPM_GPIO_ARM_RESET 15 #define SSPM_GPIO_ARM_RESET 15
#define SSPM_GPIO_LED_ERROR 33
#define SSPM_MODULE_NAME_SIZE 12 #define SSPM_MODULE_NAME_SIZE 12
@ -176,6 +185,7 @@ typedef struct {
uint8_t command_sequence; uint8_t command_sequence;
uint8_t mstate; uint8_t mstate;
uint8_t last_button; uint8_t last_button;
uint8_t error_led_blinks;
bool discovery_triggered; bool discovery_triggered;
} TSspm; } TSspm;
@ -428,7 +438,7 @@ void SSPMSendSetTime(void) {
SspmBuffer[25] = time.second; SspmBuffer[25] = time.second;
SspmBuffer[26] = 0; SspmBuffer[26] = 0;
SspmBuffer[27] = 0; SspmBuffer[27] = 0;
SspmBuffer[28] = 1 + (Rtc.time_timezone / 60); // Not sure why the "1" is needed but it is in my case SspmBuffer[28] = Rtc.time_timezone / 60;
SspmBuffer[29] = abs(Rtc.time_timezone % 60); SspmBuffer[29] = abs(Rtc.time_timezone % 60);
Sspm->command_sequence++; Sspm->command_sequence++;
SspmBuffer[30] = Sspm->command_sequence; SspmBuffer[30] = Sspm->command_sequence;
@ -746,6 +756,12 @@ void SSPMHandleReceivedData(void) {
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 1b 00 11 [00] 8b 34 32 37 39 37 34 13 4b 35 36 37 [03] [00 00 00] f8 94 15 L4, kWh start period (0) AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 1b 00 11 [00] 8b 34 32 37 39 37 34 13 4b 35 36 37 [03] [00 00 00] f8 94 15 L4, kWh start period (0)
*/ */
break;
case SSPM_FUNC_RESET:
/* 0x1C
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 1c 00 01 00 0b f9 e3
*/
// TasmotaGlobal.restart_flag = 2;
break; break;
} }
} else { } else {
@ -884,6 +900,7 @@ void SSPMSerialInput(void) {
if (crc_rcvd == crc_calc) { if (crc_rcvd == crc_calc) {
SSPMHandleReceivedData(); SSPMHandleReceivedData();
} else { } else {
Sspm->error_led_blinks = 20;
AddLog(LOG_LEVEL_DEBUG, PSTR("SPM: CRC error")); AddLog(LOG_LEVEL_DEBUG, PSTR("SPM: CRC error"));
} }
Sspm->serial_in_byte_counter = 0; Sspm->serial_in_byte_counter = 0;
@ -921,6 +938,9 @@ void SSPMInit(void) {
pinMode(SSPM_GPIO_ARM_RESET, OUTPUT); pinMode(SSPM_GPIO_ARM_RESET, OUTPUT);
digitalWrite(SSPM_GPIO_ARM_RESET, 1); digitalWrite(SSPM_GPIO_ARM_RESET, 1);
pinMode(SSPM_GPIO_LED_ERROR, OUTPUT);
digitalWrite(SSPM_GPIO_LED_ERROR, 0);
if (0 == Settings->flag2.voltage_resolution) { if (0 == Settings->flag2.voltage_resolution) {
Settings->flag2.voltage_resolution = 1; // SPM has 2 decimals but this keeps the gui clean Settings->flag2.voltage_resolution = 1; // SPM has 2 decimals but this keeps the gui clean
Settings->flag2.current_resolution = 2; // SPM has 2 decimals Settings->flag2.current_resolution = 2; // SPM has 2 decimals
@ -954,11 +974,21 @@ void SSPMEvery100ms(void) {
} }
} }
if (Sspm->error_led_blinks) {
uint32_t state = 1; // Stay lit
if (Sspm->error_led_blinks < 255) {
Sspm->error_led_blinks--;
state = Sspm->error_led_blinks >> 1 &1; // Blink every 0.4s
}
digitalWrite(SSPM_GPIO_LED_ERROR, state);
}
// Fix race condition if the ARM doesn't respond // Fix race condition if the ARM doesn't respond
if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_UNITS)) { if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_UNITS)) {
Sspm->counter++; Sspm->counter++;
if (Sspm->counter > 20) { if (Sspm->counter > 20) {
Sspm->mstate = SPM_NONE; Sspm->mstate = SPM_NONE;
Sspm->error_led_blinks = 255;
} }
} }
switch (Sspm->mstate) { switch (Sspm->mstate) {
@ -1210,10 +1240,10 @@ void SSPMEnergyShow(bool json) {
\*********************************************************************************************/ \*********************************************************************************************/
const char kSSPMCommands[] PROGMEM = "SSPM|" // Prefix const char kSSPMCommands[] PROGMEM = "SSPM|" // Prefix
"Log|Energy|History|Scan|IamHere|Display" ; "Log|Energy|History|Scan|IamHere|Display|Reset" ;
void (* const SSPMCommand[])(void) PROGMEM = { void (* const SSPMCommand[])(void) PROGMEM = {
&CmndSSPMLog, &CmndSSPMEnergy, &CmndSSPMEnergyHistory, &CmndSSPMScan, &CmndSSPMIamHere, &CmndSSPMDisplay }; &CmndSSPMLog, &CmndSSPMEnergy, &CmndSSPMEnergyHistory, &CmndSSPMScan, &CmndSSPMIamHere, &CmndSSPMDisplay, &CmndSSPMReset };
void CmndSSPMLog(void) { void CmndSSPMLog(void) {
// Report 29 log entries // Report 29 log entries
@ -1242,7 +1272,7 @@ void CmndSSPMScan(void) {
} }
void CmndSSPMIamHere(void) { void CmndSSPMIamHere(void) {
// Blink module COMM led containing relay // Blink module ERROR led containing relay
if ((XdrvMailbox.payload < 1) || (XdrvMailbox.payload > TasmotaGlobal.devices_present)) { XdrvMailbox.payload = 1; } if ((XdrvMailbox.payload < 1) || (XdrvMailbox.payload > TasmotaGlobal.devices_present)) { XdrvMailbox.payload = 1; }
SSPMSendIAmHere(XdrvMailbox.payload -1); SSPMSendIAmHere(XdrvMailbox.payload -1);
ResponseCmndDone(); ResponseCmndDone();
@ -1256,6 +1286,18 @@ void CmndSSPMDisplay(void) {
ResponseCmndNumber(Settings->sbflag1.sspm_display); ResponseCmndNumber(Settings->sbflag1.sspm_display);
} }
void CmndSSPMReset(void) {
// Reset ARM and restart
if (1 == XdrvMailbox.payload) {
Sspm->mstate = SPM_NONE;
SSPMSendCmnd(SSPM_FUNC_RESET);
TasmotaGlobal.restart_flag = 3;
ResponseCmndChar(PSTR(D_JSON_RESET_AND_RESTARTING));
} else {
ResponseCmndChar(PSTR(D_JSON_ONE_TO_RESET));
}
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/