reaper7 / SDM_Energy_Meter

reading SDM72 SDM120 SDM220 SDM230 SDM630 modbus energy meters from arduino (esp8266, esp32, avr)
245 stars 97 forks source link

Can you please explain unstable reading? #8

Closed agsochi closed 7 years ago

agsochi commented 7 years ago

I have SDM120, this converter and Wemos D1 mini. And i got NaN in output always in different places. What i should tune in fw? at 2400b

----------------------------------------
Voltage:   220.50 V
Current:   nan A
Power:     5.40 W
Total active energy: nan Wh
Total reactive energy: 0.28 VARh
----------------------------------------
Voltage:   222.70 V
Current:   nan A
Power:     5.40 W
Total active energy: nan Wh
Total reactive energy: 0.28 VARh
----------------------------------------
Voltage:   221.90 V
Current:   nan A
Power:     5.40 W
Total active energy: nan Wh
Total reactive energy: 0.28 VARh
----------------------------------------
Voltage:   222.30 V
Current:   0.03 A
Power:     nan W
Total active energy: 0.62 Wh
Total reactive energy: nan VARh
----------------------------------------
Voltage:   222.90 V
Current:   nan A
Power:     5.40 W
Total active energy: nan Wh
Total reactive energy: 0.28 VARh
----------------------------------------
Voltage:   224.50 V
Current:   nan A
Power:     5.50 W
Total active energy: nan Wh
Total reactive energy: 0.28 VARh
----------------------------------------
Voltage:   224.30 V
Current:   0.03 A
Power:     nan W
Total active energy: 0.62 Wh
Total reactive energy: nan VARh
----------------------------------------
beireken commented 7 years ago

Can you try adding a delay between readings? Like explained in this issue: https://github.com/reaper7/SDM_Energy_Meter/issues/7

agsochi commented 7 years ago

Yes, 50ms delay fix this. Thank you!

reaper7 commented 7 years ago

someone can test this example (without any delays between readings) and report whether problem with NaN readings still persists

#include <SDM.h>                                                                //import SDM template library

//SDM<2400, 12, 13> sdm;                                                        //SDM120T   baud, rx pin, tx pin
//SDM<4800, 12, 13> sdm;                                                        //SDM220T   baud, rx pin, tx pin
//SDM<9600, 12, 13> sdm;                                                        //SDM630    baud, rx pin, tx pin
//or without parameters (default from SDM.h will be used): 
SDM<> sdm;

void setup() {
  Serial.begin(115200);                                                         //initialize serial
  sdm.begin();                                                                  //initalize SDM220 communication baudrate
}

void loop() {
  float v = sdm.readVal(SDM220T_VOLTAGE);                                       //read voltage
  float c = sdm.readVal(SDM220T_CURRENT);                                       //read current
  float p = sdm.readVal(SDM220T_POWER);                                         //read power
  float f = sdm.readVal(SDM220T_FREQUENCY);                                     //read frequency

  Serial.printf("\nVoltage:   %.2fV\nCurrent:   %.2fA\nPower:     %.2fW\nFrequency: %.2fHz\n", v, c, p, f);

  delay(1000);                                                                  //wait a while before next loop
}
sjfaustino commented 7 years ago

