Push Button กดติดปล่อยดับ
การใช้งานสวิตช์ ต่อกับ ATmega328P เพื่อใช้การกดปุ่ม ให้เป็น Input ให้กับ ATmega328P ในการประมวลผลต่อไป เช่น การเขียนโปรแกรมให้กดสวิตช์แล้วให้ไฟติด แล้วเมื่อปล่อยสวิตช์ให้ไฟดับ โดยเราจะกำหนดสัญญาณ 0 หรือ 1 ให้กับขาของ ATmega328P ที่ต่อกับสวิตช์ไว้ตลอด
การที่เราต้องกำหนดสัญญาณ 0 หรือ 1 ให้กับสวิตช์ไว้ตลอดก็เพราะปกติแล้วจะสัญญาณรบกวนที่อาจทำให้ขาของ ATmega328P มีค่าเปลี่ยนแปลงระหว่าง 0 หรือ 1 อยู่บ่อย ๆ จึงต้องจ่ายสัญญาณให้เพื่อป้องกันสัญญาณรบกวน

ปุ่มกด (Push Button) หรือสวิตซ์ (Switch) เป็นอุปกรณ์พื้นฐานที่ใช้กันทั่วไปในหลายๆ โปรเจค เพื่อเชื่อมจุด 2 จุดในวงจรให้ถึงกัน มักใช้เพื่อรับข้อมูลจากผู้ใช้ เช่น เมื่อผู้ใช้กดปุ่มให้อุปกรณ์ที่ต่อพ่วงเริ่มทำงาน หรืออาจจะรับสัญญาณจากกลไกต่างๆ เช่น เมื่อวัตถุเคลื่อนที่มาถึงลิมิตสวิตซ์ (Limit Switch) ให้เครื่องจักรหยุดทำงาน เป็นต้น นอกจากนี้ยังสามารถใช้ความรู้นี้ไปประยุกต์ต่อกับเซ็นเซอร์ (Sensor) บางประเภทได้อีกด้วย แต่อย่างไรก็ตามในบทความนี้จะเน้นไปที่การใช้สวิตซ์กดแบบธรรมดา
รายการอุปกรณ์
- 1. ชุดคิทต่อวงจร Minimum ATmega328P Circuit
- 2. Breadboard 700 Points SYB-120
- 3. Jumper (M2M) cable 10cm Male to Male
- 4. FT232RL FTDI USB To TTL Serial Converter Module
- 5. USB Male to Mini USB B 5pin Data Cable
- 6. Push Button Switch สวิตช์กดติดปล่อยดับ 2 ขา
- 7. รีซิสเตอร์ 10K Ohm 1/4W 5%
ขั้นตอนการทํางาน
1 : ทดสอบโปรแกรมแรก กับ ATmega328P
โปรแกรมแรกของ การใช้งานไมโครคอนโทรลเลอร์มักจะเป็น Blink ไฟกะพริบ ซึ่งเป็นหนึ่งในโปรแกรมที่ง่ายที่สุดเท่าที่จะเป็นไปได้ในการเขียนภาษาโปรแกรมต่างๆ เพราะฉะนั้นโดยธรรมเนียมปฏิบัติแล้ว มักจะใช้ในการตรวจสอบว่าเขียนภาษาโปรแกรมได้ถูกต้องหรือระบบมีการประมวลผลที่ถูกต้อง และมักถูกใช้เป็นตัวอย่างที่ง่ายที่สุดในการแสดงผลลัพธ์ของการเขียนโปรแกรม โดยทำตามขั้นตอนลิงค์ด้านล่าง
2: เขียนโค้ดภาษาซีแบบ External Pull Up
เขียนโค้ดและอัพโหลดโค้ดตามขั้นตอนปรกติ โดยโค้ดนี้เขียนไว้สำหรับ วงจร ATmega328P ที่การต่อตัวต้านทานค่าหนึ่ง เรียกว่า Pull-UP Resistor ไว้ภายนอกไมโครคอนโทรลเลอร์ ATmega328P
#define F_CPU 16000000UL // Arduino UNO use a 16Mhz Crystal as Clock Source
#include <avr/io.h> // Contains all the I/O Register Macros
#include <util/delay.h> // Generates a Blocking Delay
int main(void)
{
DDRB |= 1 << 5; // Configuring PB5 as Output
DDRB &= ~(1<<0); // Configuring PB0 as Input
while (1)
{
if ((PINB&(1<<0)) == 1) // Reading the Pin Value
{
PORTB |= 1<<5; // Writing HIGH to glow LED
}
else
{
PORTB &= ~(1<<5); // Writing LOW
}
}
}




2.1: ต่อสวิตซ์แบบ Pull-Up Resistor

โดยจะต่อตัวต้านทานค่าหนึ่ง เรียกว่า Pull-UP Resistor ไว้ที่ไฟเลี้ยง VCC เพื่อเป็นการรักษาระดับแรงดันไฟฟ้าให้เป็น HIGH ตลอด , ATmega328P Input ขา PB0 จึงอ่านค่าได้เป็น HIGH ตลอด แต่เมื่อกดปุ่ม Button , กระแสไฟฟ้าจะไหลลง Ground ทันที Input ขา PB0 จึงอ่านค่าได้เป็น LOW


