Fix Shelly Pro 4PM issues

- Fix random ADE7935 measurements
- Fix relay 1 toggle on restart
- Add Shelly Pro 4PM display.ini
This commit is contained in:
Theo Arends 2023-02-04 17:48:53 +01:00
parent a581fc237d
commit cfd34aa02c
4 changed files with 66 additions and 12 deletions

View File

@ -0,0 +1,35 @@
:H,PRO_4PM,160,128,16,SPI,3,0,15,13,2,12,*,*,20
:S,2,1,1,0,20,20
:I
01,80
11,80
B1,3,01,2C,2D
B2,3,01,2C,2D
B3,6,01,2C,2D,01,2C,2D
B4,1,07
C0,3,A2,04,84
C1,1,C5
C2,2,0A,00
C3,2,8A,2A
C4,2,8A,EE
C5,1,0E
20,0
36,1,C8
3A,1,05
2A,4,00,02,00,7F
2B,4,00,01,00,7F
E0,10,02,1C,07,12,37,32,29,2D,29,25,2B,39,00,01,03,10
E1,10,03,1D,07,06,2E,2C,29,2D,2E,2E,37,3F,00,00,02,10
13,80
29,80
:o,28
:O,29
:A,2A,2B,2C,16
:R,36
:0,68,00,00,00
:1,CC,1A,01,01
:2,A8,01,1A,02
:3,08,1A,01,03
:i,21,20
:B,60,1
#

View File

@ -1838,14 +1838,21 @@ void DisplayLocalSensor(void)
* Public * Public
\*********************************************************************************************/ \*********************************************************************************************/
void DisplayInitDriver(void) void DisplayInitDriver(void) {
{ uint8_t devices_present = TasmotaGlobal.devices_present; // Save devices_present
TasmotaGlobal.devices_present++;
if (!PinUsed(GPIO_BACKLIGHT)) {
if (TasmotaGlobal.light_type && (4 == Settings->display_model)) {
TasmotaGlobal.devices_present--; // Assume PWM channel is used for backlight
}
}
disp_device = TasmotaGlobal.devices_present; // Set display device
XdspCall(FUNC_DISPLAY_INIT_DRIVER); XdspCall(FUNC_DISPLAY_INIT_DRIVER);
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings->display_model); // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings->display_model);
if (Settings->display_model) { if (Settings->display_model) {
// ApplyDisplayDimmer(); // Not allowed here. Way too early in initi sequence. IE power state has not even been set at this point in time
#ifdef USE_MULTI_DISPLAY #ifdef USE_MULTI_DISPLAY
Set_display(0); Set_display(0);
@ -1874,6 +1881,7 @@ void DisplayInitDriver(void)
for (uint8_t count = 0; count < NUM_GRAPHS; count++) { graph[count] = 0; } for (uint8_t count = 0; count < NUM_GRAPHS; count++) { graph[count] = 0; }
#endif #endif
/*
TasmotaGlobal.devices_present++; TasmotaGlobal.devices_present++;
if (!PinUsed(GPIO_BACKLIGHT)) { if (!PinUsed(GPIO_BACKLIGHT)) {
if (TasmotaGlobal.light_type && (4 == Settings->display_model)) { if (TasmotaGlobal.light_type && (4 == Settings->display_model)) {
@ -1881,12 +1889,16 @@ void DisplayInitDriver(void)
} }
} }
disp_device = TasmotaGlobal.devices_present; disp_device = TasmotaGlobal.devices_present;
*/
#ifndef USE_DISPLAY_MODES1TO5 #ifndef USE_DISPLAY_MODES1TO5
Settings->display_mode = 0; Settings->display_mode = 0;
#else #else
DisplayLogBufferInit(); DisplayLogBufferInit();
#endif // USE_DISPLAY_MODES1TO5 #endif // USE_DISPLAY_MODES1TO5
} else {
TasmotaGlobal.devices_present = devices_present; // Restore devices_present
disp_device = 0;
} }
} }
@ -2009,7 +2021,6 @@ void ApplyDisplayDimmer(void) {
// still call Berry virtual display in case it is not managed entirely by renderer // still call Berry virtual display in case it is not managed entirely by renderer
Xdsp18(FUNC_DISPLAY_DIM); Xdsp18(FUNC_DISPLAY_DIM);
#endif // USE_BERRY #endif // USE_BERRY
} else { } else {
XdspCall(FUNC_DISPLAY_DIM); XdspCall(FUNC_DISPLAY_DIM);
} }

View File

