mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
Add SPM yellow error led support
This commit is contained in:
parent
1a448ae364
commit
41e63321f1
@ -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
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user