Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd numbers are read correctly, even numbers not #7

Closed
sjfaustino opened this issue Jan 12, 2017 · 38 comments
Closed

Odd numbers are read correctly, even numbers not #7

sjfaustino opened this issue Jan 12, 2017 · 38 comments
Labels

Comments

@sjfaustino
Copy link

When using the code below with a SDM120C:
`#include <SDM.h> //import SDM template library

SDM<2400, D1, D2> sdm; //SDM120C baud, rx pin, tx pin

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

void loop() {

Serial.print("Frequency: ");
Serial.print(sdm.readVal(SDM120C_FREQUENCY), 2); //display frequency
Serial.println("Hz");

Serial.print("Voltage: ");
Serial.print(sdm.readVal(SDM120C_VOLTAGE), 2); //display voltage
Serial.println("V");

delay(1000); //wait a while before next loop
}`
I get:

Frequency: 50.00Hz
Voltage: 228.70V
Frequency: 50.00Hz
Voltage: nanV
Frequency: 50.00Hz
Voltage: nanV
Frequency: 50.00Hz
Voltage: nanV
Frequency: 50.00Hz
Voltage: nanV
Frequency: 50.04Hz
Voltage: nanV
Frequency: 50.00Hz
Voltage: nanV

If I swap the read order as on the code below:
`#include <SDM.h> //import SDM template library

SDM<2400, D1, D2> sdm; //SDM120C baud, rx pin, tx pin

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

void loop() {

Serial.print("Voltage: ");
Serial.print(sdm.readVal(SDM120C_VOLTAGE), 2); //display voltage
Serial.println("V");

Serial.print("Frequency: ");
Serial.print(sdm.readVal(SDM120C_FREQUENCY), 2); //display frequency
Serial.println("Hz");

delay(1000); //wait a while before next loop
}`
I get:

Voltage: 231.20V
Frequency: 50.00Hz
Voltage: 230.80V
Frequency: nanHz
Voltage: 230.80V
Frequency: nanHz
Voltage: 230.80V
Frequency: nanHz
Voltage: 230.80V
Frequency: nanHz
Voltage: 231.30V
Frequency: nanHz

@beireken
Copy link
Contributor

Please try a delay(50); between each sdm.readVal.
It never works without here.

@sjfaustino
Copy link
Author

sjfaustino commented Jan 12, 2017

A delay(1) between reading each value seems to be sufficient.
Since 1ms is such a small delay, would it not be wise to add it on the library so that the user doesn't have to worry?

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

@reaper7
Copy link
Owner

reaper7 commented Jan 12, 2017

I can add this,
but I never had such a problems
I read all values one-by-one without any delay:

    sdmval.voltage = sdm.readVal(SDM220T_VOLTAGE);
    sdmval.current = sdm.readVal(SDM220T_CURRENT);
    sdmval.power = sdm.readVal(SDM220T_POWER);
    sdmval.frequency = sdm.readVal(SDM220T_FREQUENCY);
    sdmval.energy = sdm.readVal(SDM220T_TOTAL_ACTIVE_ENERGY);

my config: SDM220 at 4800 baud

maybe baudrate affected this?

If I find some free time, then I insert some debug code with count wrong/nan reading

@beireken
Copy link
Contributor

Not sure it's Baud related. I have 120c and 630 with 2400 and 9600 baud rate.
They both show this behaviour.

@reaper7
Copy link
Owner

reaper7 commented Jan 12, 2017

After 1 hour of tests with error counter, I don't have any wrong readings.

this is my code (sorry but not usable as is because it uses my priv helper lib for wifi connection/ota/oled)
as You see, I reading all values one-by-one without any delay between.
I add errors counter variable (errorscnt), incremented every 1000ms loop, if any of reading values are NAN,
but all readings from last hour (every 1000ms) are good!

#include <ESP8266WiFi.h>

#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncJson.h>

#include <ThingSpeak.h>

#include "ESP8266r7Helper.h"
#include "SDM.h"

AsyncWebServer server(80);

WiFiClient  client;

