Ok, as requested...
but it is really not pretty to look at... (nothing is finished)
#include <SD.h>
const int buttonPin = 8;
int buttonState = 0;
int currentPins[3] = { 1, 2, 3 }; //Assign phase CT inputs to analog pins
double calib[3] = { 0.716, 0.87, 0.732 }; //{ L1, L2, L3 };
//double calib[3] = { 0.616, 0.77, 0.632 };
//double calib[3] = { 1.00, 1.2, 1.02}; //{ L1, L2, L3 };
double kilos[3];
double kJule[3];
double price[3];
float lowtariffprice = 3.2484;
float mediumtariffprice = 4.2218;
float hightariffprice = 4.4217;
unsigned long startMillis[3];
unsigned long endMillis[3];
double RMSCurrent[3];
float RMSPower[3];
float peakPower[3];
int kilostotal = 0;
int pay = 0;
int count = 370;
int X = 0;
int AA = 0;
int Y = 0;
int BB = -1;
int Z = 0;
int CC = -2;
int eleccut = 0;
float lowtariff = 0;
float mediumtariff = 0;
float hightariff = 0;
int low = 0;
int medium = 0;
int high = 0;
size_t line_length = 0;
char line[32];
#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27, 20, 4);
byte three[8] = {
B00000,
B00000,
B11000,
B00100,
B01000,
B00100,
B11000,
B00000,
};
byte two[8] = {
B00000,
B00000,
B11000,
B00100,
B01000,
B10000,
B11100,
B00000,
};
byte one[8] = {
B00000,
B00000,
B11000,
B01000,
B01000,
B01000,
B11100,
B00000,
};
byte baht[8] = {
B00100,
B11110,
B10101,
B11110,
B10101,
B10101,
B11110,
B00100,
};
void setup() {
Serial.begin(115200);
SD.begin(4);
lcd.begin(20, 4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight //
lcd.createChar(1, one);
lcd.createChar(2, two);
lcd.createChar(3, three);
lcd.createChar(4, baht);
pinMode(8, INPUT_PULLUP);
lcd.clear();
lcd.setCursor(6, 1); // set cursor to column 0, row 0 (the first row)
lcd.print("3 Phase");
lcd.setCursor(4, 2);
lcd.print("Energy Meter");
delay(2000);
size_t line_length = 0;
//File file = SD.open("DATA.TXT", FILE_WRITE | O_TRUNC); // clean file on the SD card
}
void readPhase() //Method to read information from CTs
{
for (int i = 0; i <= 2; i++) {
float current = 0;
float maxCurrent = 0;
float minCurrent = 1000;
for (int j = 0; j <= 200; j++) //Monitors and logs the current input for 200 cycles to determine max and min current
{
current = analogRead(currentPins[i]); //Reads current input and records maximum and minimum current
if (current >= maxCurrent)
maxCurrent = current;
else if (current <= minCurrent)
minCurrent = current;
}
if (maxCurrent <= 515) {
maxCurrent = 514;
}
RMSCurrent[i] = (((maxCurrent - 514) * 0.70710678118) / calib[i]); //Calculates RMS current based on maximum value and scales according to calibration
RMSPower[i] = 210 * RMSCurrent[i]; //Calculates RMS Power Assuming Voltage 220VAC, change to 110VAC accordingly
if (RMSPower[i] > peakPower[i]) {
peakPower[i] = RMSPower[i];
}
endMillis[i] = millis();
unsigned long time = (endMillis[i] - startMillis[i]);
//kilos[i] = kilos[i] + (float(RMSPower[i]) * float(time / 60 / 60 / 1000000)); //Calculate kilowatt hours use
kilos[i] = kilos[i] + (float(RMSPower[i]) * (float(time / 3600000))); //Calculate kilowatt hours use (float(time / 60 / 60 / 1000))
kJule[i] = kJule[i] + (float(RMSPower[i]) * (float(time)) / 1000000);
//Serial.println(time);
//Serial.print("RMSPower[1] ");
//Serial.println(RMSPower[1]);
//Serial.print("RMSPower[2] ");
//Serial.println(RMSPower[2]);
//Serial.print("RMSPower[3] ");
//Serial.println(RMSPower[3]);
//Serial.print("kilos[1] ");
//Serial.println(kilos[1]);
//Serial.print("kilos[2] ");
//Serial.println(kilos[2]);
//Serial.print("kilos[3] ");
//Serial.println(kilos[3]);
//Serial.print("kJules[1] ");
//Serial.println(kJule[1]);
//Serial.print("kJules[2] ");
//Serial.println(kJule[2]);
//Serial.print("kJules[3] ");
//Serial.println(kJule[3]);
startMillis[i] = millis();
}
}
void loop() //Calls the methods to read values from CTs and changes display
{
readPhase();
displayKilowattHours();
delay(1800);
readPhase();
displayKJules();
delay(1800);
//readPhase();
//displayCurrent();
//delay(1800);
readPhase();
displayRMSPower();
delay(1800);
readPhase();
displayPeakPower();
delay(1800);
readPhase();
displayTotals();
delay(1800);
readPhase();
displaysavedata();
delay(1800);
readPhase();
displayeleccut();
delay(1700);
//displaypressbutton();
//delay(1700);
}
void displayKilowattHours() //Displays all kilowatt hours data
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("****** Energy ******");
lcd.setCursor(0, 1);
lcd.print("L"
"\1"
" ");
lcd.print(kilos[0]);
lcd.print(" kW/h");
lcd.setCursor(0, 2);
lcd.print("L"
"\2"
" ");
lcd.print(kilos[1]);
lcd.print(" kW/h");
lcd.setCursor(0, 3);
lcd.print("L"
"\3"
" ");
lcd.print(kilos[2]);
lcd.print(" kW/h");
}
void displayKJules() //Displays all kilowatt hours data
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("**** Kilojules *****");
lcd.setCursor(0, 1);
lcd.print("L"
"\1"
" ");
lcd.print(kJule[0]);
lcd.print(" kJ/h");
lcd.setCursor(0, 2);
lcd.print("L"
"\2"
" ");
lcd.print(kJule[1]);
lcd.print(" kJ/h");
lcd.setCursor(0, 3);
lcd.print("L"
"\3"
" ");
lcd.print(kJule[2]);
lcd.print(" kJ/h");
}
//void displayCurrent() //Displays all current data
//{
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("** Current");
//lcd.setCursor(0, 1);
//lcd.print("L"
// "\1"
// " ");
//lcd.print(RMSCurrent[0]);
// lcd.print(" A");
//lcd.setCursor(0, 2);
// lcd.print("L"
// "\2"
// " ");
// lcd.print(RMSCurrent[1]);
// lcd.print(" A");
// lcd.setCursor(0, 3);
// lcd.print("L"
// "\3"
// " ");
// lcd.print(RMSCurrent[2]);
// lcd.print(" A");
//}
void displayRMSPower() //Displays all RMS power data
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("****** Power *******");
lcd.setCursor(0, 1);
lcd.print("L"
"\1"
" ");
lcd.print(RMSPower[0]);
lcd.print(" W");
lcd.setCursor(0, 2);
lcd.print("L"
"\2"
" ");
lcd.print(RMSPower[1]);
lcd.print(" W");
lcd.setCursor(0, 3);
lcd.print("L"
"\3"
" ");
lcd.print(RMSPower[2]);
lcd.print(" W");
}
void displayPeakPower() //Displays all peak power data
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("**** Max Power ****");
lcd.setCursor(0, 1);
lcd.print("L"
"\1"
" ");
lcd.print(peakPower[0]);
lcd.print(" W");
lcd.setCursor(0, 2);
lcd.print("L"
"\2"
" ");
lcd.print(peakPower[1]);
lcd.print(" W");
lcd.setCursor(0, 3);
lcd.print("L"
"\3"
" ");
lcd.print(peakPower[2]);
lcd.print(" W");
}
void displayTotals() //Displays all peak power data
{
lcd.clear();
kilostotal = kilos[0] + kilos[1] + kilos[2];
if (kilostotal < 150) {
lowtariff = kilostotal;
low = 1;
medium = 0;
high = 0;
}
if (kilostotal - 150 > 0) {
lowtariff = 150;
mediumtariff = kilostotal - 150;
low = 1;
medium = 1;
high = 0;
}
if (kilostotal - 150 - 250 > 0) {
lowtariff = 150;
mediumtariff = 250;
hightariff = kilostotal - 150 - 250;
low = 1;
medium = 1;
high = 1;
}
pay = (lowtariff * 3.2484 * low) + (mediumtariff * 4.2218 * medium) + (hightariff * 4.4217 * high);
if (pay < 0) {
pay = 0;
}
lowtariff = 0;
mediumtariff = 0;
hightariff = 0;
low = 0;
medium = 0;
high = 0;
lcd.setCursor(0, 0);
lcd.print(" Total consumption");
lcd.setCursor(5, 1);
lcd.print("L"
"\1"
"+ L"
"\2"
"+ L"
"\3");
lcd.setCursor(6, 2);
lcd.print(kilostotal);
lcd.print(" KW/h");
lcd.setCursor(7, 3);
lcd.print(pay);
lcd.print(" "
"\4");
}
void displaysavedata() {
Serial.println(count);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print(" Automatically");
lcd.setCursor(1, 1);
lcd.print("Backing up Data in");
lcd.setCursor(5, 2);
lcd.print(376 - count);
lcd.print(" cycles");
if (count == 373) {
count = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Saving Data");
//File file = SD.open("DATA.TXT", FILE_WRITE);
//if (file) {
// for (uint8_t i = 1; i <= 3; ++i) {
// line_length = snprintf(line, sizeof(line), "%5hi", kilos[i - 1]); //formatting the numbers and saving them on the SD cardtxt
// SD.remove("DATA.TXT");
// File file = SD.open("DATA.TXT", FILE_WRITE);
// file.println(line);
//File file = SD.open("DATA.TXT", FILE_WRITE | O_TRUNC); // clean file on the SD card
File file = SD.open("DATA.TXT", FILE_WRITE);
file = SD.open("DATA.TXT");
if (file) {
for (uint8_t i = 1; i <= 3; ++i) {
line_length = snprintf(line, sizeof(line), "%5hi", (int16_t)random(500, 600)); //formatting the random numbers and saving them on the SD card
Serial.print("Writing at position ");
Serial.print(i);
Serial.print(" : \"");
Serial.print(line);
Serial.println("\"");
file.println(line);
}
file.close(); //close the SD card file
line_length += 2; // count characters "\r\n" added by println
//file.close(); //close the SD card file
//line_length += 2; // count characters "\r\n" added by println
//lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SAVED ALL DATA");
//Serial.println("SAVED ALL DATA"); //blank line to separate save and read/distributing into variables
// Following reads all lines from file
delay(1000);
// file = SD.open("DATA.TXT");
// if (file) {
// while (file.available() >= line_length) {
// static uint8_t line_id = 0;
// file.seek(line_id * line_length); // go to line saving the 3 numbers in 3 different variables
// if (AA == 0) {
// A = file.parseInt();
// AA = AA + 1;
// BB = BB + 1;
// CC = CC + 1;
// }
// if (BB == 0) {
// B = file.parseInt();
// BB = BB + 1;
// CC = CC + 1;
// }
// if (CC == 0) {
// C = file.parseInt();
// CC = CC + 1;
// }
// file.read(line, line_length - 2); // read line without "\r\n"
// line[line_length - 2] = '\0'; // make sure to add null character to make a valid C-string
// }
// file.close(); //close the SD card file show that there are 3 numbers in the 3 variables
AA = 0;
BB = -1;
CC = -2;
}
file = SD.open("DATA.TXT", FILE_READ);
Serial.print("A");
//file = SD.open("DATA.TXT");
if (file) {
while (file.available() >= line_length) {
static uint8_t line_id = 0;
file.seek(line_id * line_length); // go to line
Serial.print("E");
if (AA == 0) {
Serial.print("F");
X = file.parseInt();
Serial.print("G");
kilos[0] = X;
AA = AA + 1;
BB = BB + 1;
CC = CC + 1;
}
if (BB == 0) {
Serial.print("H");
Y = file.parseInt();
kilos[1] = Y;
BB = BB + 1;
CC = CC + 1;
}
if (CC == 0) {
Serial.print("I");
Z = file.parseInt();
kilos[2] = Z;
CC = CC + 1;
Serial.print("J");
}
}
Serial.print("K");
Serial.print("L");
file.close();
Serial.print("M");
}
} else {
Serial.print("N");
count = count + 1;
}
Serial.print("O");
}
//void displaysavedata() {
//Serial.println(count);
// lcd.clear();
//lcd.setCursor(2, 0);
// lcd.print(" Automatically");
// lcd.setCursor(1, 1);
/// lcd.print("Backing up Data in");
/// lcd.setCursor(5, 2);
// lcd.print(376 - count);
// lcd.print(" cycles");
// if (count == 376) {
// count = 0;
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Saving Data");
// File file = SD.open("DATA.TXT", FILE_WRITE | O_TRUNC); // clean file on the SD card
// if (file) {
// for (uint8_t i = 1; i <= 3; ++i) {
// Serial.println(kilos[i - 1]);
// line_length = snprintf(line, sizeof(line), "%5hi", kilos[i - 1]); //formatting the random numbers and saving them on the SD card
// file.println(line);
// lcd.setCursor(0, i);
// lcd.print("Data saved ");
// lcd.print(kilos[i - 1]);
// Serial.print("Writing ");
// Serial.print(i);
// Serial.print(": ");
// Serial.println(kilos[i - 1]);
// }
// file.close(); //close the SD card file
// line_length += 2; // count characters "\r\n" added by println
// }
/// //File file = SD.open("DATA.TXT");
// file = SD.open("DATA.TXT");
// if (file) {
// //while (file.available() >= line_length) {
// while (file.available() >= 3) {
// static uint8_t line_id = 0;
// file.seek(line_id * line_length);
// if (AA == 0) {
//
// A = file.parseInt();
// kilos[0] = A;
// AA = AA + 1;
// BB = BB + 1;
// CC = CC + 1;
// }
// if (BB == 0) {
// B = file.parseInt();
// kilos[1] = B;
// BB = BB + 1;
// CC = CC + 1;
// }
// if (CC == 0) {
// C = file.parseInt();
// kilos[2] = C;
//
// CC = CC + 1;
// }
// file.close();
// delay (1000);
// lcd.clear();
// //lcd.setCursor(3, 0);
//lcd.print("DATA retrieved");
// lcd.setCursor(0, 1);
// lcd.print("Saved @ 1 ");
// lcd.print(kilos[0]);
// lcd.setCursor(0, 2);
// lcd.print("Saved @ 2 ");
// lcd.print(kilos[1]);
// lcd.setCursor(0, 3);
// lcd.print("Saved @ 3 ");
// lcd.print(kilos[2]);
// }
// }
// } else {
// count = count + 1;
// }
//}
//lcd.clear();
//if (count == 373) {
// count = 0;
// File file = SD.open("DATA.TXT", FILE_WRITE);
// if (file) {
// for (uint8_t i = 1; i <= 3; ++i) {
// line_length = snprintf(line, sizeof(line), "%5hi", kilos[i - 1]); //formatting the numbers and saving them on the SD card
// SD.remove("DATA.TXT");
// File file = SD.open("DATA.TXT", FILE_WRITE);
// file.println(line);
// }
// file.close(); //close the SD card file
// line_length += 2; // count characters "\r\n" added by println
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print(" SAVED ALL DATA");
// //Serial.println("SAVED ALL DATA"); //blank line to separate save and read/distributing into variables
// Following reads all lines from file
// delay(1000);
// file = SD.open("DATA.TXT");
// if (file) {
// while (file.available() >= line_length) {
// static uint8_t line_id = 0;
// file.seek(line_id * line_length); // go to line saving the 3 numbers in 3 different variables
// if (AA == 0) {
// A = file.parseInt();
// AA = AA + 1;
// BB = BB + 1;
// CC = CC + 1;
// }
// if (BB == 0) {
// B = file.parseInt();
// BB = BB + 1;
// CC = CC + 1;
// }
// if (CC == 0) {
// C = file.parseInt();
// CC = CC + 1;
// }
// file.read(line, line_length - 2); // read line without "\r\n"
// line[line_length - 2] = '\0'; // make sure to add null character to make a valid C-string
// }
// file.close(); //close the SD card file show that there are 3 numbers in the 3 variables
//}
// }
// } else {
// count = count + 1;
// }
//}
void displayeleccut() {
if (eleccut < 2) { //if there was a power cut, wait for power to stabilise (10 cycles), recall data on SD and then start normally
eleccut = eleccut + 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("**** Power Cut ****");
lcd.setCursor(0, 1);
lcd.print(" Please Wait");
lcd.setCursor(0, 2);
lcd.print(" for a minute");
lcd.setCursor(3, 3);
lcd.print(" loop ");
lcd.print(eleccut);
lcd.print(" / 10");
delay(1000);
}
if (eleccut == 2) { //if there was a power cut, wait for power to stabilise (10 cycles), recall data on SD and then start normally
eleccut = 3;
AA = 0;
BB = -1;
CC = -2;
File file = SD.open("DATA.TXT", FILE_READ);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Power Cut");
lcd.setCursor(0, 1);
lcd.print(" RETRIEVING DATA");
lcd.setCursor(0, 2);
lcd.print(" FROM MICRO SD CARD");
file = SD.open("DATA.TXT");
if (!file) {
//while (file.available() >= line_length) {
while (file.available() >= 3) {
static uint8_t line_id = 0;
file.seek(line_id * line_length);
file.read(line, line_length - 2);
if (AA == 0) {
X = file.parseInt();
kilos[0] = X;
AA = AA + 1;
BB = BB + 1;
CC = CC + 1;
}
if (BB == 0) {
Y = file.parseInt();
kilos[1] = Y;
BB = BB + 1;
CC = CC + 1;
}
if (CC == 0) {
Z = file.parseInt();
kilos[2] = Z;
CC = CC + 1;
}
//file.read(line, line_length - 2); // read line without "\r\n"
//line[line_length - 2] = '\0'; // make sure to add null character to make a valid C-string
}
file.close(); //close the SD card file
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("DATA retrieved");
lcd.setCursor(0, 1);
lcd.print("L"
"\1"
" ");
lcd.print(kilos[0]);
lcd.print(" KW/h");
lcd.setCursor(0, 2);
lcd.print("L"
"\2"
" ");
;
lcd.print(kilos[1]);
lcd.print(" KW/h");
lcd.setCursor(0, 3);
lcd.print("L"
"\3"
" ");
lcd.print(kilos[2]);
lcd.print(" KW/h");
delay(1800);
}
}
}
void displaypressbutton() {
if (eleccut > 5) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("5"
")"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff");
lcd.setCursor(0, 1);
lcd.print("\xff"
"\xff"
"\xff"
"\xff"
"\xff"
" RESET ? "
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff");
lcd.setCursor(0, 2);
lcd.print("\xff"
" Press Button NOW "
"\xff");
lcd.setCursor(0, 3);
lcd.print("\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff"
"\xff");
buttonState = digitalRead(buttonPin);
if (!buttonState == HIGH) { //create blank data file
lcd.clear();
Serial.println("Reset SD card");
delay(1000);
File file = SD.open("DATA.TXT", FILE_WRITE | O_TRUNC); // clean file on the SD card
Serial.println("file erased");
file.close();
file = SD.open("DATA.TXT", FILE_WRITE);
if (file) {
for (uint8_t i = 1; i <= 3; ++i) {
line_length = snprintf(line, sizeof(line), "%5hi", kilos[i - 1]); //formatting the numbers and saving them on the SD card
SD.remove("DATA.TXT");
File file = SD.open("DATA.TXT", FILE_WRITE);
file.println(line);
}
file.close();
line_length += 2;
lcd.setCursor(0, 0);
lcd.print(" SD card reset OK");
kilos[0] = 0;
kilos[1] = 0;
kilos[2] = 0;
peakPower[0] = 0;
peakPower[1] = 0;
peakPower[2] = 0;
file = SD.open("DATA.TXT");
if (file) {
while (file.available() >= line_length) {
static uint8_t line_id = 0;
file.seek(line_id * line_length);
if (AA == 0) {
X = file.parseInt();
AA = AA + 1;
BB = BB + 1;
CC = CC + 1;
}
if (BB == 0) {
Y = file.parseInt();
BB = BB + 1;
CC = CC + 1;
}
if (CC == 0) {
Z = file.parseInt();
CC = CC + 1;
}
file.read(line, line_length - 2);
line[line_length - 2] = '\0';
}
//file.close();
}
}
}
}
}