ทดสอบการทำงาน ด้วยโค้ดจากข้อที่ 2
การทำงานของของวิธีต่อตัวต้านทาน แบบ Pull-Up Resistor
- ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น HIGH คือเมื่อเริ่มทำงาน ไฟ LED จะติดค้างไว้ตลอด
- กดปุ่ม จะอ่านค่าได้เป็น LOW คือ ไฟ LED จะดับ และเมื่อปล่อยปุ่มกด ไฟ LED จะกลับมาติด
2.2: ต่อสวิตซ์แบบ Pull-Down Resistor

โดยจะต่อตัวต้านทาน หรือ Pull-Down Resistor ไว้ที่ Ground แทน ส่วนปุ่ม Button จะต่อเข้ากับ VCC เมื่อไม่กดจะมีสถานะเป็น LOW แต่เมื่อกดจะเป็น HIGH เพราะกระแสไฟฟ้าจะเลือกไหลเข้าหา ขา PB0 ที่มีความต้านทานน้อยกว่าแทน


ทดสอบการทำงาน ด้วยโค้ดจากข้อที่ 2
การทำงานของของวิธีต่อตัวต้านทาน แบบ Pull-Down Resistor
- ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น LOW คือเมื่อเริ่มทำงาน ไฟ LED จะดับ
- กดปุ่ม จะอ่านค่าได้เป็น HIGH คือ ไฟ LED จะติด และเมื่อปล่อยปุ่มกด ไฟ LED จะดับ
เราจะต่อสวิตซ์เพื่อใช้งานกับ ATmega328P โดยใช้การต่อวงจรที่เรียกว่า Pull-Up Resistor หรือ Pull-Down Resistor อย่างใดก็ได้ เพื่อป้องกันไม่ให้ขา Input อยู่ในสถานะ Floating จนอ่านค่าจากขา Input มาใช้งานไม่ได้
*** Floating เป็นสถานะที่ขา Input ของ MCU ไม่ได้ต่ออยู่กับ VCC หรือ GND อย่างใดอย่างหนึ่งเลย ทำให้เมื่ออ่านค่าจากขา Input นั้น จะได้ค่าออกมาในลักษณะสุ่มระหว่าง LOW และ HIGH แบบไม่สามารถคาดเดาได้ ***
3: เขียนโค้ดภาษาซีแบบ Internal Pull-Up
นอกเหนือจากการต่อวงจร 2 แบบที่ได้อธิบายไว้ด้านบนแล้ว ไมโครคอนโทรลเลอร์ ATmega328P หรือไมโครคอนโทรลเลอร์ อื่นๆ ที่คล้ายกัน ภายในเขาก็ได้ติดตั้งวงจร Pull-Up Resistor มาให้เราในตัวบอร์ดแล้ว (เรียกว่า Internal Pull-Up Resistor) โดยที่เราไม่ต้องหาตัวต้านทานจากภายนอกมาต่อเพิ่ม มีแค่สวิตซ์อย่างเดียวเราก็สามารถต่อวงจรใช้งานได้แล้ว ด้วยการเขียนโค้ดดังนี้
#define F_CPU 16000000UL // Arduino UNO use a 16Mhz Crystal as Clock Source
#include <avr/io.h> // Contains all the I/O Register Macros
#include <util/delay.h> // Generates a Blocking Delay
int main(void)
{
DDRB |= 1 << 5; // Configuring PB5 as Output
DDRB &= ~(1<<0); // Configuring PB0 as Input
PORTB |= 1<<0; // Enabling Internal Pull-Up at PB0
while (1)
{
if ((PINB&(1<<0)) == 1) // Reading the Pin Value
{
PORTB |= 1<<5; // Writing HIGH to glow LED
}
else
{
PORTB &= ~(1<<5); // Writing LOW
}
}
}

สังเกต : จากโค้ดภาษาซีที่เขียนแบบ External Pull Up จะมีการเพิ่มโค้ด บรรทัดนี้เพิ่มเข้าไป
PORTB |= 1<<0; // Enabling Internal Pull-Up at PB0

3.1: ต่อสวิตซ์แบบ Pull-Up Resistor

วิธีการต่อวงจรทำได้โดยต่อขาด้านหนึ่งของสวิตซ์เข้ากับ Input ขา PB0 ส่วนขาอีกด้านหนึ่งต่อเข้ากับ GND ซึ่งคล้ายกับการต่อ Pull-Up Resistor แบบปกติ แต่ต่างกันตรงที่ Resistor ถูกต่อแบบ Pull-Up มาให้ในตัวบอร์ดเรียบร้อยแล้ว


ทดสอบการทำงาน ด้วยโค้ดจากข้อที่ 3
การทำงานของของวิธีต่อตัวต้านทาน แบบ Pull-Up Resistor
- ไม่ได้กดปุ่ม จะอ่านค่าได้เป็น HIGH คือเมื่อเริ่มทำงาน ไฟ LED จะติดค้างไว้ตลอด
- กดปุ่ม จะอ่านค่าได้เป็น LOW คือ ไฟ LED จะดับ และเมื่อปล่อยปุ่มกด ไฟ LED จะกลับมาติด
<<< C3: การเขียนโปรแกรม GPIO เบื้องต้น บทความก่อนหน้า | C5: การใช้งานอินเตอร์รัพท์ บทความต่อไป >>>