unsigned long myChannelNumber = xxxxxx;
const char * myWriteAPIKey = "XxXxXxXxXxXxXxXxXx";

unsigned long lastsdmreadtime = 0;                //store time of last smd read

bool dtardy = false;

uint16_t errorscnt = 0;                           //error counter for debug

//------------------------------------------------------------------------------
SDM<> sdm;

struct sdm_values {
  float voltage;
  float current;
  float power;
  float frequency;
  float energy;
} sdmval;
//------------------------------------------------------------------------------
void jsonrequest(AsyncWebServerRequest *request) {
  if (dtardy) {
    AsyncJsonResponse * response = new AsyncJsonResponse();
    JsonObject& root = response->getRoot();
    root["rp"] = String(sdmval.power,1);
    root["kw"] = String(sdmval.energy,2);
    root["rv"] = String(sdmval.voltage,1);
    root["rc"] = String(sdmval.current,2);
    root["rf"] = String(sdmval.frequency,2);
    root["er"] = String(errorscnt);

    response->setLength();
    request->send(response);
    request->client()->close();
  } else {
    request->send(404);  
  }
}
//------------------------------------------------------------------------------
void outrequest(AsyncWebServerRequest *request) {
  int params = request->params();
  for(int i=0;i<params;i++){
    AsyncWebParameter* p = request->getParam(i);
    Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
  }
  request->send(200, "text/plain", "OK");
}
//------------------------------------------------------------------------------
void setup() {
  devicename = "PWRMETER";

  sdmval.voltage = NAN;
  sdmval.current = NAN;
  sdmval.power = NAN;
  sdmval.frequency = NAN;
  sdmval.energy = NAN;
  
  Serial.begin(115200);

  oledinit();
  wifiinit();
  otainit();  
  
  sdm.begin();

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", String(ESP.getFreeHeap()));
  });  
  server.on("/data.json", HTTP_GET, jsonrequest);
  server.on("/out", HTTP_GET, outrequest);
  server.onNotFound([](AsyncWebServerRequest *request){
    Serial.println("404: not found");
    request->send(404);
  });
  server.begin();  

  Serial.println(ESP.getFreeHeap());
  oledprintline((String)ESP.getFreeHeap());

  delay(2000);
}
//------------------------------------------------------------------------------
void loop() {
  static unsigned long tsupload = 0;
  static float lastenergy = -1.00;
  static float sumpower = 0.00;
  static float measurecnt = 0.00;
  static uint16_t minutes = 0;

  float tmpvoltage = NAN;
  float tmpcurrent = NAN;
  float tmppower = NAN;
  float tmpfrequency = NAN;
  float tmpenergy = NAN;
  
  if ((!otalock) && (millis() >= (lastsdmreadtime + SDM_READ_EVERY))) {
    lastsdmreadtime = millis();

    tmpvoltage = sdm.readVal(SDM220T_VOLTAGE);
    tmpcurrent = sdm.readVal(SDM220T_CURRENT);
    tmppower = sdm.readVal(SDM220T_POWER);
    tmpfrequency = sdm.readVal(SDM220T_FREQUENCY);
    tmpenergy = sdm.readVal(SDM220T_TOTAL_ACTIVE_ENERGY);

    if ((isnan(tmpvoltage)) || (isnan(tmpcurrent)) || (isnan(tmppower)) || (isnan(tmpfrequency)) || (isnan(tmpenergy))) {   // if one of reading values is a NAN then set "dataready flag to false

      dtardy = false;
      errorscnt++;                                                                                                          // increment errorscnt for debug

      sdmval.voltage = 0.00;
      sdmval.current = 0.00;
      sdmval.power = 0.00;
      sdmval.frequency = 0.00;
      sdmval.energy = 0.00;

    } else {                                                                                                                // else -> every values != NAN

      sdmval.voltage = tmpvoltage;
      sdmval.current = tmpcurrent;
      sdmval.power = tmppower;
      sdmval.frequency = tmpfrequency;
      sdmval.energy = tmpenergy;

      dtardy = true;

      if (lastenergy == -1.00) {
        lastenergy = sdmval.energy;
      }

      sumpower += sdmval.power;
      measurecnt = measurecnt + 1.00;
  
      char buff[48] = {};
      sprintf(buff, "V:%7.2f\nA:%7.2f\nP:%7.2f\nF:%7.2f\0", sdmval.voltage, sdmval.current, sdmval.power, sdmval.frequency);
      
      oledprintline(buff, 0, true, Cousine_Bold_10, TEXT_ALIGN_CENTER);
  
      if (lastsdmreadtime >= (tsupload + 60000)) {
        char floatchr[12];

        minutes++;
  
        tsupload = lastsdmreadtime;
        
        ThingSpeak.begin(client);
        ThingSpeak.setField(1,dtostrf(sdmval.voltage,0,2,floatchr));
        ThingSpeak.setField(2,dtostrf(sdmval.current,0,2,floatchr));
        ThingSpeak.setField(3,dtostrf(float(sumpower / measurecnt),0,2,floatchr));
        ThingSpeak.setField(4,dtostrf(sdmval.frequency,0,2,floatchr));
        if (minutes == 59) {
          ThingSpeak.setField(5,dtostrf((sdmval.energy - lastenergy),0,2,floatchr));
          minutes = 0;
          lastenergy = sdmval.energy;
          ThingSpeak.setField(6,errorscnt);                                                                                         // every hour send errorscnt value to thingspeak for debug
          errorscnt = 0;                                                                                                            // errorscnt uploaded, set to 0
        }    
        ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  
        measurecnt = 0.00;
        sumpower = 0.00;
      }
    }
  }
  ArduinoOTA.handle() ;                           // Check for OTA
}

this is a prototype code but works ~129days without a problems

@reaper7
Copy link
Owner

reaper7 commented Jan 12, 2017

one more thing...
how is Your connection between SDM and converter?
two wire (A&B) or three wire (A&B&GND)
I have 3 wire...

@sjfaustino
Copy link
Author

sjfaustino commented Jan 12, 2017

I'm using a Wemos D1 mini (esp8266) connected to this ttl2rs485: https://www.aliexpress.com/item/TTL-turn-RS485-module-485-to-serial-UART-level-mutual-conversion-hardware-automatic-flow-control/32709226383.html

Wemos mini to TTL2RS485:
Wemos D1 to TX TTL2RS485
Wemos D2 to RX TTL2RS485
Wemos GND to GND TTL2S485
Wemos 3.3V to VCC TTL2RS485

TTL2RS485 to SDM120C
B to pin9
A to pin10
GND not connected (don't know what is the gnd pin on the sdm120c, maybe 8?)

So, 2 wire. Also, no 120 ohm resistor in use ( I believe it is only necessary on long cable runs).

I sugest adding a ifdefine add_sdm_delay to the library and let the user do a #define add_sdm_delay if he wants.

@reaper7
Copy link
Owner

reaper7 commented Jan 12, 2017

I can't reproduce this error.
On my hardware configuration, example from this lib and my other project works without problem,
so...at this moment please add delays to Your main program or clone this lib and do this on Your copy.

GND...maybe 8:
http://techfreak.pl/miernik-zuzycia-energii-elektrycznej-sdm120/sdm120-connection/
http://eastron.inf.ua/SDM120.html

@reaper7
Copy link
Owner

reaper7 commented Jan 13, 2017

after 14 hours still no errors

@reaper7
Copy link
Owner

reaper7 commented Jan 16, 2017

@beireken - do You check if this problem also exists when converter is connected via hardware serial?

I checked this problem whole weekend, code read all fourteen SDM220 registers at once in loop every 2sec and after 2 days I have only 37 errors
where number of all reading = 48h * 60m * (60s/2) = 86400 readings

I must check if problem is a timeout/bad checksum/not enough bytes read

@beireken
Copy link
Contributor

beireken commented Jan 17, 2017

@reaper7 Do you mean changing the library to function with hardware serial and not softserial?
Or just using the pins of tx and rx and not random other.?

@reaper7
Copy link
Owner

reaper7 commented Jan 17, 2017

no no, this lib is ready for use with hardware serial,
user must set at top of sketch:

#define USE_HARDWARESERIAL

before:

#include <SDM.h> 

If You not tested yet hardware serial functionality of this lib then no question :D

Today I added a few fix, maybe some reading errors disappear...

@beireken
Copy link
Contributor

Hmm I did not know that. I will test this when I get the chance and report back.

@reaper7
Copy link
Owner

reaper7 commented Jan 17, 2017

ok, tnx.
You can test software serial too, without any delay between each sdm read

reaper7 added a commit that referenced this issue May 7, 2017
fix for issue with nan reading by sjfaustino:
#7 (comment)
#8 (comment)
@mariusz84pl
Copy link

Im trying to use your code from above but im missing this library ESP8266r7Helper.h
Where can i find it?

@reaper7
Copy link
Owner

reaper7 commented Jun 16, 2017

@mariusz84pl - this is my private lib, only for connect to wifi, configure ota and print lines on oled display.
You can replace my functions:

  oledinit();
  wifiinit();
  otainit(); 
  oledprintline("some text");

with Your own solution.
I do not publish this lib because it contains many private data like passwords etc.

@mariusz84pl
Copy link

mariusz84pl commented Jun 25, 2017

I'm trying to use hardwareserial cut can't get to work with it. TX working but no RX.

in sketch added #define USE_HARDWARESERIAL on top.
I'm using nodemcu dev Lolin, connecting to TX, RX in it. Is there something else to be added or removed?

#define USE_HARDWARESERIAL
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncJson.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
#include "SDM2.h"

@reaper7
Copy link
Owner

reaper7 commented Jun 25, 2017

added or removed? I don't know what is needed in Your application.

What kind of converter you are using, with or without DE/RE pins ?
Maybe You swap tx / rx lines?

@mariusz84pl
Copy link

I have this one
https://www.aliexpress.com/item/TTL-turn-RS485-module-485-to-serial-UART-level-mutual-conversion-hardware-automatic-flow-control/32709226383.html

Tryed every combination of connection TX/RX and can't get any values

@reaper7
Copy link
Owner

reaper7 commented Jun 25, 2017

I use the same :)

