Sebelum membuat kwh meter berbasis koin, sebenarnya saya sudah pernah membagikan video cara membuat kwh meter dengan menggunakan arduino dan datanya bisa kita lihat secara online.
Kalian bisa lihat video membuat kwh meter online disini, klik.
Untuk di artikel kali ini kita akan mempercepat pembahasan tentang bagaimana saya membuat sebuah kwh meter online berbasis koin.
Ada beberapa hal yang harus kita pahami sebelum membuat khw meter online berbasis koin ini. Pertama adalah kita harus paham dulu dasar dasar pengukuran dan perhitungan yang berkaitan tentang tegangan, arus listrik, faktor daya dan lainnya yang ada kaitan nya dengan perhitungan penggunaan energi listrik. Lalu kedua kita juga harus mampu menggunakan mikrokkontroler arduino atau sejenis nya dan memahami bagaimana membuat koneksi internet dengan menggunakan module wifi. Ketiga, kita harus paham bagaimana menggunakan koin acceptor sebagai sensor pembaca koin untuk arduino.
Setelah memahami itu semua, maka itu akan mempermudah kita untuk membuat kwh meter online berbasis koin.
Bahan bahan yang diperlukan
- Wemos D1 / Nodemcu
- LCD 16X2 + I2C
- SSR
- Stop Kontak
- Sensor Koin (Coin Acceptor)
- Modul Energy Meter (PZEM-004t)
- Kabel Jumper
Untuk mikrokontroler nya kalian bisa memilih antara menggunakan wemos d1, nodemcu atau langsung menggunakan chip esp12e nya. Untuk sensor koin nya, disini saya menggunakan sensor koin tipe 1 jenis koin. Kalian juga bisa menggunakan jenis multi koin dalam project ini.
Gambar Rangkaian
Diatas ini adalah reverensi perkabelan rangkaian kwh meter berbasis koin. Untuk pin yang digunakan sebenarnya bisa kalian ubah lagi mengikuti dari koding yang akan di upload nanti. SSR disini berfungsi sebagai saklar listrik yang akan memutus dan menghubungkan listrik ke stop kontak yang di kontrol oleh wemos D1.
Untuk sensor koin disupply tegangan 12V, sedangkan rangkaian PZEM (energy meter) di supply tegangan 5V.
Coding Arduino
#include <FS.h>
#include <math.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <WiFiClientSecure.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <WiFiManager.h>
//#include <EEPROM.h>
#include <BlynkSimpleEsp8266.h>
WiFiClientSecure client;
#define BLYNK_PRINT Serial
const int interruptPin = 2;
#include <PZEM004Tv30.h>
#include <LCD_I2C.h>
#include "Timer.h"
char blynk_token[34] = "blynk token";
char nilai_wh[34] = "";
int hitung=0;
unsigned long kaya=0;
float akhir=0;
boolean interupt=false;
float wh=0;
int ssr=13;
char kredit[10]="";
WidgetLCD lcdb(V7);
WidgetLED led(V0);
float voltage=0;
float current=0;
float power=0;
float energy=0;
float a=0;
const unsigned long PERIOD1 = 1000;
long debouncing_time = 15; //Debouncing Time in Milliseconds
volatile unsigned long last_micros;
PZEM004Tv30 pzem(14, 12);
LCD_I2C lcd(0x27);
Timer t;
bool shouldSaveConfig = false;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}
void ICACHE_RAM_ATTR ISRoutine ();
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
pinMode(ssr,OUTPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
Serial.begin(115200);
lcd.begin();
lcd.backlight();
digitalWrite(ssr,LOW);
t.every(1000, takeReading, 0);
if (SPIFFS.begin()) {
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["coin"] = kredit;
json["nilai_wh"] = wh;
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
json.printTo(Serial);
if (json.success()) {
Serial.println("\nparsed json");
//strcpy(mqtt_server, json["mqtt_server"]);
//strcpy(nilai_wh, json["nilai_wh"]);
strcpy(blynk_token, json["blynk_token"]);
strcpy(nilai_wh, json["nilai_wh"]);
strcpy(kredit, json["coin"]);
} else {
Serial.println("failed to load json config");
}
}
}
} else {
Serial.println("failed to mount FS");
}
//end read
// The extra parameters to be configured (can be either global or just in the setup)
// After connecting, parameter.getValue() will get you the configured value
// id/name placeholder/prompt default length
//WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
//WiFiManagerParameter custom_wh("Nilai kWh", "nilai kWh", nilai_wh, 10);
WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 33);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//set config save notify callback
wifiManager.setSaveConfigCallback(saveConfigCallback);
//set static ip
//wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
//add all your parameters here
//wifiManager.addParameter(&custom_mqtt_server);
//wifiManager.addParameter(&custom_mqtt_port);
wifiManager.addParameter(&custom_blynk_token);
//reset settings - for testing
//wifiManager.resetSettings();
//set minimu quality of signal so it ignores AP's under that quality
//defaults to 8%
//wifiManager.setMinimumSignalQuality();
//sets timeout until configuration portal gets turned off
//useful to make it all retry or go to sleep
//in seconds
//wifiManager.setTimeout(120);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect("Listrik Koin", "")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
//read updated parameters
//strcpy(mqtt_server, custom_mqtt_server.getValue());
//strcpy(nilai_wh, custom_wh.getValue());
strcpy(blynk_token, custom_blynk_token.getValue());
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["coin"] = kredit;
json["nilai_wh"] = nilai_wh;
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
//Serial.println("local ip");
//Serial.println(WiFi.localIP());
Blynk.config(blynk_token);
bool result = Blynk.connect();
if (result != true)
{
Serial.println("BLYNK Connection Fail");
Serial.println(blynk_token);
//wifiManager.resetSettings();
ESP.reset();
delay (5000);
}
else
{
Serial.println("BLYNK Connected");
}
// t.update();
//EEPROM.begin(512);
//Serial.println("Bambang");
takeReading(0);
////EEPROM.get(0,wh);
//delay(2000);
//takeReading(0);
//EEPROM.get(0,wh);
//Serial.print("Nilai Akhir kWh :");
//Serial.println(wh,3);
////
////Serial.println(energy,3);
////akhir=wh-energy;
//delay(1000);
Serial.print("Json nilai kWh ");
wh=atof(nilai_wh);
Serial.println(wh,3);
akhir=wh-energy;
delay(1000);
Serial.print("Kredit ");
hitung=atoi(kredit);
Serial.println(hitung);
}
void loop() {
Blynk.run();
t.update();
if(!interupt){
if(akhir<=0){
lcdb.print(0,1,"Listrik habis!!");
takeReading(0);
digitalWrite(ssr,LOW);
lcd.setCursor(0,0);
lcd.print(" Listrik Habis! ");
lcd.setCursor(0,1);
lcd.print(" Masukkan Koin! ");
//Serial.println(energy);
//pzem.resetEnergy();
energy = pzem.energy();
if( !isnan(energy) ){
//Serial.print(F("Energy: ")); Serial.print(energy,3); Serial.println(F("kWh"));
//a=((energy)*1000);
wh=energy;
simpan();
} else {
//Serial.println(F("Error reading energy"));
}
Serial.println(wh,3);
//wh=0;
}
else
{
digitalWrite(ssr,HIGH);
lcd.setCursor(0, 0);
lcd.print(voltage,0);
lcd.print("V ");
lcd.setCursor(6, 0);
lcd.print(current,2);
lcd.print("A ");
lcd.setCursor(12, 0);
lcd.print(power,0);
lcd.print("W ");
lcd.setCursor(0, 1);
lcd.print("Sisa : ");
lcd.print(akhir,3);
lcd.print("kWh ");
lcdb.print(0,0,"Total Rp. ");
lcdb.print(0,1,"Sisa : ");
lcdb.print(7,1,(akhir));
lcdb.print(12,1,"kWh ");
}
}
else{
interupt=false;
masuk();
}
delay(500);
}
void takeReading(void* context)
{
if(digitalRead(ssr)){
led.on();
}
else led.off();
ESP.wdtFeed();
voltage = pzem.voltage();
if( !isnan(voltage) ){
//Serial.print(F("Voltage: ")); Serial.print(voltage); Serial.println(F("V"));
Blynk.virtualWrite(V1, voltage);
} else {
//Serial.println(F("Error reading voltage"));
}
current = pzem.current();
if( !isnan(current) ){
//Serial.print(F("Current: ")); Serial.print(current); Serial.println(F("A"));
Blynk.virtualWrite(V2, current);
} else {
//Serial.println(F("Error reading current"));
}
power = pzem.power();
if( !isnan(power) ){
//Serial.print(F("Power: ")); Serial.print(power); Serial.println(F("W"));
Blynk.virtualWrite(V3, power);
} else {
//Serial.println(F("Error reading power"));
}
energy = pzem.energy();
if( !isnan(energy) ){
//Serial.print(F("Energy: ")); Serial.print(energy,3); Serial.println(F("kWh"));
//a=((energy)*1000);
akhir=wh-energy;
Blynk.virtualWrite(V6, energy);
} else {
//Serial.println(F("Error reading energy"));
}
float frequency = pzem.frequency();
if( !isnan(frequency) ){
//Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
Blynk.virtualWrite(V4, frequency);
} else {
//Serial.println("Error reading frequency");
}
float pf = pzem.pf();
if( !isnan(pf) ){
//Serial.print("PF: "); Serial.println(pf);
Blynk.virtualWrite(V5, pf);
} else {
//Serial.println("Error reading power factor");
}
kaya=hitung*1000;
lcdb.print(10,0,kaya);
}
ICACHE_RAM_ATTR void handleInterrupt() {
Serial.println(F("Interrupt Detected"));
interupt=true;
if((long)(micros() - last_micros) >= debouncing_time * 1000) {
last_micros = micros();
}
}
void masuk(){
wh+=0.1;
Serial.println(wh,3);
hitung+=1;
kaya=hitung*1000;
//lcdb.print(0,0,"Rp. ");
lcdb.print(4,0,kaya);
simpan();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Koin Rp 1.000! ");
lcd.setCursor(0,1);
lcd.print(" +0.100 kWh ");
delay(1000);
lcd.clear();
//interupt=false;
//a=((energy)*1000);
akhir=wh-energy;
Serial.println("Halo");
}
void simpan(){
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["coin"] = hitung;
json["nilai_wh"] = wh;
json["blynk_token"] = blynk_token;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
//json.printTo(Serial);
json.printTo(configFile);
configFile.close();
//end save
}
Dari koding diatas, saya menggunakan blynk sebagai server untuk menampung data secara online. Dan untuk pengaturan koneksi wifi nya agar dinamis saya menggunakan library wifimanager.
Kalian juga bisa menghapus bagian coding blynk jika tidak ingin menggunakan fungsi aplikasi blynk nya.
Sebelum mengupload coding nya, pastikan semua library yang diperlukan sudah terinstall pada software arduino kalian.
Video Ujicoba
Eksplorasi konten lain dari Duwi Arsana
Berlangganan untuk dapatkan pos terbaru lewat email.