บทความ Project Home Control ควบคุมเครื่องใช้ไฟฟ้าในบ้านด้วย Android

ตอนที่ 5. - โดย Tumrobot

Add On Analog Switch ( การเพิ่ม อนาล็อค สวิตช์ เข้ากับเครื่อง Home Control )

ตัว HomeControl Kit สามารถใช้โทรศัพท์ Android สำหรับเปิดปิดไฟฟ้าที่บ้านได้ แต่มีคำถามขึ้นมาว่า ถ้าโทรศัพท์แบตเตอรี่หมดหลังจากที่สั่งเปิดไฟไปแล้วล่ะ จะปิดไฟยังไงเหรอ?

คำตอบ มี 3 วิธีครับ
1. ชาร์ตแบตมือถือ แล้วก็กลับมาควบคุมใหม่ครับ (ยุ่งยากไปมั้ย)
2. ตัดไฟตัวเครื่อง HomeControl เลยครับ ถอดปลั๊กเอาก็ได้ ให้กล่องรีเซ็ทไปเลย (เหมือนจะดีขึ้นมานิดนึง)
3. เพิ่ม SW ที่ตัวเครื่อง HomeControl เพื่อที่จะสามารถควบคุม Relay แบบอิสระจากมือถือครับ (เอาไอเดีย วงจรให้ดูก่อนครับ เดี๋ยวไว้ไปเขียน Code มาลองทดสอบกัน )

สัญญาณอะนาล็อก (Analog Signal) เป็นสัญญาณแบบต่อเนื่อง มีลักษณะเป็นคลื่นไซน์ (sine wave) โดยที่แต่ละคลื่นจะมีความถี่และความเข้มของ สัญญาณที่ต่างกัน เมื่อนำสัญญาณข้อมูลเหล่านี้ผ่านอุปกรณ์รับสัญญาณและแปลงสัญญาณก็จะได้ ข้อมูลที่ต้องการ ตัวอย่างของการส่งข้อมูลที่มีสัญญาณแบบอะนาล็อก คือ การส่งผ่านระบบโทรศัพท์

สัญญาณอะนาล็อก เป็นสัญญาณที่มักเกิดขึ้นในธรรมชาติเป็นสัญญาณที่มีความต่อเนื่อง ไม่ได้มีการเปลี่ยนแปลงอย่างรวดเร็ว สัญญาณแบบนี้ เช่น เสียงพูด เสียงดนตรี เป็นต้น

