Created
August 9, 2017 05:30
-
-
Save mdmunir/e1b549e79ccbed041c9b2cced341b4d0 to your computer and use it in GitHub Desktop.
Timer untuk pompa hidroponik menggunakan arduino nano dan rtc 1307 serta keypad
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
#include <RealTimeClockDS1307.h> | |
#include <EEPROM.h> | |
#include <Keypad.h> | |
//RealTimeClock RTC;//=new RealTimeClock(); | |
#define SET_TIME 't' | |
#define SWITCH_ON '1' | |
#define SWITCH_OFF '0' | |
#define SWITCH_TOGGLE 'x' | |
#define ADD_TIMER 'a' | |
#define EDIT_TIMER 'e' | |
#define DELETE_TIMER 'd' | |
#define TIMER_VALID B1001 | |
int count = 0; | |
byte outputPins[] = {10, 11, 12, 13, A0, A1, A2, A3}; // pin ke relay | |
int timerDurations[] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
byte TIMER_COUNT, TIMER_SIZE; | |
char keypress; | |
// KEYPAD | |
const byte numRows = 4; | |
const byte numCols = 4; | |
char keymap[numRows][numCols] = { | |
{'1', '2', '3', 'A'}, | |
{'4', '5', '6', 'B'}, | |
{'7', '8', '9', 'C'}, | |
{'*', '0', '#', 'D'} | |
}; | |
byte rowPins[numRows] = {9, 8, 7, 6}; //Rows 0 to 3 | |
byte colPins[numCols] = {5, 4, 3, 2}; //Columns 0 to 3 | |
//initializes an instance of the Keypad class | |
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols); | |
struct TTimer { | |
byte config; | |
byte y; | |
byte m; | |
byte d; | |
byte h; | |
byte i; | |
unsigned int durasi; | |
}; | |
void setup() { | |
// put your setup code here, to run once: | |
Serial.begin(9600); | |
// set mode pin (2 - 9) sebagai output | |
byte i; | |
for (i = 0; i < sizeof(outputPins); i++) { | |
pinMode(outputPins[i], OUTPUT); | |
} | |
// kalibrasi waktu | |
RTC.readClock(); | |
count = RTC.getSeconds(); | |
TIMER_SIZE = sizeof(TTimer); | |
TIMER_COUNT = EEPROM.length() / TIMER_SIZE; | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
if (Serial.available()) { | |
processCommand(); | |
} | |
// process keypad | |
processKeypad(); | |
if (count % 60 == 0) { | |
// matikan state yg durasinya sudah habis | |
byte i; | |
for (i = 0; i < sizeof(outputPins); i++) { | |
if (timerDurations[i] > 0) { | |
timerDurations[i]--; | |
if (timerDurations[i] == 0) { | |
digitalWrite(outputPins[i], LOW); | |
} | |
} | |
} | |
processTimer(); | |
} | |
if (count >= 3600) { // kalibarsi detik | |
RTC.readClock(); | |
count = RTC.getSeconds(); | |
} | |
count++; | |
delay(1000); | |
} | |
void processCommand() { | |
int in, durasi, idx; | |
byte pin, x; | |
boolean state; | |
char c; | |
TTimer obj; | |
if (!Serial.available()) { | |
return; | |
} | |
char command = Serial.read(); | |
switch (command) { | |
// set waktu YYMMDD-HHIISS | |
case SET_TIME: | |
in = readSerialIntN(2); | |
RTC.setYear(in); | |
in = readSerialIntN(2); | |
RTC.setMonth(in); | |
in = readSerialIntN(2); | |
RTC.setDate(in); | |
Serial.read(); // separator | |
in = readSerialIntN(2); | |
RTC.setHours(in); | |
in = readSerialIntN(2); | |
RTC.setMinutes(in); | |
in = readSerialIntN(2); | |
RTC.setSeconds(in); | |
RTC.setClock(); | |
break; | |
// set pin output Contoh | |
// - 1059 => on-kan pin 0 selama 59 menit | |
// - 05 => off-kan pin 5 | |
// - x3123 => toggle pin 3, jika nyala tahan selama 123 menit | |
case SWITCH_ON: // on | |
case SWITCH_OFF: // off | |
case SWITCH_TOGGLE: // toggle | |
c = Serial.read(); | |
if (c >= '0' && c <= '7') { | |
x = c - '0'; | |
pin = outputPins[x]; | |
if (command == SWITCH_ON) { | |
state = HIGH; | |
} else if (command == SWITCH_OFF) { | |
state = LOW; | |
} else { | |
state = !digitalRead(pin); // toggle | |
} | |
digitalWrite(pin, state); | |
durasi = readSerialIntN(5); | |
if (state) { | |
timerDurations[x] = durasi; | |
} else { | |
timerDurations[x] = 0; | |
} | |
} | |
break; | |
case ADD_TIMER: | |
idx = -1; | |
for (x = 0; x < TIMER_COUNT; x++) { | |
EEPROM.get(x * TIMER_SIZE, obj); | |
if (obj.config >> 4 != TIMER_VALID) { // valid | |
idx = x; | |
break; | |
} | |
} | |
if (idx >= 0) { | |
setTimer(idx); | |
} | |
break; | |
case EDIT_TIMER: | |
idx = readSerialIntN(3); // address | |
setTimer(idx); | |
break; | |
case DELETE_TIMER: | |
idx = readSerialIntN(3); // address | |
obj.config = 0; | |
EEPROM.put(idx * TIMER_SIZE, obj); | |
break; | |
default: | |
Serial.readString(); | |
Serial.print("Unknown command: "); | |
Serial.println(command); | |
break; | |
} | |
} | |
void processKeypad(){ | |
char key = myKeypad.getKey(); | |
byte x; | |
boolean state; | |
if(key != NO_KEY){ | |
if(key >= '1' && key <= '8'){ | |
x = key - '1'; | |
state = !digitalRead(outputPins[x]); | |
digitalWrite(outputPins[x], state); | |
if(state){ // set durasi = 5 menit | |
timerDurations[x] = 5; | |
} | |
} | |
} | |
} | |
int readSerialIntN(int l) { | |
int i = 0; | |
boolean done = false; | |
while (Serial.available() && !done && l > 0) | |
{ | |
char c = Serial.read(); | |
if (c >= '0' && c <= '9') { | |
i = i * 10 + (c - '0'); | |
} else { | |
done = true; | |
} | |
l--; | |
} | |
return i; | |
} | |
int readSerialIntX(int max) { | |
int r = 0; | |
char c; | |
if (Serial.available()) { | |
c = Serial.read(); | |
if (c == '*') { | |
return 255; | |
} | |
if (c >= '0' && c <= '9') { // angka pertama | |
r = 10 * (c - '0'); | |
} | |
if (Serial.available()) { | |
c = Serial.read(); | |
if (c >= '0' && c <= '9') { // angka kedua | |
r = r + (c - '0'); | |
if (r <= max) { | |
return r; | |
} | |
} | |
} | |
} | |
return -1; | |
} | |
void processTimer() { | |
// read eeprom | |
byte index, x, objDayOfWeek; | |
int durasi; | |
boolean match, action; | |
TTimer obj; | |
RTC.readClock(); | |
byte y = RTC.getYear(); | |
byte m = RTC.getMonth(); | |
byte d = RTC.getDate(); | |
byte h = RTC.getHours(); | |
byte i = RTC.getMinutes(); // minute | |
byte w = RTC.getDayOfWeek(); | |
for (index = 0; index < TIMER_COUNT; index++) { | |
EEPROM.get(index * TIMER_SIZE, obj); | |
if (obj.config >> 4 == TIMER_VALID) { // valid | |
action = (obj.config & B00001000) == B00001000; // ON atau OFF | |
x = obj.config & B00000111; // nomor pin | |
objDayOfWeek = obj.durasi >> 12; // day of week disimpan bersama durasi sebagai bit ke 12-15 | |
// cocokkan konfig | |
match = (obj.y > 100 || obj.y == y) && | |
(obj.m > 100 || obj.m == m) && | |
(obj.d > 100 || obj.d == d) && | |
(obj.h > 100 || obj.h == h) && | |
(obj.i > 100 || obj.i == i) && | |
(objDayOfWeek > 7 || objDayOfWeek == w); | |
if (match) { // jika timer cocok, lakukan aksi yang seharusnya | |
digitalWrite(outputPins[x], action); | |
if (action) { // jika action adalah ON, tentukan durasinya | |
durasi = (obj.durasi << 4) >> 4; | |
timerDurations[x] = durasi; | |
} | |
} | |
} | |
} | |
} | |
void setTimer(byte address) { | |
TTimer obj; | |
char c; | |
int in; | |
if (Serial.available()) { // action | |
obj.config = TIMER_VALID << 4; | |
c = Serial.read(); | |
if (c == '1') { // jika action == 1 => ON | |
obj.config = obj.config + B1000; | |
} | |
} else { | |
return; | |
} | |
if (Serial.available()) { // pin | |
c = Serial.read(); | |
if (c >= '0' && c <= '7') { | |
obj.config = obj.config + (c - '0'); | |
} else { | |
return; | |
} | |
} else { | |
return; | |
} | |
in = readSerialIntX(59); // minute | |
if (in >= 0) { | |
obj.i = in; | |
} else { | |
return; | |
} | |
in = readSerialIntX(23); // hour | |
if (in >= 0) { | |
obj.h = in; | |
} else { | |
return; | |
} | |
in = readSerialIntX(31); // date | |
if (in >= 1) { | |
obj.d = in; | |
} else { | |
return; | |
} | |
in = readSerialIntX(12); // month | |
if (in >= 1) { | |
obj.m = in; | |
} else { | |
return; | |
} | |
in = readSerialIntX(99); // year | |
if (in >= 0) { | |
obj.y = in; | |
} else { | |
return; | |
} | |
in = readSerialIntX(6); // day of week | |
if (in >= 0) { | |
obj.durasi = in << 12; | |
} else { | |
return; | |
} | |
in = readSerialIntN(4); // durasi -> 4 digit max 4095 | |
if (in <= 4095) { | |
obj.durasi = obj.durasi + in; | |
} | |
// tambahkan ke eeprom | |
EEPROM.put(address * TIMER_SIZE, obj); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment