I had obtained three samples of a DDM18SD DIN rail mounted energy meter unit. I got mine from a UK supplier on eBay, but they are available here at AliExpress and in many different places. The unit I obtained was a single phase unit for directly measuring up to 5A and 240V AC, but up to 100A with a 100:5 current transducer.

The best thing about this unit is that, apart from having a display of the various values on the front, it also has an RS485 interface which uses MODBUS-RTU to get and set information from the meter. This should allow me to get voltage, current, power factor, real and reactive power, which I can the record with a datalogger. It also has a pulse output for every 1/1000th of a kWh. This might be useful, but more info from the RS485 is better!

Getting set up I put the unit into a decent enclosure with the display through the top. I’m only using an amp or so, so thin cables used for this test version. When it started up it showed 021 (unit ID) , 9600 (baud rate) , 1000 (impulses per kWh) and then starts to display the parameters.

I set up a Sparkfun USB to RS485 converter. I had used this before for initial testing of RS485 networks. It’s incredibly useful, especially for initial set-up & fault finding! I installed RealTerm onto my (Windows) computer. This is a highly configurable serial port terminal read/write program which is highly recommended.

I read from the booklet (also info in the AliExpress link above) that the voltage from the unit can be obtained by requesting data from a specific register (this is MODBUS-RTU protocol). You need to have the device ID and also a CRC (error) check. I used the example from the booklet of sending “01 04 00 00 00 02 71 CB”. This is in HEX. So to send that I needed to write “0x01 0x04 0x00 0x00 0x00 0x02 0x71 0xCB”. I sent this info, but got nothing back!

So I realised I had the wrong device ID. This request is for device ID “01” and my unit is 021 according to the start up menu. So I tried with “21 04 00 00 00 02 76 AB”. The “76 AB” were calculated with an online CRC calculator, here. I put in the first part of the hex number and clicked on “HEX”. I then calculated CRC-16, as this is a 4 digit HEX CRC check. You then need to scroll down to CRC-16/MODBUS and this is the CRC to use. But you also need to put the last two digits first (so “AB76” becomes “76AB”). So I tried this out, but still got nothing back!!

So the next thing I realised is that I have the device ID in decimal, not HEX. So converting 21 (decimal) into 15 (HEX) and then re-calculating the CRC check, I got “15 04 00 00 00 02 72 DF”. I put this into RealTerm and sent the line “0x15 0x04 0x00 0x00 0x00 0x02 0x72 0xDF”. I got something back!! Whoop! So now I know that communications works and that I have A and B of the RS485 correct.

The next step was to use an Arduino Nano unit and a MAX485 module. These are both freely available and low cost. The MAX485 unit is ‘half duplex’ which means you have to control when the unit is sending data and when it is receiving data. This is done with an additional digital pin and I soldered together the DE/RE pins so I just had one wire to this joint pin. I connected digital pin 10 to Software Serial Rx, digital pin 11 to Software Serial Tx and digital pin 9 to the DERE pin. Excuse the bad photo and wiring, but this was a quick test!

I found an arduino library for these energy meter modules. There are a range of energy meters, including the SDM (three phase units) and the DDM (single phase units). The Arduino library (SDM_Energy_Meter) is not in the library repository, so I needed to download the .zip from the GITHUB repository and install using the ‘install .zip’ in Arduino IDE. This has a config file to control the baud rate and digital pins required. I adjusted this for my set-up and uploaded code.

It worked and started to send data via the RS485 (I checked by looping the data back into my computer through the USB-RS485 unit). But the data was not correct. It only showed me the correct data when I set the ‘Parity’ to NONE for the serial settings. So something is not right. I checked the Energy Meter booklet again and it says that the unit must have ‘EVEN’ parity. Parity looks at all the bits in the byte being sent. With EVEN parity, if the total number of set bits are odd, then it is set high (to make total bits set high even). If the total set bits are even, then this is set to zero.

I did a double check with my DDM18SD unit. I used the USB-RS485 converter and sent the correct code with no parity. There was no reply from the unit. If it was set to even parity then it worked and I got an answer back. So I needed EVEN parity. I was using SoftwareSerial for the serial comms to the MAX485. I needed to keep the hardware serial free for other uses. But SoftwareSerial arduino library does not let you set the parity. There is no parity on that library.

So I needed to find a software serial library with parity. I found this called (you guessed it) ‘SoftwareSerialParity’. This did not work directly with the SDM library. I needed to change all the references to SoftwareSerial to SoftwareSerialParity. I also needed to add the baud and parity type to the begin command of SoftwareSerialParity. This took a bit of messing around. I decided to bring the two libraries into my project, as I had converted them slightly. I needed to remove references within my arduino library folder (as they conflicted). And I also used local references for the .h files. But this seemed to work and I uploaded the code & it built. I then looked at the output on the USB-RS485 converter and, sure enough, I was seeing the correct HEX data being sent when ‘EVEN’ parity was selected.

The next thing was to wire this up to my DDM18SD and try and get data back. This worked OK! See the RS485 terminal here and the arduino serial port output:

In that blob of code you can (maybe) see that I am sending “15 04 00 00 00 02 72 DF” and then I get back a bit of data. The arduino code converts that into the value, which can be seen on the serial port. This is voltage and shows 247.00V..

I’ve done a quick repository for this simple test code which works with an Arduino Nano talking to the DDM18SD with a MAX485 and EVEN parity. The repository is here if it is useful to you:


Hope thats some use to others – it took me a day or so of head scratching to get to this point. I’m going to incorporate the code into my remote monitoring unit to relatively easily measure isolated AC powers.

Using a Pro-Mini 3.3V Unit to talk to the DDM18SD

I wanted to use the unit with an Arduino Pro Mini running at 3.3V. This caused more issues! I used the 3.3V version of the MAX485 (The MAX3485, from Farnell here). I replaced the MAX485 on the converter board I had.  Also I needed to lower the baud rate for the data from 115200 for serial and 9600 for software serial to 57600 for serial and 1200 for software serial. This did not work! I can see that the data is being written correctly and being returned correctly, but the softwareserial buffer returns all zeros. I can do fake data which does show using the RS485 unit. The code runs correctly on a Nano powered by 5V. So I think maybe something to do with timing for the software serial port?

I tried changing the baud rate to 2400 to see if that helped.

To do this I check the example to change to 1200 baud rate, which was: 01 10 00 00 00 02 04 “44 96 00 00” 07 73. The bit in quotes is the baud rate value, but how?…

I used this conversion program to change from HEX to floating point: https://gregstoll.com/~gregstoll/floattohex/

I can see that in an example writing 44 96 00 00 sets 1200 baud rate. Using the above converter I can see that 44 96 00 00 is 1200 in floating point.

So I converted 2400 to hex which is 45 16 00 00. With my ID number of 15 & with CRC applied the actual code to send is: 15 10 00 00 00 02 04 45 16 00 00 46 97. Lets see if that works!

Yes – it changed the baud rate to 2400. Let see if the Pro Mini works…

Still nothing back in the receive of the pro-mini.

I do see that the DDM18SD requires 5-24V to work. This is not provided by the pro-mini. But what is strange is that the RS485 converter sees the correct data being sent back. So the AC monitor is sending back correct HEX data.

I’m getting an error code ‘2’ which is “SDM_ERR_WRONG_BYTES”. I can see the bytes are all zero. So it’s getting something back but not converting it quickly enough. Could going faster help?

Setting the baud rate to 9600 is 46 16 00 00, so I needed to send: 15 10 00 00 00 02 04 46 16 00 00 46 D3.

Ah! This gives me data in the frame buffer, so I’m getting there. It is reading an additional 0 at the start, so lets hack the code to read one more byte and dismiss the first byte.

