emonDC Development

Thanks for the worry :slight_smile:

I’ve a digital soldering Hako, yes i can solder it.

Well noted for the short of R22 and C33. You are right.

Thank you for your patience :smiley:

I’ve added more to the firmware today, the previous above doesn’t retain settings properly. My challenge was an already full EEPROM from previous settings-implementation.

I’ve almost got working a ‘JSON settings file’ method now. I’m reading from the file okay, just trying to get the writing working now.

Might be worth the wait.

edit: @G-deville can’t quite believe it, I have the JSON settings working, reading and writing.
emonESP_MAR2020.zip (2.1 MB)


I’m very new to openenergymonitor.
I’d like to monitor battery voltage of 12-24-48V with emonDC.
Can you help me out on the items I need to purchase ?

Many thanks !

Hi Jean, I’m not fulfilling orders right now.
If you need to monitor voltage only on a single battery emonDC could be over-the-top.
Is it only voltage you’re monitoring? What do you want to do with the data, store it locally or send it on? Maybe there’s another way…

Hello Daniel,

I’d like to send it to a remote server.
Yes as a first prototype it will be voltage monitoring only.
What do you have in mind ?

Many thanks for your quick reply !


Are you familiar with these…

NodeMCU module & MCP3208 DIP :

These two components could be the basis of cost-effective voltage monitoring over WiFi, plus stripboard, wire, solder perhaps, and common resistors, capacitors, and a 5V supply.

Depends how DIY you want to get.

Just remembered I documented some of the process here:
. MCP3202 ADC, SPI and ESP

The latest PCB has been simplified to a resistor divider with a capacitor for filtering.

2020-04-11 08.33.24 copy 2 voltage
(no input protection shown)
and then frequency response is worked out using R2 and C1, assuming R1 is much much greater than R2, which is probably what you want.

and then the ‘high impedance source to ADC’ problem is solved by having the ADC sample slow enough, that’s done in firmware with entering an SPI clock speed. The speed I’ve chosen is good with R2 at 75k, although C1 helps so without calculating it’s hard to say exactly what sampling rate / impedance combinations are accurate.

That help?

This post is a dump of stuff I’ve done in the last period working on DC monitoring.

First, I’ve made some changes and additions to the OLED display, in conjunction with the button pressing.
OLED default behaviour is On and cycling through views of different pages of data.
If a button is pressed on GPIO0 then the display and changing page will become dependant on button presses, and be Off by default (after 10 seconds of no button). I made a couple of graphics for charging and discharging too.

I could’ve remade the video after the radio unexpectedly turned on, but it was Ivor Cutler, so left it as it was.

Second, the problems a couple of users have had with inaccurate voltage readings when using the buck reg of my own design was due mostly to the complete lack of filtering at the voltage divider. The same noisy problem travelled into the current readings so it was all shambles really. I’ve worked out the filters on current and voltage channels to cancel out the noise of the buck, and noise more generally I hope. The buck operated at around 400kHz and appeared easy enough to filter out.
2020-04-11 08.33.24 copy current
This shows a very simple filter arrangement dependant on the fuses themselves, which have a rated resistance. In the video above one can see the TR5 fuse holders I’d used to work out a suitable combination of R and C. I checked also that the charging of the capacitor wasn’t blowing the fuse, there was a condition where the charging of a large cap was blowing a 50mA fuse. I did this check at 32V, and settled on 150mA fuses.
An alternative filter is depicted downstream of the shunt monitor, I’ve not done that, but will be possible in future PCBs just in case.

Third, the variant of emonESP used has had an upgrade, which most importantly could solve the WiFi dropping out issue. I’ve copied openEVSE code to put the web pages into progmem which means flashing requires one file, and can completely upgrade the firmware+web server in one flash, or OTA, or with a file dropped into the web-interface (note the security implications of this!).
I’ve finally got fluent at navigating the excellent code by J.Poulter and also the program VS Code I must say is fantastic, and makes navigation much easier because of the Find and Go To tools. I don’t know another editor which does this so well.

(I think right-click and view image to zoom in).
This shows a bunch of settings I’ve imagined will be useful to battery monitors and general board-hacking. Imagined being a key word… I’ve tested all of it but in practice I guess things can be added and others taken away. I have one test set up here but time will tell.

What else… Peukert!
Thanks to another user making me aware of this, I’ve implemented State of Charge monitoring using the Peukert exponent, or coefficient, to give an idea of the true usable amount of energy remaining in the battery. This is in addition to counting coulombs. Using the Peukert coefficient gives a more accurate idea because it factors in the changing efficiency of discharge against the rate of discharge (or charge). Meaning the faster one takes energy from a battery the less usable energy there will be in total, as the increased internal resistance of the battery will dissipate more greatly.
Still lacking from this firmware is monitoring of the temperature of the environment and batteries, and factoring in of the age of the batteries, all of which would add to accuracy. Age could be adjusted for manually in the settings by decreasing the capacity.

Example code:

#include <stdio.h>
#include "soc.h"
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <unistd.h>

// test input data
double Current_B = 5; // amps
// initial SoC for test:
double state_of_charge = 1.00 ; // 1 = 100% percent

// battery data.
double Hr = 20.0; // rated time in hours
double k = 1.3; // approx. Peukert exponent for flooded lead-acid.
double C = 100.0; // capacity of battery at rated time (Ah)

char log_buffer[200];
int period = 5;
time_t current_time;

int main()
  time_t current_time = time(NULL);
  current_time -= period; // for sensible start data.

  while(1) {
    uint32_t previous_time = current_time;
    current_time = time(NULL); // seconds.
    double Ah_period = (Current_B * (current_time-previous_time)) / 3600.0; // Coulomb counting.
    double soc_diff = Ah_period / effective_capacity_fromfull(); // state of charge difference this period.
    state_of_charge -= soc_diff; // update state of charge.
    double _time_until_discharged = time_until_discharged_fromfull() * 3600  * state_of_charge;

    sprintf(log_buffer, "state_of_charge(%%):%.6f\r\n", state_of_charge*100);
    sprintf(log_buffer, "_time_until_discharged(seconds):%.1f\r\n", _time_until_discharged);

} // end main

// Battery monitoring.
double time_until_discharged_fromfull(void) { // returns time until discharged from ideal battery condition.
  // http://www.smartgauge.co.uk/peukert2.html
  // T = (Hr*(C/Hr)^n)/(I^n)
  double Peukert_capacity = Hr * pow((C/Hr), k);
  double _time_until_discharged = Peukert_capacity / (pow(Current_B, k));
  return _time_until_discharged;

double effective_capacity_fromfull(void) { // returns eff. cap. in Ah.
  // http://www.smartgauge.co.uk/technical1.html
  // http://www.smartgauge.co.uk/peukert3.html
  double _effective_capacity = time_until_discharged_fromfull() * Current_B;
  return _effective_capacity;


$ make && ./soc
gcc -o soc soc.c

See http://www.smartgauge.co.uk for some good learning material on this, I had to develop on their basics to get the above code, which simply adds a real-time adjusted ‘time until discharged’ based on the updated SoC.
This code has not been checked by anyone else.

Helpful and fun having a couple of these recently to test with!
Over n out.

I have three units ready built apart from shunts, which require soldering in.
I will organise the shop page soon.

A couple of images regarding voltage measurement (unfortunately my GND connection is a misleading red).

This shows the board powered by two li-ion cells (buck regulator disconnected).
The channel A reading is 53.05V

Here the board is powered from the buck regulator (battery disconnected).
Channel A reading 53.03V.

I’m using an 48V 14.4Ah ebike battery.

It seems capable of welding together small metallic objects, which is nice.

Here are some figures on the voltage and current linearity of the recently distributed device.

I did the test back in May, and thought I’d get round to mapping some values to correct for current linearity, but really the offset value in the web interface compensates very well for the low-end of current readings.
Truly, the results are valid for the boards that have a filter at the shunt monitor inputs, as previously there was a noise problem, especially with the buck reg fitted.

emonDC tests HW3.6 May 2020.ods.zip (35.7 KB)

Lots of improvements to the firmware so I’ll list them in a separate post.

. I have some dead-accurate low-side shunt monitors for breadboarding with.
. I’ve replaced the MCP3208 adc with a 48-pin stm32F3 (cheaper!), and the new version will be able to run independently of the esp8266, using serial output, I’m going to aim for a 10mA board.

Thank you.

Hello Daniel,

Need help plz. I’ve burn the Reg 1 due to a reverse polarity. Could you help, Reg 1 - what reference it is.

Ouch. That’s the 5V regulator. You could bypass it connecting 5V directly.
part number reg1117-5


As you say Ouch… I don’t i will get same part. I will try with a 7805. do you think a normal regulator may fit/work. Otherwise will bypass as you said. Will update you. Thanks for usual support.

That should work fine. The though-holes near the tabs of the regulators give you access to the 5V and 3.3V

Hello Daniel,

I’ve placed a 5v source directly on tabs near regulator. First notice that power light on for few second then off, board heat also.

I’ve check D7 which seems to be short. Removed it and it work. But reading on the Source b is not accurate.

Can you advise a replacement diode.

D7 is a tvs diode for the 5V line. It had two functions
. protects against transients on the 5V line.
. provide a path for reverse polarity.

Pretty much any diode with enough capacity to blow a fuse should give you the 2nd function.
The protection against transients is not too great a deal on the 5V line anyway, but if you did find a replacement tvs diode with a reverse stand-off of 5V the transient protection would be better.

I wonder where that inaccurate reading is coming from.

Hello Daniel,

I’ve got some TVS P6Ke16 - Reverse is 13.6V. Very difficult to get an equivalent here.

If this TVS not fine, i will leave board with TVS.

Overall its working. Only Volt B section seems to be damage. The amp on B section is showing a fix value of 59.67 amp, no response.

Volt A section fine, Volt and Amp sensor line are accurate.

That diode will do alright, better than nothing.

Is one of the B-channel fuses blown? If the short circuit happened through B then either or both fuses could be done in.

TVS - Oh good, as got some lying around.

I’ve not yet tested this fuse section. Let me check this section an revert back.

Hello Daniels.

Some good news.

The Fuse are ok. no damage.

After placing the TVS P6Ke16 - both channel reading are now accurate.

Board has been placed back to my solar system.

Next step to update the firmware.

great. the current firmware is here:
. GitHub - danbates2/emonDCduo: specific for duo, h/w & s/w

there’s an update coming soon which will help with grabbing the files from the sd card… if you choose to update before this sd card manager thing coming, you’ll be able to do it again in the future over wifi so at least re-flashing would be easier.