Skip to content

Commit 772d2f3

Browse files
committed
Send correct data when using API. Fix LedSequence for API.
1 parent 27e6ede commit 772d2f3

File tree

1 file changed

+66
-75
lines changed

1 file changed

+66
-75
lines changed

Sensorbox2_ESP/src/main.cpp

Lines changed: 66 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,72 @@ extern uint8_t WIFImode;
9696
String SmartEVSEHost = "";
9797

9898
unsigned long ModbusTimer=0;
99-
unsigned char dataready=0, CTcount, DSMRver, IrmsMode = 0;
99+
unsigned char dataready=0, datareadyAPI=0, CTcount, DSMRver, IrmsMode = 0;
100100
unsigned char LedCnt, LedState, LedSeq[4] = {0,0,0,0};
101101
float Irms[3], Volts[3], IrmsCT[3]; // float is 32 bits; current in A
102102
int16_t MainsMeterIrms[3]; // current in dA (10 * A) !!!
103-
uint8_t datamemory = 0;
103+
bool lockedToP1 = false;
104104
unsigned char led = 0, Wire = WIRES4 + CW;
105105
uint16_t blinkram = 0, P1taskram = 0;
106106
extern bool LocalTimeSet;
107107
int phasesLastUpdate = 0;
108108

109109

110+
void SetLedSequence(uint8_t source) {
111+
uint8_t n = 1;
112+
113+
// Set Led sequence for the next 2 seconds
114+
// reset to first part of sequence
115+
LedCnt = 0;
116+
LedState = 8;
117+
118+
// When we have received a valid measurement from the SmartMeter, the led will blink only once.
119+
if (source & 0xC0) {
120+
// DSMR version not 5.x! Blink RED
121+
if (DSMRver < 50) LedSeq[0] = LED_RED;
122+
// DSMR version OK, Blink GREEN
123+
else LedSeq[0] = LED_GREEN;
124+
125+
// No SmartMeter connected, we use the CT's
126+
// CT measurement available?
127+
} else if (source & 0x03) {
128+
// CT measurements with current direction?
129+
if (IrmsMode == 0) {
130+
if (IrmsCT[0] < -0.1 ) LedSeq[0]=LED_GREEN; else LedSeq[0]=LED_ORANGE;
131+
if (IrmsCT[1] < -0.1 ) LedSeq[1]=LED_GREEN; else LedSeq[1]=LED_ORANGE;
132+
if (IrmsCT[2] < -0.1 ) LedSeq[2]=LED_GREEN; else LedSeq[2]=LED_ORANGE;
133+
// 6 States, ON/OFF (3 CT's)
134+
n = 3;
135+
} else {
136+
// Blink 1x Orange when not using MAINS input
137+
LedSeq[0] = LED_ORANGE;
138+
}
139+
// LED_RED_ON (PIC chip not programmed?)
140+
} else {
141+
LedSeq[0] = LED_RED;
142+
}
143+
144+
// Show WiFi mode as last blink in sequence
145+
if (WIFImode == 2) LedSeq[n] = LED_RED;
146+
else if (WIFImode == 1) LedSeq[n] = LED_GREEN;
147+
}
148+
110149