( ที่มา http://th.wikipedia.org )

เนื่องจากว่า PIC MCU มี Pin ที่สามารถอ่านสัญญาณ Analog ได้ดังนั้นเราจึงสามารถประยุกต์ให้ PIN เป็น Input อ่านสัญญาณ Analog แล้วคอยกำหนดว่าต้องเปิดปิดที่ Output ไหนบ้าง

   

จากรูป ข้างบนสามารถต่อ R Divider เพื่อแบ่งแรงดันให้แตกต่างกันออกไป และค่า R ก็สามารถปรับแต่งได้ตามเหมาะสม ซึ่ง Switch แต่ละตัวนั้นจะเป็น Switch แบบกดติดปล่อยดับเมื่อเรากด Switch จะทำให้ค่า R ที่ Switch คล่อมอยู่นั้นเกิดการเปลี่ยค่าเป็น 0 โอมห์ นั่นก็คือจะส่งผลให้ค่า R รวมเปลี่ยนแปลงไปและเกิดแรงดันที่ PIN Analog ของ MCU อ่านได้ค่าแตกต่างกันออกไปนั่นเอง

ข้อดีคือ ประหยัด Port ของ MCU เราสามารถใช้ PIN แค่ 1 PIN ก็สามารถรับรู้สถานะกด หรือ ปล่อยของ Switch แต่ละตัวได้ และสามารถสั่งให้ Relay เปิด/ปิด ได้ในกรณีที่ Switch Main ไม่ได้เปิดใช้งานอยู่

ข้อเสีย สัญญาณ Analog ไม่คงที่จะมีการเปลี่ยนค่าและมีความคลาดเคลื่อนของแรงดันที่อ่านได้ ต้องอาศัยการปรับแต่งเข้ามาช่วย และไม่สามารถแยกการใช้งานที่อิสระระหว่าง Switch จึ่งจะเป็นจะต้องกดใช้งานให้เสร็จรอบการทำงานของแต่ละ Switch และถ้าหากว่า Switch Main เปิดใช้งานอยู่ก็จะไม่สามาถสั่งเปิด/ปิด Relay ได้เช่นกัน

การเพิ่ม Code ลงในโปรแกรมของ MCU สามารถเพิ่ม Library "AN_Switch.c" ลงไปในโปรแกรมตัวเดิมได้เลยครับ ด้วยการ #include "AN_Switch.c" ลงบน HomeCtrl_main.c

ในส่วนของ Function Main อย่าลืม set_tris_a(0b00000001); ที่ RA0 ต้อง Set เป็น Input ด้วยครับ

ใน while(1) ของ Program Main ก็สามารถเพิ่มการเรียก function Check_Analog_SW(); เข้าไปได้เลยครับ

Library AN_Switch.c ( ดาวน์โหลดได้ ที่นี่ )

 

long voltage = 0;
int voltage_adj = 0;

int16 OP1_ON_CNT = 0;
int16 OP1_OFF_CNT = 0;

int16 OP2_ON_CNT = 0;
int16 OP2_OFF_CNT = 0;

int16 OP3_ON_CNT = 0;
int16 OP3_OFF_CNT = 0;

int16 OP4_ON_CNT = 0;
int16 OP4_OFF_CNT = 0;

int16 OP5_ON_CNT = 0;
int16 OP5_OFF_CNT = 0;

int16 OP6_ON_CNT = 0;
int16 OP6_OFF_CNT = 0;

#define Time 10 // สำหรับเลือก ADC ที่เป็นค่าที่ตั้งใจกด SW เท่านั้น
#define SW_Debunce 500

void ALL_OP_CLR()
{
OP1_ON_CNT = 0;
OP1_OFF_CNT = 0;

OP2_ON_CNT = 0;
OP2_OFF_CNT = 0;

OP3_ON_CNT = 0;
OP3_OFF_CNT = 0;

OP4_ON_CNT = 0;
OP4_OFF_CNT = 0;

OP5_ON_CNT = 0;
OP5_OFF_CNT = 0;


OP6_ON_CNT = 0;
OP6_OFF_CNT = 0;

}

long ADC_Read()
{
long adc;

set_adc_channel(0); // RA1_ANALOG
delay_us(10);

adc = read_adc(); // Read a value from the ADC

LCDGotoXY(1,1);
printf(WriteLCDData,"%lu",adc); // เขียนข้อความลงบน LCD ลงในบรรทัดที่ 1 ปิดถ้าไม่ต้องการการ Debug

LCDGotoXY(4,1);
printf(WriteLCDData," %lu ",OP10_ON_CNT); // เขียนข้อความลงบน LCD ลงในบรรทัดที่ 1 ปิดถ้าไม่ต้องการการ Debug

switch(adc) //ปรับ ADC ไม่นิ่งเผื่อเอาไว้
{
case 1003: voltage_adj = 0;
break;

case 1002: voltage_adj = 1;
break;

case 1001: voltage_adj = 2;
break;

case 999: voltage_adj = 3;
break;

case 998: voltage_adj = 4;
break;

case 997: voltage_adj = 5;
break;

case 996: voltage_adj = 6;
break;

case 995: voltage_adj = 7;
break;

case 994: voltage_adj = 8;
break;

case 993: voltage_adj = 9;
break;

case 992: voltage_adj = 10;
break;

}

return (adc);

}

void Check_Analog_SW()
{

ALL_OP_CLR();

voltage = ADC_Read();
//==============================================================================
//Relay 1
while( voltage >= 979 && voltage <= 989 && OP1_flag == 0 ) // Relay 1 filter 300Ms ให้แน่ใจว่าเกิดจากการกดจริง
{
OP1_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP1_ON_CNT > Time )
{
OP1_flag = 1;
output_high(OP1);
delay_ms(SW_Debunce); // Delay 500 Ms เพื่อป้องกันเปิดปิด สลับกัน
}
}

while( voltage >= 979 && voltage <= 989 && OP1_flag > 0 )
{
OP1_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP1_OFF_CNT > Time )
{
OP1_flag = 0;
output_low(OP1);
delay_ms(SW_Debunce);
}
}

//==============================================================================
//Relay 2
while( voltage >= 970 && voltage <= 978 && OP2_flag == 0 ) // Relay 2
{
OP2_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if(OP2_ON_CNT > Time )
{
OP2_flag = 1;
output_high(OP2);
delay_ms(SW_Debunce);
}
}

while( voltage >= 970 && voltage <= 978 && OP2_flag > 0 )
{
OP2_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP2_OFF_CNT > Time )
{
OP2_flag = 0;
output_low(OP2);
delay_ms(SW_Debunce);
}
}

//==============================================================================
//Relay 3
while( voltage >= 959 && voltage <= 969 && OP3_flag == 0 ) // Relay 3
{
OP3_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP3_ON_CNT > Time ) // แก้บัค ADC ไม่นิ่ง
{
OP3_flag = 1;
output_high(OP3);
delay_ms(SW_Debunce);
}
}