Using latest version of this library, latest software serial and the code below (printf on the esp8266 doesn't understand floats), I get:

Voltage: 228.20V Current: nanA Power: 0.00W Frequency: nanHz

Voltage: 228.40V Current: nanA Power: 0.00W Frequency: nanHz

Voltage: 228.40V Current: nanA Power: 0.00W Frequency: nanHz

Voltage: 228.10V Current: nanA Power: 0.00W Frequency: nanHz

#include <SDM.h>                                                                //import SDM template library

SDM<2400, 12, 13> sdm;                                                        //SDM120T  baud, rx pin, tx pin
//SDM<4800, 12, 13> sdm;                                                        //SDM220T baud, rx pin, tx pin
//SDM<9600, 12, 13> sdm;                                                        //SDM630  baud, rx pin, tx pin
//or without parameters (default from SDM.h will be used): 
//SDM<> sdm;

void setup() {
  Serial.begin(115200);                                                         //initialize serial
  sdm.begin();                                                                  //initalize SDM220 communication baudrate
}

void loop() {
  float v = sdm.readVal(SDM120C_VOLTAGE);                                       //read voltage
  float c = sdm.readVal(SDM120C_CURRENT);                                       //read current
  float p = sdm.readVal(SDM120C_POWER);                                         //read power
  float f = sdm.readVal(SDM120C_FREQUENCY);                                     //read frequency

  Serial.printf("\nVoltage:   %sV\nCurrent:   %sA\nPower:     %sW\nFrequency: %sHz\n", String(v, 2).c_str(), String(c, 2).c_str(), String(p, 2).c_str(), String(f, 2).c_str());

  delay(1000);                                                                  //wait a while before next loop
}

If I modify the library with a delay(1), it works

  delay(1);
  if (_dere_pin != NOT_A_PIN)                                               //transmit to SDM  -> DE Enable, /RE Disable (for control MAX485)
    digitalWrite(_dere_pin, HIGH);

Voltage: 231.40V Current: 0.00A Power: 0.00W Frequency: 50.00Hz

Voltage: 230.90V Current: 0.00A Power: 0.00W Frequency: 50.04Hz

Voltage: 231.10V Current: 0.00A Power: 0.00W Frequency: 50.00Hz

Voltage: 231.00V Current: 0.00A Power: 0.00W Frequency: 50.00Hz

reaper7 commented 7 years ago

done

btw, which version does not understand float?? I'm using printf with %f without problem

codmpm commented 6 years ago

I'm still getting nan with an SDM220, using ESP8266 core 2.4.1 and the code from https://github.com/reaper7/SDM_Energy_Meter/issues/8#issuecomment-298623158 together with the current master of the library.

void loop() {
  float v = sdm.readVal(SDM220T_VOLTAGE);                                       //read voltage
  float c = sdm.readVal(SDM220T_CURRENT);                                       //read current
  float p = sdm.readVal(SDM220T_POWER);                                         //read power
  float f = sdm.readVal(SDM220T_FREQUENCY);                                     //read frequency

  Serial.printf("\nVoltage:   %sV\nCurrent:   %sA\nPower:     %sW\nFrequency: %sHz\n", String(v, 2).c_str(), String(c, 2).c_str(), String(p, 2).c_str(), String(f, 2).c_str());

  delay(1000);  
}

Gives me:

Voltage:   225.68V
Current:   nanA
Power:     nanW
Frequency: nanHz

Voltage:   225.59V
Current:   nanA
Power:     nanW
Frequency: nanHz

Adding a delay of 20ms between each readVal() makes the situation better, but there are still nan's from time to time:

Voltage:   225.28V
Current:   0.00A
Power:     0.00W
Frequency: 50.01Hz

Voltage:   225.32V
Current:   0.00A
Power:     nanW
Frequency: 50.01Hz

Voltage:   225.37V
Current:   nanA
Power:     0.00W
Frequency: 50.01Hz

Maybe you have an idea how to optimize this. Or should I simply use the hardware serial?

Thank you for the lib. Cheers, Patrik

reaper7 commented 6 years ago

Please try to use hw serial, I don't have more than 1-2 errors per day for sdm220 with hw serial (without any delay between readings)

reaper7 commented 6 years ago

or maybe try to remove rs485 line terminator as @da3020 wrote: https://github.com/reaper7/SDM_Energy_Meter/issues/16

codmpm commented 6 years ago

I'm using a plain SN75176B - which is a drop-in replacement for the MAX485 - with no additional resistors.

Maybe I should add some Pull-Up's like these chinese boards have?

max485-module-sch1

//edit: Obviously the SN75176B is not made for 3.3V operation. I'm looking for alternatives...

reaper7 commented 6 years ago

It's hard to say for me...it's just an idea.

codmpm commented 6 years ago

I've ordered the SP3485EN-L, which is a 3.3V version of the MAX485. The MAX485/SN75176B itself is specified for 5V.

I will test when they arive to know if it's simply a problem with 3.3V logic.

reaper7 commented 6 years ago

if You waiting for new converter, please try on "old" 5V how it works on ESP8266 HW serial lines. Of course if You have free time :) this operation requires an additional uart converter on Serial1 for debug results

#define USE_HARDWARESERIAL

#include <SDM.h>                                                                //import SDM template library

SDM<YOUR_BAUD_SETTINGS, YOUR_DERE_PIN, false> sdm;

void setup() {
  Serial1.begin(115200);                                                        //initialize serial 1
  sdm.begin();                                                                  //initalize SDM220 communication baudrate
}

void loop() {
  float v = sdm.readVal(SDM120C_VOLTAGE);                                       //read voltage
  float c = sdm.readVal(SDM120C_CURRENT);                                       //read current
  float p = sdm.readVal(SDM120C_POWER);                                         //read power
  float f = sdm.readVal(SDM120C_FREQUENCY);                                     //read frequency

  Serial1.printf("\nVoltage:   %sV\nCurrent:   %sA\nPower:     %sW\nFrequency: %sHz\n", String(v, 2).c_str(), String(c, 2).c_str(), String(p, 2).c_str(), String(f, 2).c_str());

  delay(1000);                                                                  //wait a while before next loop
}
codmpm commented 6 years ago

Sorry for getting back late... I've switched to the SP3485EN-L (3.3V RS485 tranceiver) and have the same result, but slightly more stable. Only every 3rd/4th reading has a nan, independet from if I add delay(20) or not between smd.readVal().

I will try the "hardware"-serial next and will get back to you. Meanwhile I ordered samples of the MAX3483 from Maxim to check if these work better...

reaper7 commented 6 years ago

I have one more idea to check, please comment lines from 191 to 193

// #if !defined ( USE_HARDWARESERIAL )
//       sdmSer.listen();                                                          //enable softserial rx interrupt
// #endif