so, I just tested this simple sketch with hw serial (my sdm is set to 9600b!!!):

#define USE_HARDWARESERIAL

#include <SDM.h>

SDM<9600> sdm;

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, HIGH);
  sdm.begin();
}

void loop() {
  float tmpval = NAN;
  
  tmpval = sdm.readVal(SDM220T_VOLTAGE);

  if (!isnan(tmpval)) {
    digitalWrite(BUILTIN_LED, LOW);
  }
  
  delay(1000);
  digitalWrite(BUILTIN_LED, HIGH);
}

led blinks, it's mean reading ok

this is my "hardware" ;)

sdm2

@mali-x
Copy link

mali-x commented Mar 21, 2018

I have WEMOS d1 mini.
What does the error
ets Jan 8 2013,rst cause:4, boot mode:(1,7)

wdt reset

@reaper7
Copy link
Owner

reaper7 commented Mar 21, 2018

@mali-x
Copy link

mali-x commented Mar 21, 2018

This happens to me when I want to test Sdm_live_page.

@reaper7
Copy link
Owner

reaper7 commented Mar 21, 2018

at start or whether during operation?
example modified in some way?
it connects to the access point?

@mali-x
Copy link

mali-x commented Mar 21, 2018

Error appears at the beginning. With programming i do not have problem. It is, when the program start on esp.
I used your DEMO Sdm_live_page

@reaper7
Copy link
Owner

reaper7 commented Mar 21, 2018

example sdm_simple works for You?

@mali-x
Copy link

mali-x commented Mar 21, 2018

sorry,
yes sdm_simple works.
on esp works others examples with wifi

@reaper7
Copy link
Owner

reaper7 commented Mar 21, 2018

I removed some external libs(for display the time) from example, please download again and try.

You are using hardware or software serial? If softwareserial, then on which pins?

