/* *Created by : Bang Naga (Ucok Sinaga) *Date : 05 September 2016 *Email : emailsinaga@gmail.com *FB : www.facebook.com/nagasakti */ // Pin 3 Sensor Low dengan Sensort Interupt =1 jika sensor pin2 Sensor Interap =0 (Khusus Arduino Uno) #include #include #include #include // this #include still required because the RTClib depends on it #include "RTClib.h" #include #include #include #include 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'; }