and from 251 to 253

// #if !defined ( USE_HARDWARESERIAL )
//       sdmSer.end();                                                             //disable softserial rx interrupt
// #endif

maybe something is wrong with enabling/disabling softwareserial RX interrupt

codmpm commented 6 years ago

I still get nan-readings... and a panic:

Current:   nanA
Power:     0.00W
Frequency: 50.00Hz

Exception (0):
epc1=0x402275a0 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4022642d depc=0x00000000

ctx: sys 
sp: 3ffff6c0 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffff860:  4022642d 00000000 00000000 00000001  
3ffff870:  00000002 00000000 402275a0 00000000  
3ffff880:  00000000 4022642d 00000000 40104927  
3ffff890:  40104908 3fffc100 00000000 00000000  
[...]
3fffff70:  40226492 3fff04b4 3fff079c 40226497  
3fffff80:  3fff09f4 3fff09e4 00000000 3ffeeac0  
3fffff90:  40220813 00000000 3fff079c 402283e7  
3fffffa0:  40000f49 3fffdab0 3fffdab0 40000f49  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v614f7c32
~ld

Exception (0):
epc1=0x402274e0 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4022642d depc=0x00000000

ctx: sys 
sp: 3ffee540 end: 3fffffb0 offset: 01a0
reaper7 commented 6 years ago

with sw serial and commented lines? I have no idea...

with hw serial - 18hours / 218106 readings without any error: schowek01

codmpm commented 6 years ago

I have to make sure, that my esp is not faulty... I will get back to you as soon as I have time to test... especially with hardware serial. I only testet it with softserial, yet...

Thanks for your time!

codmpm commented 6 years ago

I've used another ESP8266 - no nan's nor wdt resets, yet!! Still using Softserial with a 3.3V RS485-tranceiver.

How do you manage to flash while the RS485 tranceiver is also connected to the hardware serial? Should I enable it (VCC) from software to not feed the "programming data" to the tranceiver?

reaper7 commented 6 years ago

Nice to hear. I reflash by OTA

codmpm commented 6 years ago

Ok, I've implemented that already... finishing up the code to push some vars to mqtt. Will post it in a minute. Powered with 3.3V directly and I'm still using softserial: getting nan occasionaly, but not many.

Currently I think the nan readings have to do something with the power source. Powered with an LDO (AP2210K) I have many more nan's. I will hook the scope up to make a better assumption.

I've also tested with it the LDO and an added 330µF capacitor over the 3.3V line using softserial. This get's ma far less nan's... with a 1000µF I don't see nan's anymore... but I'm only testing right now.

codmpm commented 6 years ago

Here is what I came up with: https://github.com/codmpm/esp-sdm-mqtt

And, I also get nan's with the 1000µF capacitor over time... will update when I've hooked up the scope.

reaper7 commented 6 years ago

I'm using MeanWell din rail 5V power supply, connected directly to wemos d1 usb connector and converter powered from wemos 3.3V pin. Exactly like in this picture: https://user-images.githubusercontent.com/4134851/27516122-349b6124-59b3-11e7-8151-d3e8bafbced6.jpg

codmpm commented 6 years ago

Hm, I can't see anything faulty with the scope. Meanwhile I'm using hardware serial, which works like a charm.

Egyras commented 6 years ago

I'am using meanwell hdr-15-5 and connected 2 x Wemos D1 mini with https://www.aliexpress.com/item/TTL-turn-RS485-module-485-to-serial-UART-level-mutual-conversion-hardware-automatic-flow-control/32709226383.html converters. Both pairs shares same power supply. Seems only 1 pair works pretty stable and second one doesnt want to work normaly, both RX/TX leds blinks but rate is much lower..... Yesterday for half day both worked without isssues. Any suggestions, maybe just connect seperate power supply for second pair ? Power should be enough as meanwell hdr-15-5 can provide 2.4A

reaper7 commented 6 years ago

have you swapped pair? wemos1 to converter2 and wemos2 to converter1 to detect which element can cause errors. As I understand, you are using two sdm? If yes, you can use one pair for reading both sdm (with different ID)

Egyras commented 6 years ago

I have tried to swap, no luck. Even used different converter. When I conect seperate power supply seems no problems. Maybe some interference when 1 power supply is used. I plan to read more sdm, so need 2 wemos and 2 converters. At the moment 2 sdm working.

reaper7 commented 6 years ago

you can read up to 247 (with id from 1 to 247) devices from one pair (wemos+converter). all sdm must be set to the same baudrate but must have different id's then you read one by one with: sdm.readVal(SOME_REGISTER, 0x01); //for first sdm sdm.readVal(SOME_REGISTER, 0x02); //for second sdm etc...

Egyras commented 6 years ago

I pass all values via mqqt and need stability, will try to read several SDM from one pair.

reaper7 commented 6 years ago

I also pass values (but from one sdm) to home mqtt server and to remote thingspeak, the same values are available via internal esp8266 http server for live page and json for remote php requests, everything is done by one wemos module