Skip to content

Instantly share code, notes, and snippets.

@mdmunir
Created August 9, 2017 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdmunir/e1b549e79ccbed041c9b2cced341b4d0 to your computer and use it in GitHub Desktop.
Save mdmunir/e1b549e79ccbed041c9b2cced341b4d0 to your computer and use it in GitHub Desktop.
Timer untuk pompa hidroponik menggunakan arduino nano dan rtc 1307 serta keypad
#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