Try debuging code yourself by inserting Serial.print("something"); in different places, to detect the error location.

@mali-x
Copy link

mali-x commented Mar 22, 2018

reinstall arduino and libraries
SDM120 pin 13/15 or 12/14

ets Jan 8 2013,rst cause:4, boot mode:(3,7)

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

@reaper7
Copy link
Owner

reaper7 commented Mar 22, 2018

sorry but I cant duplicate this issue,
with core debug enabled I got on hardware serial console:

10f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v00000000
~ld

SDK:2.2.1(cfd48f3)/Core:win-2.5.0-dev/lwIP:2.0.3(STABLE-2_0_3_RELEASE/glue:arduino-2.4.1)
sta config unchangedscandone
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 3
cnt 

connected with TP-LINK_XXXXXX, channel 11
dhcp client start...
ip:192.168.6.37,mask:255.255.255.0,gw:192.168.6.1
pm open,type:2 0
:urn 41
:urd 12, 41, 13
:urd 4, 41, 26
:urd 5, 41, 31

web page works

this is my code:

//sdm live page example by reaper7

//#define USE_HARDWARESERIAL
#define READSDMEVERY  2000                                                      //read sdm every 2000ms
#define NBREG   6                                                               //number of sdm registers to read
//#define USE_STATIC_IP

/*  WEMOS D1 Mini                            
                     ______________________________                
                    |   L T L T L T L T L T L T    |
                    |                              |
                 RST|                             1|TX
                  A0|                             3|RX
                  D0|16                           5|D1
                  D5|14                           4|D2
                  D6|12                    10kPUP_0|D3
RX SSer/HSer swap D7|13                LED_10kPUP_2|D4
TX_SSer/HSer swap D8|15                            |GND
                 3V3|__                            |5V
                       |                           |
                       |___________________________|
*/

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>

#include <ESPAsyncTCP.h>                                                        // https://github.com/me-no-dev/ESPAsyncTCP
#include <ESPAsyncWebServer.h>                                                  // https://github.com/me-no-dev/ESPAsyncWebServer

#include <SDM.h>                                                                // https://github.com/reaper7/SDM_Energy_Meter

#include "index_page.h"
//------------------------------------------------------------------------------
AsyncWebServer server(80);

#if !defined ( USE_HARDWARESERIAL )                                             // SOFTWARE SERIAL
SDM<4800, 13, 15, NOT_A_PIN> sdm;                                               // baud, rx_pin, tx_pin, de/re_pin(not used in this example)
#else                                                                           // HARDWARE SERIAL
SDM<4800, NOT_A_PIN, false> sdm;                                                // baud, de/re_pin(not used in this example), uart0 pins 3/1(false) or 13/15(true)
#endif
//------------------------------------------------------------------------------
String devicename = "PWRMETER";

#if defined ( USE_STATIC_IP )
IPAddress ip(192, 168, 0, 130);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
#endif

const char* wifi_ssid = "TP-LINK_XXXXXX";
const char* wifi_password = "12345678";

String lastresetreason = "";

unsigned long readtime;
volatile bool otalock = false;
//------------------------------------------------------------------------------
typedef volatile struct {
  volatile float regvalarr;
  const uint16_t regarr;
} sdm_struct;

