Table of Contents
Toggle
In this tutorial, I will show you how to make a Wemos ( ESP8266 ) based Multifunction Energy Meter. This little Meter is a very useful device that monitors voltage, current, power, energy, and capacity. Apart from these it also monitors the ambient temperature which is important for solar photovoltaic application. This device is suitable for almost any DC device. This small meter can also be used for measuring the real capacity of the battery pack or power bank using a dummy load. The Meter can measure up to voltage range from 0 – 26V and a maximum current of 3.2A.
This project is a continuation of my earlier Energy meter project.
The following are the new features added to the earlier version
1. Monitor the parameters from the smartphone
2. Auto range of parameters
3. Monitoring the Electricity Bill
4. USB device tester
I got inspired by the following two projects
1. Power Monitor” – DC Current and Voltage Sensor (INA219)
2. Make Your Own Power Meter/Logger
I would like to give special thanks to the above two project authors.
Supplies:
Components Used:
1. Wemos D1 Mini Pro ( Amazon )
2. INA219 ( Amazon )
3. 0.96″ OLED Display ( Amazon )
4. DS18B20 Temp Sensor ( Amazon )
5. Lipo Battery ( Amazon )
6. Screw Terminals ( Amazon )
7. Female / Male Headers ( Amazon )
8. Perforated Board ( Amazon )
9. 24 AWG Wire ( Amazon )
10. Slide Switch ( Amazon )
11. USB Male Port ( Amazon )
12. 11. USB Female Port ( Amazon )
12. PCB Standoffs ( Amazon )
13. Solar Panels ( Voltaic )
Tools & Instruments Used:
1. Soldering Iron ( Amazon )
2. Wire Stripper ( Amazon )
3. Multimeter ( Amazon )
How the Multifunction Energy MeterWorks?
The heart of the Energy Meter is an ESP8266 based Wemos board. The ESP8266 senses the current and voltage by using the INA219 current sensor and temperature by temperature sensor DS18B20. According to this voltage and current, ESP does the maths for calculating power, energy, and capacity. From energy consumption, the electricity bill is calculated based on the energy rate ( price per kWh ).
The Whole Schematic is divided into 4 groups
1. Wemos D1 Mini Pro
The power required for the Wemos board is supplied from a LiPovBattery through a slide switch.
2. Current Sensor
The Current Sensor INA219 is connected to the Arduino board in I2C communication mode ( SDA and SCL pin).
3. OLED Display
Similar to the current Sensor, the OLED display is also connected to the Arduino board in the I2C communication mode. However, the address for both the device is different.
4. Temperature Sensor
Here I have used the DS18B20 temperature sensor. It uses a one-wire protocol to communicate with the Arduino.
Schematic_DIY+Arduino+Multi+Function+Power+Meter+V2.0_2020-09-18_23-32-20
Prepare the Header Pins
To mount the Arduino, OLED display, current sensor, and temperature sensor, you need some female straight headers pin. When you purchase the straight headers, they’ll be too long for the components to be used. So, You’ll need to trim them down to an appropriate length. I used a nipper to trim down it.
The following are the details about the headers :
1. Wemos Board – 2 x 8 pins
2. INA219 – 1 x 6 pins
3. OLED – 1 x 4 pins
4. Temp. Sensor – 1 x 3 pins
Solder the Female Headers
After preparing the female headers pin, solder them to the perforated board.
After soldering the header pins, check whether all the components fit perfectly or not.
Solder Screw Terminals, USB Port and Switch
First solder the 3 screw terminals, the screw terminals are used for connecting 1. Source 2. Load and 3. Battery
The top terminals are used for source and load connection and the bottom terminal placed side to the switch is used for connecting the battery pack.
Then solder the slide switch. The slide switch turns ON and OFF power to the Wemos board.
At last solder the female USB port. The size of the mounting legs of the USB port is slightly larger than the holes in the perforated hole, so you have to make the hole wider by using a drill. Then press the USB port into that holes and solder all the pins.
Prepare the INA219 Sensor
The INA219 sensor comes with 6pin male header strips and a screw terminal. The male header pins are for I2C connection with microcontroller and the screw terminal is for power line connection for measuring the current.
Here I have soldered the 6pin male pins to the INA219 and left the screw terminal for considering aesthetic look. Then I directly solder two wires to the soldering pad given for the screw terminal as shown in the above picture.
Mount the Temperature Sensor
Here I am using the DS18B20 temperature sensor in the TO-92 package. By considering the easy replacement, I have used a 3 pin female header. But you can directly solder the sensor to the perforated board.
The pin diagram for DS18B20 is shown in the above picture.
Make the Circuit
After soldering the female headers and screw terminals, you have to join the pads as per the schematic diagram shown above.
The connections are pretty straight forward
INA219 / OLED -> Wemos
VCC -> VCC
GND – > GND
SDA -> D2
SCL-> D1
DS18B20 -> Wemos
GND – > GND
DQ -> D4 through a 4.7K pull-up resistor
VCC -> VCC
At last, connect the screw terminals as per the schematic.
I have used 24AWG colored wires to make the circuit. Solder the wire as per the circuit diagram
Prepare the Battery Pack
Here I have used a 700mAh battery pack to power the Wemos board. The battery pack is mounted on the backside of the circuit board. To mount the battery, I have used 3M double-sided tape.
Few thoughts :
1. If you don’t want to use a battery pack, you can use source power to power the Wemos board by using a voltage regulator circuit.
2. You can add a TP4056 charging board to charge the LiPo battery.
Mounting the Standoffs
After soldering and wiring, mount the standoffs at 4 corners. It will provide sufficient clearance to the soldering joints and wires from the ground.
Software and Libraries
1. Preparing Arduino IDE for Wemos Board
To upload the Arduino code to the Wemos board, you have to follow this Instructables
Set the correct board and COM Port.
2. Install the Libraries
Then you have to import the library on to your Arduino IDE
Download the following libraries
5.OneWire
3. Arduino Sketch
After installing the above libraries, paste the Arduino code given below.
Enter the auth code from step-1, ssid, and password of your router.
Then upload the below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
#define BLYNK_PRINT Serial #define BLYNK_MAX_READBYTES 512 #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> #include <Wire.h> #include <Adafruit_INA219.h> #include <Adafruit_SSD1306.h> #include <OneWire.h> #include <DallasTemperature.h> /****************************************************************************/ BlynkTimer timer; Adafruit_INA219 ina219; #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Virtual Pins - Base #define vPIN_VOLTAGE V0 #define vPIN_CURRENT V1 #define vPIN_POWER V2 #define vPIN_ENERGY V3 #define vPIN_CAPACITY V4 #define vPIN_TEMP V5 #define vPIN_CURRENT_GRAPH V6 #define vPIN_ENERGY_PRICE V7 #define vPIN_ENERGY_COST V8 #define vPIN_BUTTON_AUTORANGE V9 // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // GPIO where the DS18B20 is connected to const int oneWireBus = 2; // Setup a oneWire instance to communicate with any OneWire devices OneWire oneWire(oneWireBus); // Pass our oneWire reference to Dallas Temperature sensor DallasTemperature sensors(&oneWire); float shuntvoltage = 0.00; float busvoltage = 0.00; float current_mA = 0.00; float loadvoltage = 0.00; float energy = 0.00, energyCost, energyPrevious, energyDifference; float energyPrice = 5.25 ; float power = 0.00; float tempC=0.00; float tempF=0.00; float capacity=0.00; int sendTimer, pollingTimer, priceTimer, graphTimer, autoRange, countdownResetCon, countdownResetClock, counter2, secret, stopwatchTimer; long stopwatch; int splitTimer1, splitTimer2, splitTimer3, splitTimer4, splitTimer5; int sendTimer1, sendTimer2, sendTimer3, sendTimer4, sendTimer5; unsigned long previousMillis = 0; unsigned long interval = 100; char auth[] = "XXXX"; // Enter Blynk auth id char ssid[] = "XXXX"; //Enter your WIFI Name char pass[] = "XXXX"; //Enter your WIFI Password /****************************************************************************/ void get_sensor_data() { // get the INA219 and DS18B20 Sensor values and throw some basic math at them shuntvoltage = ina219.getShuntVoltage_mV(); busvoltage = ina219.getBusVoltage_V(); current_mA = ina219.getCurrent_mA(); loadvoltage = busvoltage + (shuntvoltage / 1000); // V power = current_mA * loadvoltage ; // mW energy = energy + (power / 1000 / 1000); //Wh capacity = capacity + current_mA/1000; // nothing connected? set all to 0, otherwise they float around 0. if (loadvoltage < 1.2 )loadvoltage = 0; if(current_mA < 2 ) { current_mA = 0; power = 0; energy = 0; capacity=0; } sensors.requestTemperatures(); // get temperatures tempC = sensors.getTempCByIndex(0); //tempF = sensors.getTempFByIndex(0); } // this function is for updaing the REAL TIME values and is on a timer void display_data() { // VOLTAGE Blynk.virtualWrite(vPIN_VOLTAGE, String(loadvoltage, 2) + String(" V") ); display.clearDisplay(); display.setCursor(0, 10); display.print(loadvoltage); display.print(" V"); // CURRENT if (current_mA > 1000 && autoRange == 1) { Blynk.virtualWrite(vPIN_CURRENT, String((current_mA / 1000), 3) + String(" A") ); display.setCursor(0, 30); display.print((current_mA / 1000), 2); display.print(" A"); } else { Blynk.virtualWrite(vPIN_CURRENT, String(current_mA, 2) + String(" mA")); display.setCursor(0, 30); display.print(current_mA,1); display.print(" mA"); } // POWER if (power > 1000 && autoRange == 1) { Blynk.virtualWrite(vPIN_POWER, String((power / 1000), 3) + String(" W") ); display.setCursor(0, 50); display.print(String((power / 1000),2)); display.print(" W"); } else { Blynk.virtualWrite(vPIN_POWER, String(power, 0) + String(" mW") ); display.setCursor(0, 50); display.print(power,0); display.print(" mW"); } energyDifference = energy - energyPrevious; // ENERGY CONSUMPTION if (energy > 1000 && autoRange == 1) { Blynk.virtualWrite(vPIN_ENERGY, String((energy / 1000), 3) + String(" kWh")); display.setCursor(70,10); display.print((energy/1000),3); display.println(" kWh"); } else { Blynk.virtualWrite(vPIN_ENERGY, String(energy, 3) + String(" Wh")); display.setCursor(70,10); display.print(energy,3); display.println(" Wh"); } energyPrevious = energy; // ENERGY COST energyCost = energyCost + ((energyPrice / 1000 / 100) * energyDifference); if (energyCost > 9.999) { Blynk.virtualWrite(vPIN_ENERGY_COST, String((energyCost),7)); } else { Blynk.virtualWrite(vPIN_ENERGY_COST, String((energyCost), 7)); } // CAPACITY if (capacity > 1000 && autoRange == 1){ Blynk.virtualWrite(vPIN_CAPACITY, String((capacity/ 1000), 2) + String(" Ah") ); display.setCursor(70,30); display.print((capacity/1000),2); display.println(" Ah"); } else{ Blynk.virtualWrite(vPIN_CAPACITY, String((capacity), 2) + String(" mAh") ); display.setCursor(70,30); display.print(capacity,1); display.println(" mAh"); } // TEMPERATURE display.setCursor(70,50); display.print(tempC); display.println(" C"); //display.println(" F"); Blynk.virtualWrite(vPIN_TEMP, String(tempC, 2) + String(" ºC") ); //Blynk.virtualWrite(vPIN_TEMP, String(tempF, 1) + String(" ºF") ) display.display(); } // AUTO RANGE BUTTON BLYNK_WRITE(vPIN_BUTTON_AUTORANGE) { autoRange = param.asInt(); display_data(); } // the stopwatch counter which is run on a timer void stopwatchCounter() { stopwatch++; long days = 0, hours = 0, mins = 0, secs = 0; String secs_o = ":", mins_o = ":", hours_o = ":"; secs = stopwatch; //convect milliseconds to seconds mins = secs / 60; //convert seconds to minutes hours = mins / 60; //convert minutes to hours days = hours / 24; //convert hours to days secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max hours = hours - (days * 24); //subtract the coverted hours to days in order to display 23 hours max if (secs < 10) secs_o = ":0"; if (mins < 10) mins_o = ":0"; if (hours < 10) hours_o = ":0"; // Blynk.virtualWrite(vPIN_ENERGY_TIME, days + hours_o + hours + mins_o + mins + secs_o + secs); } /****************************************************************************/ void setup() { Serial.begin(115200); // initialize OLED display display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(12,25); display.print("Open Green Energy"); display.display(); Serial.begin(115200); Blynk.begin(auth, ssid, pass); // START INA219 ina219.begin(); sensors.begin(); // TIMERS pollingTimer = timer.setInterval(1000, get_sensor_data); graphTimer = timer.setInterval(4000, []() { Blynk.virtualWrite(vPIN_CURRENT_GRAPH, current_mA); }); stopwatchTimer = timer.setInterval(1000, stopwatchCounter); // setup split-task timers so we dont overload ESP // with too many virtualWrites per second timer.setTimeout(200, []() { sendTimer1 = timer.setInterval(2000, display_data); }); // start in auto-range mode & sync widget to hardware state autoRange = 0; Blynk.virtualWrite(vPIN_CURRENT_GRAPH, 1); Blynk.virtualWrite(vPIN_ENERGY_PRICE, String(energyPrice, 4) ); } /****************************************************************************/ void loop() { // the loop... dont touch or add to this! Blynk.run(); timer.run(); } |
Interfacing With Blynk App
As the Wemos board has an inbuilt WiFi chip, you can connect it to your router and monitor all the parameters from your Smartphone. Here I have used Blynk app for making the smartphone monitoring app.
Blynk is an app that allows full control over Arduino, ESP8266, Rasberry, Intel Edison, and much more hardware. t is compatible with both Android and iPhone.
In Blynk everything runs on ⚡️Energy. When you create a new account, you get ⚡️2,000 to start experimenting; Every Widget needs some Energy to operate.
Follow the below steps :
Step-1: Download the Blynk app
1. For Android
2. For iPhone
Step-2:
Get the Auth Token In order to connect Blynk App and your hardware, you need an Auth Token.
1. Create a new account in Blynk App.
2. Press the QR icon on the top menu bar.
Create a clone of this Project by scanning the QR code shown above. Once it detected successfully, the whole project will be on your phone immediately.
3. After the project was created, the Blynk team will send you an Auth Token over the registered email id.
4. Check your email inbox and find the Auth Token.
To start using it:
1. Download Blynk App: http://j.mp/blynk_Android or http://j.mp/blynk_iOS
2. Touch the QR-code icon and point the camera to the code below
3. Enjoy my app!
Testing the Circuit
To test the Multifunction Energy Meter board, I have connected a 12V battery as a source and a 3W LED as a load.
The battery is connected to the source screw terminal and the LED is connected to the load screw terminal. The LiPo battery is connected to the battery screw terminal and then switch ON the circuit by using the slide switch. You can see all the parameters are displaying on the OLED screen.
The parameters in the first column are 1. Voltage 2. Current 3. Power The parameters in the second column are 1. Energy 2. Capacity 3. Temperature
Now open the Blynk app to monitor all the above parameters from your smartphone.
To check the accuracy I used my multimeter and a Tester as shown above. The accuracy is close to them.
I am really satisfied with this pocket-sized gadget.
Thanks for reading my tutorial. If you like my project, don’t forget to share it.
Comments and feedback are always welcome.