111150
// Every ~2 seconds send measurement data to APIs
112151
void Timer2S(void * parameter) {
113152
while (true) {
114153
if (WiFi.status() == WL_CONNECTED) {
115-
if ((datamemory & 0x80 ) || (datamemory & 0x03)) { // we have data
154+
155+
// We have valid data. Does not allow switching from P1 back to CT data !
156+
// A broken P1 connection now creates a comm error instead of (invalid) CT measurements being used.
157+
if ( (lockedToP1 == true && datareadyAPI & 0x80) || (lockedToP1 == false && datareadyAPI & 0x03) ) {
158+
159+
for (uint8_t x = 0; x < 3; x++) {
160+
// P1 data has precedence over CT data, although CT data might be newer.
161+
if (datareadyAPI & 0x80) MainsMeterIrms[x] = round(Irms[x] * 10);
162+
else MainsMeterIrms[x] = round(IrmsCT[x] * 10);
163+
}
164+
116165
#if MQTT
117166
//publishing to the broker
118167
MQTTclient.publish(MQTTprefix + "/MainsCurrentL1", MainsMeterIrms[0], false, 0);
@@ -145,10 +194,11 @@ void Timer2S(void * parameter) {
145194
FREE(currents);
146195
#endif
147196
}
197+
SetLedSequence(datareadyAPI);
148198
}
149199
}
150200

151-
datamemory = 0;
201+
datareadyAPI = 0;
152202
}
153203
vTaskDelay(2000 / portTICK_PERIOD_MS);
154204
}
@@ -193,27 +243,6 @@ void read_settings(bool write) {
193243
}
194244

195245

196-
// Poly used is x^16+x^15+x^2+x
197-
unsigned int CRC16(unsigned int crc, unsigned char *buf, int len)
198-
{
199-
for (int pos = 0; pos < len; pos++)
200-
{
201-
crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc
202-
203-
for (int i = 8; i != 0; i--) { // Loop over each bit
204-
if ((crc & 0x0001) != 0) { // If the LSB is set
205-
crc >>= 1; // Shift right and XOR 0xA001
206-
crc ^= 0xA001;
207-
}
208-
else // Else LSB is not set
209-
crc >>= 1; // Just shift right
210-
}
211-
}
212-
return crc;
213-
}
214-
215-
216-
217246
// ----------------------------------------------------------------------------------------------------------------
218247
// CT data is measured by the PIC, is send on a serial line to Serial0 of the ESP32
219248
// The final calculations and phase angle corrections are done by the ESP32.
@@ -309,9 +338,6 @@ void CTReceive() {
309338
IrmsMode = 0;
310339
}
311340

312-
for (int x = 0; x < 3; x++) {
313-
MainsMeterIrms[x] = round(IrmsCT[x] * 10);
314-
}
315341
phasesLastUpdate = time(NULL);
316342

317343
// very small values will be displayed as 0.0A
@@ -332,6 +358,7 @@ void CTReceive() {
332358

333359
// update dataready, so the Master knows the CT's have been read with new data
334360
dataready |= 0x03;
361+
datareadyAPI |= 0x03;
335362
_LOG_V("\rCT1: %2.1f A CT2: %2.1f A CT3: %2.1f A ",IrmsCT[0],IrmsCT[1],IrmsCT[2] );
336363

337364
} else {
@@ -414,13 +441,13 @@ void P1Extract() {
414441
Irms[1] = (L2Power-L2PowerReturn)/Volts[1];
415442
Irms[2] = (L3Power-L3PowerReturn)/Volts[2];
416443

417-
for (int x = 0; x < 3; x++) {
418-
MainsMeterIrms[x] = round(Irms[x] * 10);
419-
}
420444
phasesLastUpdate = time(NULL);
421445

422-
if (DSMRver >= 50) dataready |= 0x80; // P1 dataready
423-
else dataready |= 0x40; // DSMR version not 5.0 !!
446+
if (DSMRver >= 50) {
447+
dataready |= 0x80; // P1 dataready
448+
datareadyAPI |= 0x80;
449+
lockedToP1 = true;
450+
} else dataready |= 0x40; // DSMR version not 5.0 !!
424451

425452
_LOG_V("L1: %3d V L2: %3d V L3: %3d V ",(int)(Volts[0]),(int)(Volts[1]),(int)(Volts[2]) );
426453
_LOG_V("L1: %2.1f A L2: %2.1f A L3: %2.1f A \r\n",Irms[0],Irms[1],Irms[2] );
@@ -511,17 +538,14 @@ void P1Task(void * parameter) {
511538
_LOG_A("\nheap error after CT receive\n");
512539
}
513540

514-
// remember state of dataready, as it will be cleared after sending the data to the modbus Master.
515-
if (dataready > datamemory) datamemory = dataready;
516-
517541
if (WiFi.status() != WL_CONNECTED && esp_timer_get_time() / 1000000 > 5 && WIFImode != 2 && esp_timer_get_time() / 1000000 < 180) {
518542
// if we have no wifi
519543
// and we are not in the first 5 seconds of startup (to give the existing wifi time to connect and P1 data to be entered)
520544
// and we are not already in wifimode 2
521545
// and we are not later then the first 180s after startup; perhaps we are not interested in having a wifi connection?
522546
// we go to wifimode 2 smartconfig
523547
WIFImode = 2;
524-
if (datamemory & 0x80 ) {
548+
if (lockedToP1) {
525549
handleWIFImode(&Serial); // P1 data comes in so Serial0 is available
526550
blockCT = true;
527551
} else {
@@ -613,42 +637,8 @@ ModbusMessage MBReadFC04(ModbusMessage request) {
613637
// Prepare start of response
614638
response.add(request.getServerID(), request.getFunctionCode(), (uint8_t)(words * 2));
615639

616-
// Set Led sequence for the next 2 seconds
617-
// reset to first part of sequence
618-
LedCnt = 0;
619-
n = 1;
620-
LedState = 8;
621-
622-
// When we have received a valid measurement from the SmartMeter, the led will blink only once.
623-
if (dataready & 0xC0) {
624-
// DSMR version not 5.x! Blink RED
625-
if (DSMRver < 50) LedSeq[0] = LED_RED;
626-
// DSMR version OK, Blink GREEN
627-
else LedSeq[0] = LED_GREEN;
628-
629-
// No SmartMeter connected, we use the CT's
630-
// CT measurement available?
631-
} else if (dataready & 0x03) {
632-
// CT measurements with current direction?
633-
if (IrmsMode == 0) {
634-
if (IrmsCT[0] < -0.1 ) LedSeq[0]=LED_GREEN; else LedSeq[0]=LED_ORANGE;
635-
if (IrmsCT[1] < -0.1 ) LedSeq[1]=LED_GREEN; else LedSeq[1]=LED_ORANGE;
636-
if (IrmsCT[2] < -0.1 ) LedSeq[2]=LED_GREEN; else LedSeq[2]=LED_ORANGE;
637-
// 6 States, ON/OFF (3 CT's)
638-
n = 3;
639-
} else {
640-
// Blink 1x Orange when not using MAINS input
641-
LedSeq[0] = LED_ORANGE;
642-
}
643-
// LED_RED_ON (PIC chip not programmed?)
644-
} else {
645-
LedSeq[0] = LED_RED;
646-
}
647-
648-
// Show WiFi mode as last blink in sequence
649-
if (WIFImode == 2) LedSeq[n] = LED_RED;
650-
else if (WIFImode == 1) LedSeq[n] = LED_GREEN;
651-
640+
SetLedSequence(dataready);
641+
652642
// Set Modbus Sensorbox version 2.0 (20) + Wire settings.
653643
// Set Software version in MSB
654644
ModbusData[0] = (SENSORBOX_SWVER << 8) + SENSORBOX_VERSION + Wire;
@@ -699,8 +689,9 @@ ModbusMessage MBReadFC04(ModbusMessage request) {
699689

700690
if ((millis() - ModbusTimer) > 2500) {
701691
LOG_W("Missed modbus response\n");
702-
ModbusTimer = millis();
703-
}
692+
}
693+
ModbusTimer = millis();
694+
704695

705696
// Loop over all words to be sent
706697
for (uint16_t i = 0; i < words; i++) {

0 commit comments

Comments
 (0)