@ -27,8 +27,7 @@
* {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 2","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"} * {"NAME":"Shelly Pro 2","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"} * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 4PM","GPIO":[769,1,1,1,9568,0,0,0,1,705,9569,737,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,6214,736,704,3461,0,4736,1,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,0,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 4PM No display","GPIO":[1,1,1,1,9568,0,0,0,1,1,9569,1,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,6214,736,704,3461,0,4736,1,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
* *
* Shelly Pro 1/2 uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring * Shelly Pro 1/2 uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
* Shelly Pro 4 uses an SPI to control one MCP23S17 for buttons/switches/relays/leds and two ADE7953 for energy monitoring and a second SPI for the display * Shelly Pro 4 uses an SPI to control one MCP23S17 for buttons/switches/relays/leds and two ADE7953 for energy monitoring and a second SPI for the display

View File

@ -32,7 +32,7 @@
* {"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"} * {"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"} * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"}
* {"NAME":"Shelly Pro 4PM No display","GPIO":[1,1,1,1,9568,0,0,0,1,1,9569,1,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,6214,736,704,3461,0,4736,1,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"} * {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,768,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,0,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
* *
* Based on datasheet from https://www.analog.com/en/products/ade7953.html * Based on datasheet from https://www.analog.com/en/products/ade7953.html
* *
@ -241,6 +241,7 @@ struct Ade7953 {
SPISettings spi_settings; SPISettings spi_settings;
int8_t pin_cs[ADE7953_MAX_CHANNEL / 2]; int8_t pin_cs[ADE7953_MAX_CHANNEL / 2];
#endif // USE_ESP32_SPI #endif // USE_ESP32_SPI
bool use_spi;
} Ade7953; } Ade7953;
/*********************************************************************************************/ /*********************************************************************************************/
@ -283,7 +284,7 @@ void Ade7953Write(uint16_t reg, uint32_t val) {
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Write %08X"), val); // AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Write %08X"), val);
#ifdef USE_ESP32_SPI #ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) { if (Ade7953.use_spi) {
Ade7953SpiEnable(); Ade7953SpiEnable();
SPI.transfer16(reg); SPI.transfer16(reg);
SPI.transfer(0x00); // Write SPI.transfer(0x00); // Write
@ -313,7 +314,7 @@ int32_t Ade7953Read(uint16_t reg) {
int size = Ade7953RegSize(reg); int size = Ade7953RegSize(reg);
if (size) { if (size) {
#ifdef USE_ESP32_SPI #ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) { if (Ade7953.use_spi) {
Ade7953SpiEnable(); Ade7953SpiEnable();
SPI.transfer16(reg); SPI.transfer16(reg);
SPI.transfer(0x80); // Read SPI.transfer(0x80); // Read
@ -450,7 +451,7 @@ void Ade7953GetData(void) {
int32_t reg[ADE7953_MAX_CHANNEL][ADE7953_REGISTERS]; int32_t reg[ADE7953_MAX_CHANNEL][ADE7953_REGISTERS];
#ifdef USE_ESP32_SPI #ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) { if (Ade7953.use_spi) {
uint32_t channel = 0; uint32_t channel = 0;
for (uint32_t chip = 0; chip < ADE7953_MAX_CHANNEL / 2; chip++) { for (uint32_t chip = 0; chip < ADE7953_MAX_CHANNEL / 2; chip++) {
if (Ade7953.pin_cs[chip] < 0) { continue; } if (Ade7953.pin_cs[chip] < 0) { continue; }
@ -705,6 +706,7 @@ void Ade7953DrvInit(void) {
Ade7953.model = ADE7953_SHELLY_PRO_1PM; Ade7953.model = ADE7953_SHELLY_PRO_1PM;
} }
Ade7953.cs_index = 0; Ade7953.cs_index = 0;
Ade7953.use_spi = true;
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1); SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
Ade7953.spi_settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); // Set up SPI at 1MHz, MSB first, Capture at rising edge Ade7953.spi_settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); // Set up SPI at 1MHz, MSB first, Capture at rising edge
AddLog(LOG_LEVEL_INFO, PSTR("SPI: ADE7953 found")); AddLog(LOG_LEVEL_INFO, PSTR("SPI: ADE7953 found"));
@ -820,8 +822,15 @@ bool Xnrg07(uint32_t function) {
bool result = false; bool result = false;
switch (function) { switch (function) {
case FUNC_ENERGY_EVERY_SECOND: case FUNC_ENERGY_EVERY_SECOND: // Use energy interrupt timer (fails on SPI)
Ade7953EnergyEverySecond(); if (!Ade7953.use_spi) { // No SPI
Ade7953EnergyEverySecond();
}
break;
case FUNC_EVERY_SECOND: // Use loop timer (without interrupt)
if (Ade7953.use_spi) { // SPI
Ade7953EnergyEverySecond();
}
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = Ade7953Command(); result = Ade7953Command();