ARDUINO + RTC Module+ Keypad + Relay Module

ผมอยากทราบแนวทางของการตั้งเวลาผ่าน Keypad ครับพี่ โดยใช้ Arduino UNOR3 คือผมจะทำเกี่ยวกับเครื่องเปิดปิดปั๊มน้ำ 2 ตัวครับพี่ โดยมีรายละเอียดดังนี้ โดยจะมี 2 โหมด คือ Auto - Manual เมื่อเราเข้า โหมด Auto โดยสามารถกดได้ที่ Keypad จากนั้นจะเข้าสู่ การตั้งเวลาครับ จากนั้นพอตั้งเรียบร้อยแล้ว จะกด บันทึกนี่คือฟังชั่น Auto ครับ ส่วนฟังชั่น Manual เมื่อกดเข้าโหมด Manual แล้ว จะสามารถควบคุม Relay ผ่าน Keypad ได้เลยครับพี่ ประมาณนี้ครับ รบกวนช่วยแนะนำแนวทางผมหน่อยนะครับพี่

ตอนนี้ เขียน Code ไว้แบบไหนครับ แล้ว ติดขัดตรงไหนครับ ต่ออุปกรณ์แบบไหนบ้างครับ ลงรูปแล้ว อธิบายให้หน่อยครับ

1 Like

ตอนนี้ผมเขียนโค๊ดการทำงานของ Keypad กับ Relay เรียบร้อยครับพี่ ในโหมด Manual ครับพี่

#include <Keypad.h>       
#include <Wire.h>           
#include <LiquidCrystal_I2C.h>           
LiquidCrystal_I2C lcd(0x27, 16, 2);  
#include <DS3231.h>

#include <SoftwareSerial.h>
SoftwareSerial UnoSerial(3, 2); // RX | TX



const int OnHour ;
const int OnMin  ;
const int OffHour ;
const int OffMin ;


int Kill ;

char customKey;    
const byte ROWS = 4;      
const byte COLS = 4;      
char keys[ROWS][COLS] = {      
    {'1', '2', '3' , 'A'},
    {'4', '5', '6' , 'B'},
    {'7', '8', '9' , 'C'},
    {'*', '0', '#' , 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};   
byte colPins[COLS] = {5, 4, 3, 2};    
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); 


int  Kill = 0;   

int relay_1 = 12;
int relay_2 = 13;


int relay_3 = 10;
int relay_4 = 11;


void setup()
{
    Serial.begin(9600);

  pinMode(3, INPUT);
  pinMode(2, OUTPUT);
  UnoSerial.begin(57600);

  
    pinMode(relay_1,OUTPUT);
    digitalWrite (relay_1, HIGH);
        pinMode(relay_2,OUTPUT);
    digitalWrite (relay_2, HIGH);
        pinMode(relay_3,OUTPUT);
    digitalWrite (relay_3, HIGH);
        pinMode(relay_4,OUTPUT);
    digitalWrite (relay_4, HIGH);
    lcd.begin(); 
    lcd.setBacklight(255); 
    lcd.setCursor(0, 1);
    delay(3000);  
    lcd.clear();   
    Serial.print("--------------------------------");
    Serial.print("* WELCOME *");
    Serial.print("--------------------------------");

      rtc.begin();

      
}


void loop()
{    

  Serial.print(i_data);
  
    customKey = customKeypad.getKey();  // customkey

    if (customKey) {
        Serial.println(customKey);
    }

    if (customKey == 'D') {  
        lcd.setCursor(3, 0);; 
        lcd.print("***MAIN MENU***"); 
        Serial.println("******************  MAIN MENU  ******************");
        lcd.setCursor(0, 1);;
        lcd.print(" Select MENU A or B ");
        Serial.println(" ----- Select MENU A or B ----- ");
        Serial.println("---------------------------------------------------");
    }
    
    if (customKey == 'A') {  
        lcd.setCursor(3, 0);;  
        lcd.print("AUTO");
        Serial.println("AUTO MODE");
        lcd.setCursor(0, 1);;  
        lcd.print("  ");
        Serial.println("---------------------------------------------------");

        customKey = customKeypad.getKey();
        while (customKey != '*')
        {
            if (customKey == '1') {                
                Kill = 1;    
                UnoSerial.print(Kill);           
                lcd.setCursor(5, 0);;
                lcd.print(" AUTO MODE TIME "); 
                Serial.println("");
                Serial.print("");               
                lcd.setCursor(5, 1);;   
                lcd.print("SETTIME"); 
                Serial.println("20 MS");                
                Serial.println("***********************************************");
                                  
            }
                         if(customKey == '#' ){                         
                          digitalWrite(relay1,HIGH);
                          digitalWrite(relay2,HIGH);
                          lcd.clear();
                          lcd.setCursor(3,0);
                          lcd.print("All Close");
  
                                        }           
            //*****************************************************************/
            customKey = customKeypad.getKey();
        }        
    }

     if (customKey == 'B') {
        lcd.setCursor(3, 0);; 
        lcd.print("MANUAL MODE");  
        //Serial.println("MANUAL MODE");
        lcd.setCursor(0, 1);;  
        lcd.print("  ");
        Serial.println("---------------------------------------------------");
        customKey = customKeypad.getKey();
        while (customKey != '*')
        {
            if (customKey == '1') {  
                
                Kill = 1;                    
                lcd.setCursor(1, 0);
                lcd.print("MANUAL PUMP 1");
                Serial.println("");               
                Serial.print("");
                digitalWrite(relay_3,LOW); 
                lcd.setCursor(2, 1);
                lcd.print(" START PUMP ");   
                Serial.println("START PUMP");
                
                Serial.println("***********************************************");                                  
            }
            if (customKey == '2') {  
                
                Kill = 2;                    
                lcd.setCursor(1, 0);
                lcd.print("MANUAL PUMP 2");
                Serial.println("");               
                Serial.print("");
                digitalWrite(relay_4,LOW); 
                lcd.setCursor(2, 1);   
                lcd.print(" START PUMP 2"); 
                Serial.println("START PUMP 2");
                
                Serial.println("***********************************************");                                  
            }          
                  if(customKey == '#' ){
                          
                          digitalWrite(relay3,HIGH);
                          digitalWrite(relay4,HIGH);
                          lcd.clear();
                          lcd.setCursor(3,0);
                          lcd.print("All Close");
  
                                        }           
            //*****************************************************************/                                  
            customKey = customKeypad.getKey();
                    }
                }
          }



/*
//*************************MODULE TIME*************************
 t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  
  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }
    
    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
//************************************************************

*/

ที่ติดตรงนี้คือการใช้ RTC Module ครับพี่ ไม่รู้จะเริ่มยังไงครับ

พอดีผมเพิ่มการส่งข้อมูลไปให้ Esp8266 ด้วยครับพี่ แต่ตอนนี้ผมยังไม่เคลียร์ฝั่งออฟไลน์นี่แหละพี่ครับ ที่ติดจริงๆคือ ผมไม่รู้จะทำยังไงให้ Keypad มันกรอกเวลา ครับพี่

เยี่ยมครับ ได้ 1 Block ทำงานแล้ว ต่อไปศึกษาเขียน Code RTC ( ตามเวปผู้ขาย อุปกรณ์ RTC จะมี Code ตัวอย่างให้ทดสอบ หรือ โหลด ไบนารี่ _RTC จะมี ตัวอย่าง Code ให้มาด้วย ) และทดสอบว่าเวลาทำงานตรงไหม การดึงเวลามาใช้งาน ไฟดับทำยังไงให้เวลาเดินได้ต่อ ทำทีละ Block ให้ทำงานได้ก่อน เดียวค่อยเอามารวมร่างกัน

ตัวอย่างครับ

File Simulate
countdown-timer-proteus-simulation.zip (20.5 KB)

Countdown Timer Arduino Code / Programming:

#include <Keypad.h>
//#include <LiquidCrystal.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  //0x27 is the i2c address, while 16 = columns, and 2 = rows. 

#include<stdio.h>
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {4, 5, 6, 7}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 9, 10}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );





int relay = 13;

int counter = 0; 
int attempts = 0; 
int max_attempts = 3; 

String mymints;
int minutes = 0; 

String mysecs; 
int seconds = 0; 
long int total_seconds = 0; 
int secflag = 0; 
int timer_started_flag = 0; 


// Tracks the time since last event fired
unsigned long previousMillis=0;
unsigned long int previoussecs = 0; 
unsigned long int currentsecs = 0; 
 unsigned long currentMillis = 0;
  int interval= 1 ; // updated every 1 second
int tsecs = 0; 
 
void setup(){
  Serial.begin(9600);
  lcd.init();                 //Init the LCD
  lcd.backlight();            //Activate backlight 
  

  pinMode(relay, OUTPUT);
  digitalWrite(relay, LOW);
  
  Serial.println("enter password");
    lcd.print("Countdown Timer");

    delay(2000); 
    lcd.clear();
     lcd.print("Enter Minutes:");
}
  
void loop()
{
  
 keypadfunction();
 
}

void keypadfunction()
{ 
 char key = keypad.getKey();
  
  if (key){
    Serial.println(key);
    counter = counter + 1; 
    lcd.setCursor(counter, 1);
    lcd.print(key);
  }
  
  if (key == '1')
  {

    mymints = mymints + 1;   
  }
  
    if (key == '2')
  {

    mymints = mymints + 2;  
  }
  
  if (key == '3')
  {
 
    mymints = mymints + 3; 
  }
  
   if (key == '4')
  {
  
    mymints = mymints + 4;  
  }
  
  if (key == '5')
  {
  
    mymints = mymints + 5;
  }
  
   if (key == '6')
  {
   
    mymints = mymints + 6; 
  }
  
   if (key == '7')
  {

    mymints = mymints + 7; 
  }

   if (key == '8')
  {

    mymints = mymints + 8; 
  }
  
  if (key == '9')
  {

    mymints = mymints + 9;
  }
             
                 if (key == '0')
  {

    mymints = mymints + 0; 
  }

                    if (key == '#')
  {

    counter = 0;
    mymints = ""; 
    minutes = 0;  
    mysecs = ""; 
    seconds = 0; 
    secflag = 0;  

    lcd.clear(); 
    lcd.setCursor(0,0); 
    lcd.print("Enter Minutes:"); 
  }
  
  
        if (key == '*')
  {
lcd.clear();     
minutes = mymints.toInt();
Serial.println(minutes);
lcd.clear(); 
lcd.print("Minutes: "); 
lcd.setCursor(0,1); 
lcd.print(minutes); 
mymints = ""; // empty the string
delay(2000); 
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Seconds:");
counter = 0; 
secflag = 1; 

while(secflag == 1)
{
forSeconds(); 
}    
  }  
   
}

void forSeconds()
{ 
 char key = keypad.getKey();
  
  if (key){
    Serial.println(key);
    counter = counter + 1; 
    lcd.setCursor(counter, 1);
    lcd.print(key);
  }
  
  if (key == '1')
  {

   mysecs = mysecs + 1;   
  }
  
    if (key == '2')
  {

   mysecs = mysecs + 2;  
  }
  
  if (key == '3')
  {
 
    mysecs = mysecs + 3; 
  }
  
   if (key == '4')
  {
  
    mysecs = mysecs + 4;  
  }
  
  if (key == '5')
  {
  
    mysecs = mysecs + 5;
  }
  
   if (key == '6')
  {
   
    mysecs = mysecs + 6; 
  }
  
   if (key == '7')
  {

    mysecs = mysecs + 7; 
  }

   if (key == '8')
  {

    mysecs = mysecs + 8; 
  }
  
  if (key == '9')
  {

    mysecs = mysecs + 9;
  }
             
                 if (key == '0')
  {

    mysecs = mysecs + 0; 
  }

                   if (key == '#')
  {

    counter = 0;
    mymints = ""; 
    minutes = 0;  
    mysecs = ""; 
    seconds = 0; 
    secflag = 0;  

    lcd.clear(); 
    lcd.setCursor(0,0); 
    lcd.print("Enter Minutes:"); 
  }
  
  
  
        if (key == '*')
  {

lcd.clear();     
seconds = mysecs.toInt();
Serial.println(seconds);
lcd.clear();
lcd.setCursor(0,0); 
lcd.print("Seconds: "); 
lcd.setCursor(0,1); 
lcd.print(seconds); 
mysecs = ""; // empty the string
delay(2000); 
lcd.clear();
lcd.setCursor(0,0);
 
lcd.print("Mins      Secs"); 
lcd.setCursor(1,1); 
lcd.print(minutes); 
lcd.setCursor(10,1); 
lcd.print(seconds); 
total_seconds = (minutes * 60) + seconds ;
counter = 0;
secflag = 0; 
timer_started_flag = 1;

lcd.clear();
lcd.print("T Seconds:");
lcd.setCursor(11,0);
lcd.print( total_seconds );
delay(3000); 
while( timer_started_flag == 1)
{
   char key = keypad.getKey();
  
  if (key){
    Serial.println(key);
    counter = counter + 1; 
    lcd.setCursor(counter, 1);

  }

   if (key == '#')
  {

    counter = 0;
    mymints = ""; 
    minutes = 0;  
    mysecs = ""; 
    seconds = 0; 
    secflag = 0;  
    total_seconds = 0; 
     timer_started_flag = 0;
    lcd.clear(); 
    lcd.setCursor(0,0); 
    lcd.print("Enter Minutes:"); 
  }

         //  lcd.clear(); 
  lcd.setCursor(0,0); 
  lcd.print("T Seconds:");
  lcd.setCursor(11,0); 
  lcd.print( total_seconds );
  lcd.setCursor(0,1);
  if( total_seconds > 0)
  {
    digitalWrite(relay, HIGH); 
  lcd.print("load ON "); 
  }

    if( total_seconds <= 0)
  {
    total_seconds = 0; 
    digitalWrite(relay, LOW); 
  lcd.print("load OFF"); 
  }

     currentMillis = millis();
   currentsecs = currentMillis / 1000; 
    if ((unsigned long)(currentsecs - previoussecs) >= interval) {
      total_seconds = total_seconds - 1;
      lcd.clear(); 
      previoussecs = currentsecs;
    }
}
 
  }  
  
  
}

ขอบคุณสำหรับคำแนะนำนะครับพี่ ขอบคุณมากครับผมจะศึกษาต่อไปครับพี่ :green_heart:

ขอบคุณมากครับพี่เดี๋ยวผมจะลองดูครับพี่แล้วจะเอาโค๊ดมาแปะ ไว้ครับพี่ขอบคุณครับ :blush::green_heart:

มันมีโค้ต อีกชุด ที่ไว้ตั้ง RTC ต้องเอามาผสมกันครับ

RTC

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>

//************************************//
LiquidCrystal_I2C lcd(0x3F,16,2); // Display  I2C 16 x 2
RTC_DS1307 RTC;

//************Button*****************//
int P1=6; // Button SET MENU'
int P2=7; // Button +
int P3=8; // Button -

//************Variables**************//
int hourupg;
int minupg;
int yearupg;
int monthupg;
int dayupg;
int menu =0;

void setup()
{

  lcd.begin();
  lcd.backlight();
  lcd.clear();

  pinMode(P1,INPUT);
  pinMode(P2,INPUT);
  pinMode(P3,INPUT);

  Serial.begin(9600);
  Wire.begin();
  RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // Set the date and time at compile time
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  // RTC.adjust(DateTime(__DATE__, __TIME__)); //removing "//" to adjust the time
    // The default display shows the date and time
  int menu=0;
}
 
void loop()
{ 

// check if you press the SET button and increase the menu index
  if(digitalRead(P1))
  {
   menu=menu+1;
  }
// in which subroutine should we go?
  if (menu==0)
    {
     DisplayDateTime(); // void DisplayDateTime

    }
  if (menu==1)
    {
    DisplaySetHour();
    }
  if (menu==2)
    {
    DisplaySetMinute();
    }
  if (menu==3)
    {
    DisplaySetYear();
    }
  if (menu==4)
    {
    DisplaySetMonth();
    }
  if (menu==5)
    {
    DisplaySetDay();
    }
  if (menu==6)
    {
    StoreAgg(); 
    delay(500);
    menu=0;
    }
    delay(100);
}

void DisplayDateTime ()
{
// We show the current date and time
  DateTime now = RTC.now();

  lcd.setCursor(0, 1);
  lcd.print("Hour:");
  if (now.hour()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.hour(), DEC);
  hourupg=now.hour();
  lcd.print(":");
  if (now.minute()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);
  minupg=now.minute();
  lcd.print(":");
  if (now.second()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.second(), DEC);

  lcd.setCursor(0, 0);
  lcd.print("Date: ");
  if (now.day()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);
  dayupg=now.day();
  lcd.print("/");
  if (now.month()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);
  monthupg=now.month();
  lcd.print("/");
  lcd.print(now.year(), DEC);
  yearupg=now.year();
}

void DisplaySetHour()
{
// time setting
  lcd.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)
  {
    if(hourupg==23)
    {
      hourupg=0;
    }
    else
    {
      hourupg=hourupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if(hourupg==0)
    {
      hourupg=23;
    }
    else
    {
      hourupg=hourupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set time:");
  lcd.setCursor(0,1);
  lcd.print(hourupg,DEC);
  delay(200);
}

void DisplaySetMinute()
{
// Setting the minutes
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    if (minupg==59)
    {
      minupg=0;
    }
    else
    {
      minupg=minupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (minupg==0)
    {
      minupg=59;
    }
    else
    {
      minupg=minupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Minutes:");
  lcd.setCursor(0,1);
  lcd.print(minupg,DEC);
  delay(200);
}
  
void DisplaySetYear()
{
// setting the year
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {    
    yearupg=yearupg+1;
  }
   if(digitalRead(P3)==HIGH)
  {
    yearupg=yearupg-1;
  }
  lcd.setCursor(0,0);
  lcd.print("Set Year:");
  lcd.setCursor(0,1);
  lcd.print(yearupg,DEC);
  delay(200);
}

void DisplaySetMonth()
{
// Setting the month
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    if (monthupg==12)
    {
      monthupg=1;
    }
    else
    {
      monthupg=monthupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (monthupg==1)
    {
      monthupg=12;
    }
    else
    {
      monthupg=monthupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Month:");
  lcd.setCursor(0,1);
  lcd.print(monthupg,DEC);
  delay(200);
}

void DisplaySetDay()
{
// Setting the day
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    if (dayupg==31)
    {
      dayupg=1;
    }
    else
    {
      dayupg=dayupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (dayupg==1)
    {
      dayupg=31;
    }
    else
    {
      dayupg=dayupg-1;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set Day:");
  lcd.setCursor(0,1);
  lcd.print(dayupg,DEC);
  delay(200);
}

void StoreAgg()
{
// Variable saving
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("SAVING IN");
  lcd.setCursor(0,1);
  lcd.print("PROGRESS");
  RTC.adjust(DateTime(yearupg,monthupg,dayupg,hourupg,minupg,0));
  delay(200);
}

refer

พอผมเจอลิงค์ที่พี่ส่งมา ผมพอจะเข้าใจเลยครับพี่ ขอบคุณมากครับผม :pray::blush:

เดี๋ยวผมจะอัพเดทอีกครั้งนะครับพี่ :green_heart:

อืมม อันนี้ผมขอไม่คืนนะครับ เพราะผมก็ไม่มีตังสักบาทเหมือนกัน จ่ายค่าเช่าเว็บหมดแล้ว :rofl:

พี่ครับผมขอโทษ ผมน่าจะรีบครับพี่ มันเลยสะกดเองครับ :laughing: