Skip to content
reading SDM120 SDM220 SDM230 SDM630 modbus energy meters from esp8266 arduino
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples Update index_page.h Jun 25, 2018
img update imgs Apr 17, 2018
.gitignore update Jun 22, 2018
README.md
SDM.cpp an attempt to reduce the occurrence of error no.3 Oct 10, 2018
SDM.h additional sdm630 registers by @helianto Sep 3, 2018
SDM_Config_User.h cosmetic changes in the SDM_Config_User.h file Mar 20, 2019
keywords.txt new line init commit Jun 21, 2018
library.properties new line init commit Jun 21, 2018

README.md

WARNING! library initialization changed!

old library version is available at old_template branch

Library for reading SDM120 SDM220 SDM230 SDM630 Modbus Energy meters.

SECTIONS:

1. INTRODUCTION

2. SCREENSHOTS

3. CONFIGURING

4. INITIALIZING

5. READING

6. DEBUGING

7. CREDITS


Introduction:

This library allows you reading SDM module(s) using:

  • Hardware Serial (recommended option, smallest number of reads errors) or
  • Software Serial (library for ESP8266)

you also need rs232<->rs485 converter:

  • with automatic flow direction control (look at images below) or
  • with additional pins for flow control, like MAX485
    (in this case MAX485 DE and RE pins must be connected together to one of uC pin
    and this pin must be passed when initializing the library
    )

Tested on Wemos D1 Mini with Arduino IDE 1.8.3-1.9.0b & ESP8266 core 2.3.0-2.4.1


Screenshots:



live page example (extended) screenshot


Configuring:

Default configuration is specified in the SDM.h file, and parameters are set to:
Software Serial, baud 4800, uart config SERIAL_8N1, without DE/RE pin.

User can set the parameters in two ways:

  • by editing the SDM_Config_User.h file
  • by passing values during initialization (section below)

NOTE for Hardware Serial mode: to force the Hardware Serial mode,
user must edit the corresponding entry in SDM_Config_User.h file.
adding #define USE_HARDWARESERIAL to the main ino file is not enough.


Initializing:

If the user configuration is specified in the SDM_Config_User.h file
or if the default configuration from the SDM.h file is suitable
initialization is limited to passing serial port reference (software or hardware)
and looks as follows:

//lib init when Software Serial is used:
#include <SoftwareSerial.h>
#include <SDM.h>

SoftwareSerial swSerSDM(13, 15);

//              _software serial reference
//             |
SDM sdm(swSerSDM);


//lib init when Hardware Serial is used:
#include <SDM.h>

//            _hardware serial reference
//           |
SDM sdm(Serial);

If the user wants to temporarily change the configuration during the initialization process
then can pass additional parameters as below:

//lib init when Software Serial is used:
#include <SoftwareSerial.h>
#include <SDM.h>

SoftwareSerial swSerSDM(13, 15);

//              __________________software serial reference
//             |      ____________baudrate(optional, default from SDM_Config_User.h)   
//             |     |           _dere pin for max485(optional, default from SDM_Config_User.h)
//             |     |          |
SDM sdm(swSerSDM, 9600, NOT_A_PIN);


//lib init when Hardware Serial is used:
#include <SDM.h>

//            _____________________________________hardware serial reference
//           |      _______________________________baudrate(optional, default from SDM_Config_User.h)
//           |     |           ____________________dere pin for max485(optional, default from SDM_Config_User.h)
//           |     |          |            ________hardware uart config(optional, default from SDM_Config_User.h)
//           |     |          |           |       _swap hw serial pins from 3/1 to 13/15(optional, default from SDM_Config_User.h)
//           |     |          |           |      |
SDM sdm(Serial, 9600, NOT_A_PIN, SERIAL_8N1, false);

NOTE for ESP8266: when GPIO15 is used (especially for swapped hardware serial):
some converters (like mine) have built-in pullup resistors on TX/RX lines from rs232 side,
connection this type of converters to ESP8266 pin GPIO15 block booting process.
In this case you can replace the pull-up resistor on converter with higher value (100k),
to ensure low level on GPIO15 by built-in in most ESP8266 modules pulldown resistor.


Reading:

List of available registers for SDM120/220/230/630:
https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h#L50

//reading voltage from SDM with slave address 0x01 (default)
//                                      __________register name
//                                     |
float voltage = sdm.readVal(SDM220T_VOLTAGE);

//reading power from 1st SDM with slave address ID = 0x01
//reading power from 2nd SDM with slave address ID = 0x02
//useful with several meters on RS485 line
//                                      __________register name
//                                     |      ____SDM device ID  
//                                     |     |
float power1 = sdm.readVal(SDM220T_POWER, 0x01);
float power2 = sdm.readVal(SDM220T_POWER, 0x02);

NOTE: if you reading multiple SDM devices on the same RS485 line,
remember to set the same transmission parameters on each device,
only ID must be different for each SDM device.


Debuging:

Sometimes readVal return NaN value (not a number),
this means that the requested value could not be read from the sdm module for various reasons.

Please check out open and close issues, maybe the cause of your error is explained or solved there.

The most common problems are:

You can get last error code using function:

//get last error code
//                                      __________optional parameter,
//                                     |          true -> read and reset error code
//                                     |          false or no parameter -> read error code
//                                     |          but not reset stored code (for future checking)
//                                     |          will be overwriten when next error occurs
uint16_t lasterror = sdm.getErrCode(true);

//clear error code also available with:
sdm.clearErrCode();

Errors list returned by getErrCode:
https://github.com/reaper7/SDM_Energy_Meter/blob/master/SDM.h#L142

You can also check total number of errors using function:

//get total errors counter
//                                       _________optional parameter,
//                                      |         true -> read and reset errors counter
//                                      |         false or no parameter -> read errors counter
//                                      |         but not reset stored counter (for future checking)
uint16_t cnterrors = sdm.getErrCount(true);

//clear errors counter also available with:
sdm.clearErrCount();

Credits:

👍 ESP SoftwareSerial library by Peter Lerup (https://github.com/plerup/espsoftwareserial)
👍 crc calculation by Jaime García (https://github.com/peninquen/Modbus-Energy-Monitor-Arduino)
👍 new registers for SDM120 and SDM630 by bart.e (https://github.com/beireken/SDM220t)


2016-2018 Reaper7

paypal.me/reaper7md

You can’t perform that action at this time.