volatile sdm_struct sdmarr[NBREG] = {
  {0.00, SDM220T_VOLTAGE},                                                      //V
  {0.00, SDM220T_CURRENT},                                                      //A
  {0.00, SDM220T_POWER},                                                        //W
  {0.00, SDM220T_POWER_FACTOR},                                                 //PF
  {0.00, SDM220T_PHASE_ANGLE},                                                  //DEGREE
  {0.00, SDM220T_FREQUENCY},                                                    //Hz
};
//------------------------------------------------------------------------------
void xmlrequest(AsyncWebServerRequest *request) {
  String XML = F("<?xml version='1.0'?><xml>");
  if(!otalock) {
    for (int i = 0; i < NBREG; i++) { 
      XML += "<response" + (String)i + ">";
      XML += String(sdmarr[i].regvalarr,2);
      XML += "</response" + (String)i + ">";
    }
  }
  XML += F("<freeh>");
  XML += String(ESP.getFreeHeap());
  XML += F("</freeh>");
  XML += F("<rst>");
  XML += lastresetreason;
  XML += F("</rst>");
  XML += F("</xml>");
  request->send(200, "text/xml", XML);
}
//------------------------------------------------------------------------------
void indexrequest(AsyncWebServerRequest *request) {
  request->send_P(200, "text/html", index_page); 
}
//------------------------------------------------------------------------------
void ledOn() {
  digitalWrite(LED_BUILTIN, LOW);
}
//------------------------------------------------------------------------------
void ledOff() {
  digitalWrite(LED_BUILTIN, HIGH);
}
//------------------------------------------------------------------------------
void ledSwap() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
//------------------------------------------------------------------------------
void otaInit() {
  ArduinoOTA.setHostname(devicename.c_str());

  ArduinoOTA.onStart([]() {
    otalock = true;
    ledOn();
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    ledSwap();
  });
  ArduinoOTA.onEnd([]() {
    ledOff();
    otalock = false;
  });
  ArduinoOTA.onError([](ota_error_t error) {
    ledOff();
    otalock = false;
  });
  ArduinoOTA.begin();
}
//------------------------------------------------------------------------------
void serverInit() {
  server.on("/", HTTP_GET, indexrequest);
  server.on("/xml", HTTP_PUT, xmlrequest);
  server.onNotFound([](AsyncWebServerRequest *request){
    request->send(404);
  });
  server.begin();
}
//------------------------------------------------------------------------------
static void wifiInit() {
  WiFi.persistent(false);                                                       // Do not write new connections to FLASH
  WiFi.mode(WIFI_STA);
#if defined ( USE_STATIC_IP )
  WiFi.config(ip, gateway, subnet);                                             // Set fixed IP Address
#endif
  WiFi.begin(wifi_ssid, wifi_password);

  while( WiFi.status() != WL_CONNECTED ) {                                      //  Wait for WiFi connection
    ledSwap();
    delay(100);
  }
}
//------------------------------------------------------------------------------
void sdmRead() {
  float tmpval = NAN;

  for (uint8_t i = 0; i < NBREG; i++) {
    tmpval = sdm.readVal(sdmarr[i].regarr);

    if (isnan(tmpval))
      sdmarr[i].regvalarr = 0.00;
    else
      sdmarr[i].regvalarr = tmpval;

    yield();
  }
}
//------------------------------------------------------------------------------
void setup() {
#ifndef USE_HARDWARESERIAL
  Serial.begin(115200);
#endif
  pinMode(LED_BUILTIN, OUTPUT);
  ledOn();

  lastresetreason = ESP.getResetReason();

  wifiInit();
  otaInit();
  serverInit();
  sdm.begin();

  readtime = millis();

  ledOff();
}
//------------------------------------------------------------------------------
void loop() {
  ArduinoOTA.handle();

  if ((!otalock) && (millis() - readtime >= READSDMEVERY)) {
    sdmRead();
    readtime = millis();
  }

  yield();
}

@mali-x
Copy link

mali-x commented Mar 28, 2018

Hello.

Thank you very much for all your help and informations. I did my web.
But now i have another problem. :) In Simple Program is between datas NAN. I changed pin and changed delay and all other things. By every measure is ther one NAN. What i did wrong and where is the problem?

Best Regards, M. Rotovnik

@reaper7
Copy link
Owner

reaper7 commented Mar 28, 2018

all measurements in one loop run are NAN?
or
one incorrect reading in each loop (random, sometimes voltage, sometimes frequency etc...)?

