/*
*Created by : Bang Naga (Ucok Sinaga)
*Date : 05 September 2016
*Email : [email protected]
*FB : www.facebook.com/nagasakti
*/
// Pin 3 Sensor Low dengan Sensort Interupt =1 jika sensor pin2 Sensor Interap =0 (Khusus Arduino Uno)
#include <Keypad.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h> // this #include still required because the RTClib depends on it
#include "RTClib.h"
#include <Time.h>
#include <TimeLib.h>
#include <string.h>
#include <stdlib.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
int itgl1, ibln1, ithn1, itgl2, ibln2, ithn2;
struct date {
int dd, mm, yy;
};
RTC_Millis rtc;
String strnovoucher;
String strtglexpire;
String strnomesin;
String strkodepulsa;
String internaltanggal;
String internalnomesin;
String strtgl, strbln, strthn;
boolean BKode = false;
boolean iVoucher = false;
char novoucher[16]; //6 Digit Tanggal, 4 Digit NoMesin, 4 Digit Pulsa
char tglexpire[6];
char nomesin[4];
char kodepulsa[4];
int validasi1, validasi2;
long tglmemory;
int b,i,j,k,l,x,y,z = 1;
String strKode;
String kuncireset; //Kode
long EEPNonMesin = 1234; // No Mesin
long EEPMilliLiter = 0; // Total Pemakaian Air - ml
long EEPSaldo = 0; // Sisa Pemakaian Air - ml
int PinTone = 13;
int pinSelenoid = 12;
byte sensorInterrupt = 0;
byte sensorPin = 2;
float calibrationFactor = 4.5;
volatile byte pulseCount;
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {9,8,7,6};//{5,4,3,2};
byte colPins[COLS] = {5,4,3};// {9,8,7,6};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup()
{
lcd.init(); // initialize the lcd
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("Meteran Air");
lcd.setCursor(0,1);
lcd.print("PDAM Prabayar");
delay(3000);
internalnomesin = EEPROMReadlong(0);
//EEPSaldo =0;
EEPSaldo= EEPROMReadlong(8); //Saldo Milli Liter
rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
// Aktifkan jika ingin merubah tanggal
// rtc.adjust(DateTime(2016, 10, 18, 17, 21, 59));
Serial.begin(9600);
pinMode(PinTone, OUTPUT); //piezo Pin
pinMode(pinSelenoid, OUTPUT);
digitalWrite(pinSelenoid, LOW);
delay (1000);
digitalWrite (pinSelenoid, HIGH); // Tutup Keran
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
flowMilliLitres = 0;
totalMilliLitres = 0;
oldTime = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
void loop()
{
bacaflow();
char key = keypad.getKey();
if(key){ //Akhir Baca Keypad
switch (key)
{
case '*':
BKode == true;
inputVoucher(key);
bacakode(key);
iVoucher = true;
i=0;
tone(PinTone, 2000, 100);
delay(100);
break;
case '#':
BKode == false;
tone(PinTone, 2000, 100);
delay(100);
Serial.println ("--------- Mode Validasi -------------");
//--------------- Awal Validasi Voucher
if (iVoucher == true){
int b;
for(int b=0; b<3; b++){
Serial.print(novoucher[b]);
strKode += novoucher[b];
}
Serial.println ("");
if (strKode == "123") {
Serial.println ("RESET SALDO = 0 ");
Serial.println ("----------------------------");
ResetSaldo();
Serial.println ("----------------------------");
//kosongkan Array No Voucher
int j;
for (j=0; j<=16; j++){
novoucher[j] = ' ';
}
strKode = "";
strtgl = "";
strbln = "";
strthn = "";
iVoucher = false;
break;
}
int dcode ;
Serial.print ("Decode Chipper:" );
for (dcode = 0; dcode < 16; dcode++) {
Serial.print(trans(charToInt(novoucher[dcode])));
//strnovoucher += novoucher[dcode];
}
Serial.println ("##############################");
Serial.println (strnovoucher);
Serial.println ("##############################");
// int lvoucher;
// lvoucher = strnovoucher.length();
// for (lv = 0; lv < lvoucher
// Serial.println (strnovoucher.toInt());
Serial.println ("----------------------------");
Serial.print ("Voucher : ");
Serial.println (novoucher);
Serial.print ("Expire : " );
int j;
strtglexpire = "";
tglmemory = "";
for(int j=0; j<8; j++){
Serial.print(trans(charToInt(novoucher[j])));
strtglexpire += trans(charToInt(novoucher[j]));
tglmemory = strtglexpire.toInt();
}
Serial.println();
int x;
strtgl = "";
for (int x=0; x<2; x++){
strtgl += trans(charToInt(novoucher[x]));
}
Serial.print ("Tanggal : ");
Serial.println(strtgl.toInt());
itgl2 = strtgl.toInt();
int y;
strbln = "";
for (int y=2; y<4; y++){
strbln += trans(charToInt(novoucher[y]));
}
Serial.print ("Bulan : ");
Serial.println(strbln.toInt());
ibln2 = strbln.toInt();
int z;
strthn = "";
for (int z=4; z<8; z++){
strthn += trans(charToInt(novoucher[z]));
}
Serial.print ("Tahun : ");
Serial.println(strthn.toInt());
ithn2 = strthn.toInt();
int k;
Serial.print ("No Mesin : ");
strnomesin ="";
for (int k=8; k<12; k++){
Serial.print(trans(charToInt(novoucher[k])));
strnomesin += trans(charToInt(novoucher[k]));
}
Serial.println();
strkodepulsa = "";
Serial.print ("Pulsa Air : ");
for (int l=12; l<16; l++){
Serial.print(trans(charToInt(novoucher[l])));
strkodepulsa += trans(charToInt(novoucher[l]));
}
Serial.println ("");
internalnomesin = EEPROMReadlong(0);
if (cektanggal() == 1){
Serial.println("======== Validasi No Mesin ==========");
if (strnomesin == internalnomesin) {
// Cek Voucher Terakhir
int lastNominal = EEPROMReadlong(12);
int LastTanggal = EEPROMReadlong(16);
//strtglexpire.toInt();
Serial.println(lastNominal);
Serial.println(LastTanggal);
Serial.println(strkodepulsa.toInt());
Serial.println(strtgl.toInt());
if ((lastNominal == strkodepulsa.toInt()) && (LastTanggal == strtgl.toInt())){
Serial.println ("Nomor Voucher sudah pernah digunakan");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Voucher Invalid");
lcd.setCursor(0,1);
lcd.print("Sudah terpakai");
delay(2000);
}else{
Serial.println("Tanggal Voucher & No Mesin valid");
Serial.println("UPDATE PULSA METERAN : ");
Serial.print(strkodepulsa);
long pulsabaru = strkodepulsa.toInt();
Serial.print(" x 10 x 1000 ltr = ");
TambahSaldo (pulsabaru * 10000); // Milli Liter * 10 <<<<<<<<<<<<<<<<
EEPROMWritelong(12,strkodepulsa.toInt()); //Rekam Pulsa Terakhir
EEPROMWritelong(16,strtgl.toInt()); //Rekam Pulsa Terakhir
Serial.print (pulsabaru * 10000);
Serial.println(" ml");
Serial.println(" ################################################");
validasi1 = 1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Voucher Valid");
lcd.setCursor(0,1);
lcd.print("Stok bertambah");
delay(3000);
}
}else{
Serial.println("Tanggal Voucher Valid tetapi ID Mesin tidak valid");
Serial.println (strnomesin);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Keyword/Voucher");
lcd.setCursor(0,1);
lcd.print("anda tidak valid");
validasi1 = 0;
}
}else{
Serial.println("Voucher Expire, Voucher diabaikan");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Keyword/Voucher");
lcd.setCursor(0,1);
lcd.print("anda tidak valid");
delay(3000);
}
Serial.println("=================================================");
}
//--------------- Akhir Validasi Voucher
//kosongkan Array No Voucher
int j;
for (j=0; j<=16; j++){
novoucher[j] = ' ';
}
strtgl = "";
strbln = "";
strthn = "";
strKode = "";
iVoucher = false;
break;
default:
tone(PinTone, 2000, 100);
delay(100);
if (iVoucher == true){
//Serial.print(key);
novoucher[i] = key;
lcd.print(key);
i++;
}
}
}//-------------------------Akhir Baca Keypad
}
void bacakode(char key){
if (BKode == true){
lcd.print(key);
}
}
void inputVoucher(char key) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Input Token:");
//processNumberKey(key);
lcd.setCursor(0, 1);
iVoucher = true;
lcd.blink();
delay(1000);
}
void bacaflow(){
if((millis() - oldTime) > 1000)
{
detachInterrupt(sensorInterrupt);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
flowMilliLitres = (flowRate / 60) * 1000;
totalMilliLitres += flowMilliLitres;
unsigned int frac;
frac = (flowRate - int(flowRate)) * 10;
EEPMilliLiter = totalMilliLitres;
pulseCount = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
EEPSaldo = EEPSaldo - flowMilliLitres;
TulisMemory (EEPNonMesin, EEPMilliLiter, EEPSaldo);
BacaMemory();
}
}
void pulseCounter()
{
pulseCount++;
}
int validasivoucher(){
//validasi tanggal
DateTime now = rtc.now();
internaltanggal += now.day();
internaltanggal += now.month();
internaltanggal += now.year();
Serial.println (internaltanggal);
Serial.println (strtglexpire);
//validasi nomor mesin;
Serial.println(strnomesin);
Serial.println(nomesin);
}
int cektanggal(){
DateTime now = rtc.now();
itgl1 = now.day(), DEC;
ibln1 = now.month(), DEC;
ithn1 = now.year(), DEC;
Serial.println ("Tanggal Sekarang: ");
Serial.println (String(itgl1) + "/" + String(ibln1) + "/" + String(ithn1));
Serial.println ("------------------------------------------------");
Serial.print ("Tanggal Voucher: ");
Serial.println (String(itgl2) + "/" + String(ibln2) + "/" + String(ithn2));
Serial.println ("------------------------------------------------");
struct date d1 = {itgl1, ibln1, ithn1};
struct date d2 = {itgl2, ibln2, ithn2};
int cmp = date_cmp(d1, d2);
if (cmp == 0){
Serial.println("Tanggal Voucher Expire");
return 0;}
else if (cmp > 0){
Serial.println ("Tanggal Voucher Expire");
return 0;}
else {Serial.println("Tanggal Voucher Valid");
return 1;
}
}
int date_cmp(struct date d1, struct date d2){
if (d1.dd == d2.dd && d1.mm == d2.mm && d1.yy ==d2.yy)
return 0;
else if (d1.yy > d2.yy || d1.yy == d2.yy && d1.mm > d2.mm || d1.yy == d2.yy && d1.mm == d2.mm && d1.dd > d2.dd)
return 1;
else return -1;
}
// -------------------------- Awal Fungsi yang berkaitan dengan Memory
void TulisMemory(long nilai1, long nilai2, long nilai3 ){
EEPROMWritelong(0, nilai1); //Nomor Mesin
EEPROMWritelong(4, nilai2); //pemakian
EEPROMWritelong(8, nilai3); //Saldo Liter
}
void BacaMemory(){
Serial.print("Last Voucher Key: ");
Serial.println(EEPROMReadlong(12));
Serial.println(EEPROMReadlong(16));
Serial.println("************************************************************** ");
Serial.print("Nomor Mesin : ");
Serial.println(EEPROMReadlong(0));
Serial.print("Pemakaian : ");
Serial.print(EEPROMReadlong(4));
Serial.println(" ml");
Serial.print("Sisa Saldo : ");
Serial.print(EEPROMReadlong(8));
Serial.println(" ml");
Serial.print("Sisa Saldo : ");
Serial.print(EEPROMReadlong(8)/1000);
Serial.println(" liter");
Serial.println("--------------------------------------------");
if (iVoucher == false){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Total:");
lcd.setCursor(7,0);
lcd.print(EEPROMReadlong(4));
lcd.setCursor(14,0);
lcd.print("mL");
lcd.setCursor(0,1);
lcd.print("Sisa :");
lcd.setCursor(7,1);
lcd.print(EEPROMReadlong(8)/1000);
long sisa = EEPROMReadlong(8)/1000;
if (sisa <=0){
digitalWrite (pinSelenoid, HIGH); // Tutup Keran
playTone(1000, 7000);
}else{
digitalWrite (pinSelenoid, LOW); // Buka Keran
}
if (sisa <= 100 && sisa >= 0){
playTone(300, 160);
}
lcd.setCursor(15,1);
lcd.print("L");
}
}
void TambahSaldo(long saldoml){
EEPSaldo = EEPROMReadlong(8) + saldoml;
EEPROMWritelong(8,EEPSaldo );
EEPROMWritelong(4,0); //Reset ke 0 pemakaian
}
void ResetSaldo(){
EEPSaldo = 0;
EEPROMWritelong(8,EEPSaldo );
EEPROMWritelong(4,0 );
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Reset meteran");
lcd.setCursor(0,1);
lcd.print("berhasil");
delay(3000);
}
void EEPROMWritelong(int address, long value)
{
//Write the 4 bytes into the eeprom memory.
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
long EEPROMReadlong(long address)
{
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
// -------------------------- Akhir Fungsi yang berkaitan dengan Memory
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(PinTone,HIGH);
delayMicroseconds(period / 2);
digitalWrite(PinTone, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
int trans(int x2) {
//int x2;
//x2 = chr(x1);
Serial.println (" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
//Serial.print (x1);
//Serial.print (" ");
Serial.print (x2);
Serial.print (" ");
int result;
if (x2 >= 0 && x2 <= 2)
{
result = x2 + 7;
return result;
} else if (x2 >= 3 && x2 <= 9) {
result = x2 - 3;
return result;
}
Serial.print (result);
}
int charToInt (char ch){ // ubah Charter ke Integer
return ch-'0';
}
Comments