นี่คือโปรเจคแรกของพี่ที่ใช้ Arduino UNO ครับน้อง ใช้โค้ดที่ให้ไป เราก็จะสามารถเปลี่ยนความสว่างของ LED ได้อัตโนมัติเลย
โค้ดนี้จะเพิ่มและลดความสว่างของ LED เป็น 255 ขั้น พร้อมดีเลย์ที่เราตั้งได้ โค้ดนี้ใช้ analogWrite(PWM) ในโหมด 8-bit นั่นแปลว่าเราควบคุมความสว่างได้ละเอียดถึง 255 ระดับเลย พี่ลองใช้ตรรกะโค้ดหลายแบบสำหรับโปรเจคนี้
ลงลึกเทคนิค: พัลส์วิดท์มอดูเลชันและดิวตี้ไซเคิล
โปรเจคนี้เผยให้เห็นชั้นต่างๆ ที่ซ่อนอยู่ในปฏิสัมพันธ์ง่ายๆ จากการรับรู้สู่การเรืองแสง กลไกหลักคือ พัลส์วิดท์มอดูเลชัน (PWM) เทคนิคที่สัญญาณดิจิตอลถูกเปิดปิดเร็วมากเพื่อเลียนแบบแรงดันอนาล็อก เปอร์เซ็นต์ของเวลาที่สัญญาณเป็น "เปิด" (HIGH) เทียบกับ "ปิด" (LOW) เรียกว่า ดิวตี้ไซเคิล โดยการปรับดิวตี้ไซเคิลนี้จาก 0% ถึง 100% Arduino ก็จะควบคุมกำลังไฟฟ้าเฉลี่ยที่ส่งไปให้ LED ได้ ทำให้มันดูหรี่แสงได้อย่างลื่นไหล
- ชั้นระบุตัวตน: ไทเมอร์ภายในของ Arduino ทำหน้าที่เป็นเครื่องยนต์เวลาความละเอียดสูง สร้างสัญญาณคลื่นสี่เหลี่ยมที่แม่นยำสำหรับสัญญาณ PWM
- ชั้นแปลงสัญญาณ: ระบบใช้ความละเอียด PWM 8-bit เพื่อจับคู่ 256 ขั้น (0-255) กับดิวตี้ไซเคิลที่ตรงกัน ทำให้ควบคุมความสว่างได้ละเอียด
- ชั้นอินเตอร์เฟซภาพ: LED ความสว่างสูง ให้ผลตอบรับภาพที่ชัดเจนในแต่ละขั้นความสว่าง
- ชั้นประตูสื่อสาร: พินมาตรฐานของ Arduino (ที่รองรับ PWM) เช่น พิน 10 ในโปรเจคนี้ ให้เอาต์พุตทางกายภาพสำหรับสัญญาณ
- ตรรกะการประมวลผล: โค้ด Arduino ใช้กลยุทธ์ "ส่งต่อดิวตี้ไซเคิล": มันตีความคำสั่ง
analogWrite()เพื่อตั้งค่าดิวตี้ไซเคิล PWM สร้างการส่องสว่างเป็นจังหวะ
โครงสร้างพื้นฐานฮาร์ดแวร์-ซอฟต์แวร์
- Arduino Uno: บอร์ดไมโครคอนโทรลเลอร์ที่รันโค้ดและสร้างสัญญาณ PWM
- เอาต์พุต LED: LED ขนาด 10mm ต่อกับพินหมายเลข 10 บนบอร์ด Arduino UNO เป็นเอาต์พุตภาพ
- พิน PWM (พิน 10): พินดิจิตอลที่สามารถส่งสัญญาณ PWM ออกมาเพื่อควบคุมความสว่าง LED
- เบรดบอร์ด: ใช้สร้างวงจรต้นแบบชั่วคราวแบบไม่ต้องบัดกรี
- ตัวต้านทาน (220 โอห์ม): ตัวต้านทานจำกัดกระแสนี้ สำคัญมาก เพื่อป้องกัน LED จากกระแสเกิน ป้องกันไหม้ ต้องต่อแบบอนุกรมกับ LED
- สาย Micro-USB: ใช้สำหรับอัปโหลดโค้ดลง Arduino และจ่ายไฟ

เวอร์ชันแรกของโค้ด
ในเวอร์ชันนี้มีลูป while 2 อัน ตอนแรกความสว่างจะสูง ดังนั้นลูป while แรกใช้เพื่อลดความสว่างจาก 255 ลงไป 0 พร้อมดีเลย์ 5 มิลลิวินาที
while(intensity != 0)
{
analogWrite(10, intensity);
delay(d);
intensity = intensity - 1;
}
ลูป while นี้จะจบเมื่อความสว่างกลายเป็น 0 และลูป while ที่สองก็จะเริ่ม ในลูปนี้ความสว่างจะเพิ่มจาก 0 ถึง 255
while((intensity < 255) && (intensity >= 0))
{
analogWrite(10, intensity);
delay(d);
intensity = intensity + 1;
}
int intensity = 255;
int d = 5;
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 10 as an output.
pinMode(10, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
while(intensity != 0) //this loop is to decrement intensity
{
analogWrite(10, intensity);
delay(d);
intensity = intensity - 1;
}
while((intensity < 255) && (intensity >= 0)) //increment intensity
{
analogWrite(10, intensity);
delay(d);
intensity = intensity + 1;
}
}
รหัสเวอร์ชันที่สอง
เวอร์ชันนี้ใช้ตัวแปรสองตัวคือ intensity กับ flag พอ flag เป็น 0 ความสว่าง (intensity) ก็จะเพิ่มขึ้นเรื่อยๆ พอความสว่างขึ้นไปสุดที่ 255 ละ flag ก็จะกลายเป็น 1 ทีนี้พอ flag เป็น 1 ความสว่างก็จะลดลงแทน วนไปเรื่อยๆ แบบนี้แหละ
int intensity = 0;
int flag = 0;
int d = 5;
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
analogWrite(10, intensity);
delay(d);
if(flag == 0)
intensity = intensity + 1;
if(intensity == 255)
flag = 1;
if(flag == 1)
intensity = intensity - 1;
if(intensity == 0)
flag = 0;
}
โค้ดสองเวอร์ชันแรกมันดูยาวไปหน่อย พี่เลยลองย่อดู เวอร์ชันที่สามนี่คือผลลัพธ์ที่ได้
รหัสเวอร์ชันที่สาม
เวอร์ชันนี้พี่ใช้ abs() กับ intensity++ นะ ความสว่างจะเริ่มจาก -255 ขึ้นไปถึง 255 แล้วก็กลับลงมาที่ -255 วนลูปแบบนี้ abs() มันคือฟังก์ชันหาค่าสัมบูรณ์ อย่าง abs(-255) ก็ได้ 255, abs(0) ได้ 0 อะไรแบบนั้น
int intensity = 255;
int d = 5;
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
analogWrite(10,abs(intensity));
delay(d);
if(intensity++ == 256)
intensity = -255;
}
รหัสเวอร์ชันสุดท้าย
นี่คือโค้ดที่สั้นที่สุดแล้ว หลังจากลองผิดลองถูกมาหลายรอบ ใช้ตัวแปร intensitychange มาควบคุมทิศทางการหรี่-สว่าง พอความสว่าง (intensity) ไปชนขอบที่ 0 หรือ 255 เครื่องหมายของ intensitychange ก็จะกลับด้าน ทำให้ทิศทางการเปลี่ยนความสว่างพลิกไปด้วย
int intensity = 255;
int intensitychange = -1;
int d = 5;
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
analogWrite(10, intensity);
delay(d);
intensity = intensity + intensitychange;
if((intensity == 0) || (intensity == 255))
{
intensitychange = -intensitychange;
}
}
ขั้นตอนการทำให้ไฟหรี่-สว่างอัตโนมัติ
กระบวนการทั้งหมดออกแบบมาให้ใช้ง่ายสุดๆ:
- จัดวางชิ้นส่วน: ต่อ LED กับตัวต้านทาน 220 โอห์ม แบบอนุกรมบนเบรดบอร์ด ให้ถูกขา ต่อตัวต้านทานไปที่ขา 10 ของ Arduino และต่อ LED ไปที่ GND
- ตั้งค่าและอัปโหลด: ใน Arduino IDE ก็อปปี้โค้ดเวอร์ชันไหนก็ได้ด้านบนไปวาง ฟังก์ชัน
setup()จะตั้งให้ขา 10 เป็นเอาต์พุต - ลูปทำงานต่อเนื่อง: พออัปโหลดเสร็จ ฟังก์ชัน
loop()ก็จะทำงานไม่หยุด คำนวณค่าความสว่างและอัปเดตสัญญาณ PWM เรียลไทม์ - ดูผลลัพธ์: มองไปที่ LED ของน้อง มันจะหรี่และสว่างขึ้นลงเองอัตโนมัติ เหมือนไฟกำลังเต้นเป็นจังหวะ
ไอเดียพัฒนาต่อ
- เพิ่มจอแสดงผล: ต่อจอ OLED เล็กๆ เพื่อแสดงค่าอะไรก็ได้ เช่น "Duty Cycle (%)" หรือค่าอื่นๆ
- ควบคุมด้วยมือ: ต่อโพเทนชิออมิเตอร์เพื่อใช้ปรับความเร็วหรี่-สว่าง หรือค่าความสว่างสูงสุดด้วย
analogRead() - ควบคุมผ่านเน็ต: เพิ่มโมดูล WiFi เพื่อสั่งงานรูปแบบการหรี่ไฟจากแดชบอร์ดบนเว็บได้
- ปรับรูปแบบการหรี่: แก้โค้ดให้ความสว่างเปลี่ยนแบบไม่เป็นเส้นตรง (เช่น แบบลอการิทึม) จะได้ดูเป็นธรรมชาติขึ้น
[!IMPORTANT] อย่าลืมต่อ ตัวต้านทาน (Resistor) จำกัดกระแส (เช่น 220 โอห์ม) แบบอนุกรมกับ LED ทุกครั้ง ห้ามขาด! ไม่งั้น LED ไหม้แน่นอน ตรวจสอบการต่อวงจรให้ดีก่อนเปิดไฟเลี้ยงเสมอ