while( voltage >= 959 && voltage <= 969 && OP3_flag > 0 )
{
OP3_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP3_OFF_CNT > Time )
{
OP3_flag = 0;
output_low(OP3);
delay_ms(SW_Debunce);
}
}

//==============================================================================
//Relay 4
while( voltage >= 943 && voltage <= 953 && OP4_flag == 0 ) // Relay 4
{
OP4_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP4_ON_CNT > Time ) // แก้บัค ADC ไม่นิ่ง
{
OP4_flag = 1;
output_high(OP4);
delay_ms(SW_Debunce);
}
}

while( voltage >= 943 && voltage <= 953 && OP4_flag > 0 )
{
OP4_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP4_OFF_CNT > Time )
{
OP4_flag = 0;
output_low(OP4);
delay_ms(SW_Debunce);
}
}

//==============================================================================
//Relay 5
while( voltage >= 870 && voltage <= 880 && OP5_flag == 0 ) // Relay 5
{
OP5_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP5_ON_CNT > Time ) // แก้บัค ADC ไม่นิ่ง
{
OP5_flag = 1;
output_high(OP5);
delay_ms(SW_Debunce);
}
}

while( voltage >= 870 && voltage <=880 && OP5_flag > 0 )
{
OP5_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP5_OFF_CNT > Time )
{
OP5_flag = 0;
output_low(OP5);
delay_ms(SW_Debunce);
}
}

//==============================================================================
//Relay 6
while( voltage >= 785 && voltage <= 795 && OP6_flag == 0 ) // Relay 6
{
OP6_ON_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP10_ON_CNT > Time )
{
OP6_flag = 1;
output_high(OP6);
delay_ms(SW_Debunce);
}
}

while( voltage >= 785 && voltage <= 795 && OP6_flag > 0 )
{
OP6_OFF_CNT++;
voltage = ADC_Read();
delay_ms(1);

if( OP6_OFF_CNT > Time )
{
OP6_flag = 0;
output_low(OP6);
delay_ms(SW_Debunce);
}
}

Exit_SW_Select: delay_us(1);

} //==============================================================================
//End Program

 

ป.ล. จากการทดสอบใช้แรงดัน 5V เข้าที่ R1 ค่า 47K ผลการทดสอบพบว่าแรงดันจาก Switching มีการแกว่งอยู่ที่ +/- 5% ทำให้ค่า Analog ที่อ่านเข้ามาที่ MCU มีความผิดพลาดซึ่งจะทำให้ TACT SW กดติดบ้างไม่ติดบ้าง วิธีแก้ไขให้ทดสอบย้ายแรงดัน 5V ไปที่ 3.3V ในส่วนของ LM1117-3.3 ดีกว่าครับ ซึ่งจะได้แรงดัน Output ที่แน่นอนกว่า และทำให้ TACT SW มีความแม่นยำมากกว่า

 

การควบคุม Switch ของเครื่อง Home Control แบบอิสระด้วย Switch เปิด/ปิด 2 ทาง

เป็นอีก 1 วิธีที่เราสามารถเพิ่ม Switch เปิด/ปิดไฟบ้านที่เราใช้กันปัจจุบันโดยการเปลี่ยนมาเป็น Switch เปิด/ปิด 2 ทาง

 

 

 

ส่วนวิธีการต่อใช้งานการต่อดังรูปต่อไปนี้

   

 

ข้อดี สามารถควบคุมได้อิสระจากทั้งสองฝั่งคือฝั่ง Switch main ก็สามารถสั่งเปิด/ปิดได้ และจากเครื่อง Home Control ก็สามารถสั่งเปิด/ปิดได้ เหมือนกัน ไม่ว่าจะเป็นการลืมปิดไฟ หรืออยากให้เปิด/ปิด ไฟตอนไหนก็สามารถทำได้อย่างอิสระ

ข้อเสีย ต้องเดินสายไฟเพิ่มขึ้นอีก 1 เส้นเพื่อเข้ากับเครื่อง Home Control ซึ่งถ้าหากว่าตัวเครื่องอยู่ห่างกับ Switch ควบคุมก็จะทำให้ต้องเดินสายไฟเพิ่มขึ้นมาเป็นระยะทางที่ไกลขึ้น และที่สำคัญหากติดตั้งวิธีการนี้เรียบร้อยแล้ว เราไม่สามารถที่จะปลดเครือง Home Control ออกจากระบบได้ ไม่เช่นนั้นจะทำให้ Switch main ไม่สามารถเปิด/ปิดไฟได้ ซึ่งถ้าหาต้องการนำเครื่อง Home Control ออกจากระบบจะต้องทำการลัดวงจร Switch อีกตัวระหว่าง Pin 1 และ Pin 2 ให้เชื่อมต่อเข้าหากันด้วย

 

อ่านต่อ ตอนที่ 6