I decided (after a lot of playing) to use a 3.3V top 5V converter and a level shifter for the data. I used a CD40109 level shifter (as I had one lying around). I uses a low power 3.3 to 5V DC-DC converter. I put the transmit line and the direction control for the 5V version of the MAX485 TTL to RS485 IC. I also tried to use the receive pin through this, but it did not work. I also tried using a resistor voltage divider to reduce the 5V to 3.3V. This also did not work! I then just tried putting the receive line directly into the Rx of softwareSerialParity line on the Pro-Mini. This worked!

The data is not totally reliable but 90% of the time I get data back. I’m going to try with a bi-directional level shifter to check that works. But basically with a DC DC converter to give me 5V locally and a level shifter, I can use the 5V version of the MAX485 to give me RS485 with EVEN parity which talks to the DDM18SD energy monitor. This is not ideal (additional energy lost through the DC-DC converter) but at least it works!

17 responses to “Talking to a DDM18SD Energy Meter

  1. Hi Matthew,
    I’m trying to connect a DDM18SD meter to a MEGA2560 Serial1 using a MAX485.
    I uncommented #define USE_HARDWARESERIAL and left the above #undef USE_HARDWARESERIAL commented in SDM_Config_User.h .
    Changed Rx/Tx pin numbers to MEAG2560 Serial1 hardware pins (18&19) and DERE to D9 in SDM_Config_User.h
    Get nanV in serial monitor.
    What am I doing wrong here?

    1. Hmmmm. Afraid it’s quite hard to fault find that kind of thing via email.
      I would suggest:
      Check baud rate of the DDM18SD – is it definitely what you want?
      Do you have an RS485 to USB converter? (I use one of these from Sparkfun: https://www.sparkfun.com/products/9822)
      This really helped me. I then used a serial terminal program to see any data being sent back. This shows data even if its not correct and really helps with fault finding.
      Once I was able to send a command via the RS485 converter and a serial terminal program, then I sent on to use the arduino to connect.
      So I suppose its breaking the project in two: Is communication to the meter OK? Is data to/from the Arduino OK? Then get them to talk.
      Best of luck with it all. Please comment here if you find anything strange for why its not communicating.


    1. Hi,
      I’m not sure you can (but I could be wrong). I think this might be a tamper feature to stop people saying they have used less energy than they have!
      So only way to record it is to set the reading at the start as your zero point and see changes from there…

  2. Hi there,
    I built a script, using tasmota scripting language, to read this meter. It works perfectly.
    Opened yesterday an issue on Tasmota smart meter docs repository on Github to add this meter and its script in the examples list. Waiting for approval. If interested in, take a look there.

  3. Hi, can you create a daisy chain of RS485 meters? Is there a way to change each unit Modbus IDs so that you can read them in chian? Thanks!

    1. Hi!
      Yes – you can daisy chain RS485 together (and thats the best way of connecting together RS485 devices: https://www.se.com/ww/en/faqs/FA221785/).
      You can set the meter address to any value from 1 – 247. Remember value written to unit is in HEX, so its 01 to F7 in HEX.
      Check out this example to change the parameter:
      DDM18SD change address
      I did do this to my meter, but I only have one, so have not tried daisy chaining.
      Hope thats useful,

    1. Hi Panos,
      Taken me a while to reply!
      It should be possible with that RS485 adaptor. The main things to check are that the baud rate is OK, and you must use EVEN parity (this is not a default).
      While it might not help you now, it might be useful to others in the future.

  4. Hi, I was wondering if you could provide a bit more detail regarding the 100:5 transducer mentioned?

    I have been looking at these meters for an automation project but I require them to measure power usage on several ring mains (32A UK Domestic).

    I was hoping to use a few of these inside a consumer unit housing but I have been unable to find any further details on what you have mentioned with usage of a transducer?

    Many thanks

    1. Hi,
      I’m meaning a current transformer:
      Current Transformer Basics

      This is a transformer that usually clips around the cable under test and gives a reduced output signal which can be measured. In the case of the 100:5 ratio CT then if 100A is flowing in the primary then we get 5A flowing in the secondary. The DDM18SD is designed for a maximum of 5A, but can measure up to 100A if a 100:5 CT is used.

      Hope thats some help.

Leave a Reply

Your email address will not be published. Required fields are marked *