what you changed?
7 days ago you wrote (#7 (comment)):

sorry,
yes sdm_simple works.
on esp works others examples with wifi

@mali-x
Copy link

mali-x commented Mar 28, 2018

I have SDM120
and
https://www.aliexpress.com/store/product/10PCS-LOT-TTL-turn-RS485-module-485-to-serial-UART-level-mutual-conversion-hardware-automatic-flow/403088_32709166081.html

Example :sdm_simple change serial PIN
SDM<2400, 4, 5> sdm;
or
SDM<2400, 14, 16> sdm;
or
SDM<2400, 13, 15> sdm;

Change delay time:
if (_dere_pin != NOT_A_PIN)
digitalWrite(_dere_pin, HIGH);
delay(2);

Change delay :
.....
Serial.print(sdm.readVal(SDM220T_VOLTAGE), 2);
delay(50);
Serial.print(sdm.readVal(SDM220T_CURRENT), 2);
delay(50);
......

Change SDM120 - SDM220
sdm.readVal(SDM120C_CURRENT
sdm.readVal(SDM220T_CURRENT

............................
Random NAN
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: 0.00W
Frequency: 50.04Hz
�[1;0HVoltage: nanV
Current: 0.00A
Power: 0.00W
Frequency: 50.09Hz
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: nanW
Frequency: 50.09Hz
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: 0.00W
Frequency: 50.09Hz
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: 0.00W
Frequency: 50.04Hz
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: 0.00W
Frequency: 50.09Hz
�[1;0HVoltage: 236.10V
Current: nanA
Power: 0.00W
Frequency: nanHz
�[1;0HVoltage: 236.10V
Current: 0.00A
Power: 0.00W
Frequency: nanHz

@reaper7
Copy link
Owner

reaper7 commented Mar 29, 2018

try to check which error causes a bad reading,
add after every reading (before delay):

Serial.print("Last ERROR: ");
Serial.println(sdm.getErrCode(true));

Have you tried other speeds? 4800?

I still suggest switching to HardwareSerial which I personally use.
I read all 14 SDM220 registers in loop every 3sec with only yeld() between every register(without any delay), what it takes ~470ms
and after last 15hours I have only two errors. 14registers * 20readings every minute * 60min * 15h = 252000readings and only 2 errors...

@mali-x
Copy link

mali-x commented Mar 29, 2018

Error 4.
Speed 4800 to SDM120 does not work

�[1;0HVoltage: 230.50V
Last ERROR: 0
Current: nanA
Last ERROR: 4
Power: 0.00W
Last ERROR: 0
Frequency: 50.00Hz
Last ERROR: 0
�[1;0HVoltage: 230.40V
Last ERROR: 0
Current: 0.00A
Last ERROR: 0
Power: 0.00W
Last ERROR: 0
Frequency: nanHz
Last ERROR: 4
�[1;0HVoltage: nanV
Last ERROR: 4
Current: 0.00A
Last ERROR: 0
Power: 0.00W
Last ERROR: 0
Frequency: 50.00Hz
Last ERROR: 0

@reaper7
Copy link
Owner

reaper7 commented Mar 29, 2018

error 4 -> SDM_ERR_TIMEOUT
this means that at the declared time (in this case 500ms)
esp serial did not get full reply frame (9 bytes) from sdm.

Try to increase MAX_MILLIS_TO_WAIT
in line 18 https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h#L18
from 500 to e.g. 1000
maybe 500ms is too low for Your baud rate 2400

@mali-x
Copy link

mali-x commented Apr 1, 2018

Thank you for all informations.
I change all times, but nothing helps.

How can I change the speed from 2400 to 4800?

I would not yous Tx in Rx pin, because I allready use them for Serial.print.

@reaper7 reaper7 closed this as completed Jul 5, 2018
kaebmoo added a commit to kaebmoo/SDM_Energy_Meter that referenced this issue Sep 20, 2018
@janbro1
Copy link

janbro1 commented Jun 16, 2019

Thank you for all informations.
I change all times, but nothing helps.

How can I change the speed from 2400 to 4800?

I would not yous Tx in Rx pin, because I allready use them for Serial.print.

I have the very same setup as descibed here. I also changed the MAX_MILLIS_TO_WAIT to 1500 to be on the safe side. But I continue to receive the error code 4 as well. If possible I would like to stay with 2400 baud. Simply because I don't have the software to change it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants