Arduino Project 4CH Relay Timer #03
โดยปรกติตัวบอร์ด Arduino นั้น จะเริ่มทำงานโดยการ Run คำสั่งในโปรแกรมย่อย setup() และ Loop() ตามลำดับนะครับ ซึ่งโปรแกรมย่อยทั้ง 2 ตัวนี้จำเป็นต้องมีอยู่ในโปรแกรมของเรานะครับ โดยตัวโปรแกรมย่อย Loop() เมื่อโปรแกรมทำงานจนจบ จะทำการเริ่มใหม่อัตโนมัตินะครับ และวนอยู่ในโปรแกรมย่อย Loop() ไปเรื่อย ๆ นะครับ
มาดูกันที่ส่วนหัวของโปรแกรมกันครับ ตัวแปรที่ประกาศในส่วนนี้
จะสามารถใช้งานได้ในทุก ๆ โปรแกรมย่อยนะครับ
//เริ่มจากอ้างอิง Library ที่เราต้องใช้กันก่อน
#include <RTClib.h>
#include <Wire.h> // Required by RTClib
#include <LiquidCrystal.h>
// Required by LCDKeypad
#include <EEPROM.h>
//กำหนดตัวแปรที่ใช้ในการอ้างอิงปุ่มที่เรากด
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
//กำหนดขา และคำสั่งในการเปิด/ปิดไฟของหน้าจอ LCD
#define LCD_BACKLIGHT_PIN
10 // controls
LCD backlight
#define LCD_BACKLIGHT_OFF()
digitalWrite( LCD_BACKLIGHT_PIN, LOW )
#define LCD_BACKLIGHT_ON() digitalWrite( LCD_BACKLIGHT_PIN, HIGH )
//กำหนดตัวแปร LCD และขาที่ใช้งาน |ถ้าไม่อ้างอิง library LiquidCrystal จะเกิด Error นะครับ
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//กำหนดตัวแปรเกี่ยวกับ RTC shield |ถ้าไม่อ้างอิง library RTClibจะเกิด Error นะครับ
RTC_DS3231 RTC;
//สร้างตัวแปร states ขึ้นมา โดยจะมีสถานะตามบทความก่อนหน้านี้นะครับ
enum states
{
MAIN_DISPLAY,
ALARM_NO,
ALARM_SET_MENU,
SET_AL_STATE,
SET_TIME,
};
//จากนั้นกำหนดตัวแปร state ขึ้นมา
states state;
//สร้างตัวแปรขึ้นมาเก็บค่าสถานะของ
Relay แต่ละตัวครับ
//ตรงนี้แนะนำว่าควรเป็นแบบ Array นะครับ เพราะเวลาเขียน Code ควบคุมจะง่ายกว่าการกำหนดแบบแยกแต่ละตัว
//address คือตำแหน่ง memory ใน EEPROM ที่เราจะทำการบันทึกลงไปนะครับ
boolean AlarmSt[4]={0,0,0,0}; //array เก็บสถานะ เปิด/ปิด ของ Relay address 0-3
//เก็บตัวแปร เวลาที่จะเตือน
uint8_t OAlarmHH[4]={0,0,0,0}; //address 4-7
uint8_t OAlarmMM[4]={0,0,0,0}; //address 8-11
uint8_t FAlarmHH[4]={0,0,0,0}; //address 12-15
uint8_t FAlarmMM[4]={0,0,0,0}; //address 16-19
//ตัวแปรอื่น ๆ
ที่จำเป็นต้องใช้งานครับ
int itmMnu; //ตัวแปรเก็บค่าmenu
int button; // เก็บค่าปุ่มที่กด
boolean refreshState; //ตัวแปรไว้ตรวจสอบว่าจะ refresh สถานะ Relay หรือไม่
int SetRelayNumber; //เก็บค่าตัวแปรขณะตั้งค่า Relay
unsigned long timeRef; //จัดเก็บเวลาอ้างอิง
unsigned long timeRefBL; //จัดเก็บเวลาอ้างอิง black light
DateTime now; // ตัวแปรที่เกี่ยวกับเวลาครับ |ถ้าไม่อ้างอิง library RTClibจะเกิด Error นะครับ
|
ต่อไปมาดูในส่วนของโปรแกรมย่อย setup() กันนะครับ
void setup()
{
//ตั้งค่า Out
Put ต่าง ๆ
//ตรงนี้ยังไม่ครบนะครับ
ยังไม่ได้กำหนดขาในส่วนของ Relay เนื่องจากยังไม่ได้ใช้
//ถ้าได้ใช้เมื่อไหร่จะเขียนบอกในบทความต่อ
ๆ ไปนะครับ
pinMode(LCD_BACKLIGHT_PIN,
OUTPUT); //ถ้าไม่กำหนดขาตรงนี้คำสั่งปิดไฟ LCD จะใช้ไม่ได้นะครับ
//โหลดค่าต่าง ๆ ของ Relay มาเก็บไว้ตัวแปรที่เราสร้างไว้นะครับ
โดยเรียกผ่านโปรแกรมย่อย loadEEPROM()
for(int i=1;i<=3;i++)
{
loadEEPROM(i);
}
// ปรับตั้งค่าของ LCD และ RTC ครับ
Serial.begin(9600);
Wire.begin();
lcd.begin(16, 2);
RTC.begin();
// บรรทัดด้านล่างนี้คือคำสั่งตั้งค่าเวลาและวันที่ให้กับ
RTC shield นะครับ
ใช้เฉพาะตั้งเวลาครั้งแรกก็พอ
//โดยต้องใช้ร่วมกับ Library wire นะครับ
เนื่องจากเป็นการรับค่าวันที่และเวลาจากคอมพิวเตอร์
// RTC.adjust(DateTime(__DATE__, __TIME__));
//กำหนดค่าสถานะเริ่มต้นของโปรแกรมนะครับ
กำหนดเป็น MAIN_DISPLAY
state = MAIN_DISPLAY;
//กำหนดระยะเวลาไฟ LCD ครับ
timeRefBL = millis() + 10000;
//กำหนดให้แสดงผลสถานะของ Relay เมื่อเริ่มรันโปรแกรม refreshState=true;
}
|
ต่อไปมาดูในส่วนของโปรแกรมย่อย Loop () กันนะครับ
void loop()
{
//กำหนดเวลาอ้างอิง -> เอาไว้ตรวจสอบ Loop การกดปุ่ม
timeRef = millis();
//ตรวจสอบว่าครบกำหนดแสดงไฟ LCD หรือยัง
if (millis() < timeRefBL
){
LCD_BACKLIGHT_ON();
}else{
LCD_BACKLIGHT_OFF();
}
//คำสั่งเลือกว่าจะให้ทำอะไร
โดยอ้างอิงจากสถานะที่ตัวแปร state
switch (state)
{
case MAIN_DISPLAY:
showTime();
if(refreshState==true){showRelayState();refreshState=false;}
//รอเพิ่มโปรแกรมย่อยตรวจสอบและตั้งค่า
Relay output
break;
case ALARM_NO:
showAlarmNo();
break;
case ALARM_SET_MENU:
showAlarmSet();
break;
case SET_AL_STATE:
setALstate();
break;
case SET_TIME:
setALTime();
break;
}
//Loop ตรวจสอบการกดปุ่มนะครับ เราจะวนรอประมาน 1 วินาที
while ( (unsigned long)(millis() - timeRef) < 970 )
{
button =
read_LCD_buttons();
//โปรแกรมย่อยตรวจสอบการกดปุ่ม
if(button!=btnNONE){ //เมื่อกดปุ่มแล้วให้ทำงานตาม Code ด้านล่างนี้
waitButtonRelease(); //เรียกโปรแกรมย่อย
ตรวจสอบว่ากดปุ่มเสร็จหรือยัง
transition(button); //โปรแกรมย่อย
ตรวจสอบว่าจะทำอะไรเมื่อกดปุ่ม
refreshState=true;
break;
}
}
}
|
นี่ก็เป็นส่วนเริ่มต้นของโปรแกรมนี้นะครับ ในบทความต่อไปจะทยอยเอาโปรแกรมย่อยที่ได้เรียกใช้ทั้งหมดมาแสดงและอธิบายเพิ่มเติมให้ครับ
Arduino tips
การประกาศตัวแปรแบบ Signed และ Unsigned
Signed จะเป็นค่าเริ่มต้นของระบบนะครับ กรณีไม่ได้ระบุว่าเป็น Signed หรือ Unsigned โปรแกรมก็จะกำหนดให้เป็น Signed เลย โดยการประกาศตัวแปรแบบนี้ค่าของตัวแปรนั้นสามารถเป็นค่าติดลบได้ ส่วน
Unsigned จะมีแต่ค่าบวกนะครับ ทำให้สามารถเก็บเฉพาะค่าบวกได้มากกว่าประกาศแบบ Signed ถึง 2 เท่านะครับ
การประกาศตัวแปรแบบ Signed และ Unsigned
Signed จะเป็นค่าเริ่มต้นของระบบนะครับ กรณีไม่ได้ระบุว่าเป็น Signed หรือ Unsigned โปรแกรมก็จะกำหนดให้เป็น Signed เลย โดยการประกาศตัวแปรแบบนี้ค่าของตัวแปรนั้นสามารถเป็นค่าติดลบได้ ส่วน
Unsigned จะมีแต่ค่าบวกนะครับ ทำให้สามารถเก็บเฉพาะค่าบวกได้มากกว่าประกาศแบบ Signed ถึง 2 เท่านะครับ
ความคิดเห็น
แสดงความคิดเห็น