บทเรียน 17/31: วิธีขัดจังหวะการหน่วงเวลาใน Arduino และตัวต้านทานที่ไวต่อแสง LDR | Robojax
ในคู่มือนี้ เราจะสำรวจแนวคิดสำคัญสองประการของ Arduino ได้แก่ อินเทอร์รัปต์และตัวต้านทานที่ไวต่อแสง (LDR) คุณจะได้เรียนรู้วิธีขัดจังหวะดีเลย์ในโค้ดของคุณ เพื่อให้ Arduino ตอบสนองต่อการกดปุ่มได้ทันที จากนั้นเราจะสร้างวงจรตรวจจับแสงที่สามารถเปิดออดหรือไฟโดยอัตโนมัติในเวลากลางคืน โปรเจกต์นี้เหมาะสำหรับผู้ที่ต้องการก้าวข้ามการเขียนโค้ดกระพริบ LED พื้นฐาน และเริ่มสร้างโปรเจกต์อัตโนมัติที่ตอบสนองต่อโลกจริง คุณสามารถนำทักษะเหล่านี้ไปประยุกต์ใช้เพื่อสร้างไฟกลางคืนอัจฉริยะสำหรับโถงทางเดิน สัญญาณเตือนความปลอดภัยง่ายๆ ที่ดังเมื่อประตูเปิด ไฟสวนพลังงานแสงอาทิตย์ที่เปิดเมื่อพลบค่ำ หรือม่านอัตโนมัติที่ปิดเมื่อพระอาทิตย์ตกดิน บทเรียนนี้อ้างอิงจากชุด Arduino 3-in-1 ของ SunFounder แต่แนวคิดนี้ใช้ได้กับบอร์ด Arduino มาตรฐานทุกตัว

ฮาร์ดแวร์และอุปกรณ์
เพื่อทำตามโปรเจกต์นี้ คุณจะต้องมีอุปกรณ์ดังต่อไปนี้ Arduino Uno หรือ Nano มาตรฐานเหมาะสำหรับการสร้างนี้
- Arduino Uno หรือ Nano
- ตัวต้านทานที่ไวต่อแสง (LDR) เช่น Kweeds KM601
- ตัวต้านทาน 10k โอห์ม
- ปุ่มกด
- ออด
- เบรดบอร์ดและสายจัมเปอร์
ทำความเข้าใจอินเทอร์รัปต์ของ Arduino
ในสเก็ตช์ Arduino มาตรฐาน ฟังก์ชัน loop() จะทำงานอย่างต่อเนื่อง โดยดำเนินการทีละบรรทัด เมื่อคุณใช้ delay() Arduino จะหยุดทำอย่างอื่นทั้งหมดในช่วงเวลานั้น นี่เป็นปัญหาหากคุณต้องตอบสนองต่อเหตุการณ์สำคัญ เช่น การกดปุ่ม ขณะที่งานอื่นกำลังทำงานอยู่ ตัวอย่างเช่น หากคุณมีดีเลย์หนึ่งวินาทีเพื่อกระพริบ LED การกดปุ่มอาจไม่ถูกรับรู้นานถึงหนึ่งวินาที ซึ่งรู้สึกว่าตอบสนองช้า (ในวิดีโอที่ 08:13)
อินเทอร์รัปต์ของ Arduino แก้ปัญหานี้ได้ อินเทอร์รัปต์เป็นคุณสมบัติฮาร์ดแวร์ที่อนุญาตให้พินเฉพาะ "ขัดจังหวะ" โปรแกรมหลัก หยุดสิ่งที่กำลังทำอยู่ชั่วคราว และรันฟังก์ชันพิเศษที่เรียกว่า Interrupt Service Routine (ISR) ซึ่งช่วยให้ Arduino ตอบสนองต่อเหตุการณ์ที่มีความสำคัญสูงได้ทันที ไม่ว่าสิ่งอื่นจะเกิดขึ้นอะไรก็ตาม สิ่งสำคัญคือต้องทราบว่าไม่ใช่ทุกพินที่รองรับอินเทอร์รัปต์ บน Arduino Uno และ Nano มีเพียงพิน 2 และ 3 เท่านั้นที่ใช้เพื่อจุดประสงค์นี้ได้ (ในวิดีโอที่ 02:37) บอร์ดอื่นๆ เช่น Mega มีตัวเลือกมากกว่า แต่สำหรับโปรเจกต์นี้ เราจะใช้พิน 2
อินเทอร์รัปต์สามารถถูกกระตุ้นได้จากการเปลี่ยนแปลงสถานะต่างๆ บนพิน: LOW, CHANGE, RISING และ FALLING โหมด CHANGE จะกระตุ้นอินเทอร์รัปต์เมื่อใดก็ตามที่สถานะของพินเปลี่ยนจาก HIGH เป็น LOW หรือ LOW เป็น HIGH ซึ่งเหมาะสำหรับการสลับด้วยปุ่มกด
คู่มือการเดินสายไฟ
เราจะสร้างวงจรสองวงจรในบทเรียนนี้ วงจรแรกสาธิตอินเทอร์รัปต์ด้วยปุ่มกดและออด และวงจรที่สองใช้ LDR เพื่อตรวจจับระดับแสง เริ่มต้นด้วยวงจรอินเทอร์รัปต์กันก่อน
วงจรที่ 1: ปุ่มกดและออดสำหรับสาธิตอินเทอร์รัปต์
วงจรนี้ตรงไปตรงมา ปุ่มกดเชื่อมต่อกับพิน 2 ซึ่งเป็นพินอินเทอร์รัปต์ของเรา ตัวต้านทาน 10k โอห์มแบบ pull-down ช่วยให้พินอ่านค่า LOW เมื่อไม่ได้กดปุ่ม และ HIGH เมื่อกดปุ่ม ออดเชื่อมต่อกับพิน 8
สำหรับการสาธิตอินเทอร์รัปต์ ให้เชื่อมต่ออุปกรณ์ดังนี้:
- ปุ่มกด: เชื่อมต่อขาหนึ่งเข้ากับ 5V และอีกขาเข้ากับดิจิทัลพิน 2 เชื่อมต่อตัวต้านทาน 10k โอห์มจากพิน 2 ไปยัง GND
- ออด: เชื่อมต่อขาลบเข้ากับ GND และขาบวกเข้ากับดิจิทัลพิน 8
วงจรที่ 2: LDR และออดสำหรับการตรวจจับแสง
สำหรับวงจร LDR เราใช้การจัดเรียงแบบตัวแบ่งแรงดันไฟฟ้า ความต้านทานของ LDR เปลี่ยนแปลงตามแสง ซึ่งจะเปลี่ยนแรงดันไฟฟ้าที่พินแอนะล็อก เมื่อมืด LDR จะมีความต้านทานสูง (ประมาณ 10k โอห์ม) และเมื่อสว่าง ความต้านทานจะลดลงอย่างมาก (ในวิดีโอที่ 16:25) การเปลี่ยนแปลงความต้านทานนี้คือสิ่งที่เราวัด
ตัวแบ่งแรงดันไฟฟ้าจำเป็นเพราะ Arduino อ่านได้เฉพาะแรงดันไฟฟ้า ไม่ใช่ความต้านทาน โดยการวาง LDR อนุกรมกับตัวต้านทานคงที่ 10k โอห์ม แรงดันไฟฟ้าที่จุดระหว่างทั้งสองจะเปลี่ยนแปลงตามสัดส่วนกับความต้านทานของ LDR แรงดันไฟฟ้านี้จะถูกอ่านโดยตัวแปลงแอนะล็อกเป็นดิจิทัล (ADC) ของ Arduino
สำหรับการสาธิต LDR ให้เชื่อมต่ออุปกรณ์ดังนี้:
- LDR: เชื่อมต่อขาหนึ่งเข้ากับ 5V และอีกขาเข้ากับแอนะล็อกพิน A0
- ตัวต้านทาน 10k โอห์ม: เชื่อมต่อจากขา LDR ที่ไปยัง A0 ลงไปยัง GND เพื่อสร้างตัวแบ่งแรงดันไฟฟ้า
- ออด: เชื่อมต่อขาลบเข้ากับ GND และขาบวกเข้ากับดิจิทัลพิน 8
หมายเหตุ: การกำหนดพินที่แน่นอนถูกกำหนดไว้ในโค้ดและสามารถเปลี่ยนแปลงได้ตามการตั้งค่าของคุณ
คำอธิบายโค้ด
เราจะเน้นที่ส่วนที่ผู้ใช้สามารถกำหนดค่าได้ของโค้ดที่ให้มา ซึ่งควบคุมพฤติกรรมของโปรเจกต์ โปรแกรมเต็มรูปแบบสามารถดาวน์โหลดได้ด้านล่างบทความ
โค้ดถูกออกแบบมาให้แก้ไขได้ง่าย ที่ด้านบนของสเก็ตช์ คุณจะพบตัวแปรสำคัญที่คุณสามารถปรับได้
const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;
ที่นี่ buzzerPin ถูกตั้งค่าเป็นพิน 8 ซึ่งเป็นจุดที่คุณเชื่อมต่อออด interruptPin ถูกตั้งค่าเป็นพิน 2 ซึ่งเป็นพินที่จะคอยฟังการกดปุ่ม ตัวแปร state เป็นไบต์แบบ volatile ที่เก็บสถานะปัจจุบันของออด (HIGH หรือ LOW) มันถูกทำเครื่องหมายเป็น volatile เพราะมันถูกแก้ไขภายในรูทีนบริการอินเทอร์รัปต์ (ISR) และคีย์เวิร์ดนี้ช่วยให้แน่ใจว่า Arduino อ่านค่าล่าสุดเสมอ ตัวแปร count เป็นตัวนับง่ายๆ ที่เพิ่มขึ้นในลูปหลักเพื่อแสดงว่าลูปยังคงทำงานอยู่ขณะที่อินเทอร์รัปต์ทำงาน
ในฟังก์ชัน setup() พินของออดถูกตั้งเป็น OUTPUT และพินอินเทอร์รัปต์ถูกตั้งเป็น INPUT บรรทัดที่สำคัญคือ attachInterrupt() ซึ่งเป็นจุดที่คุณกำหนดค่าอินเทอร์รัปต์ ฟังก์ชันนี้บอก Arduino ว่าต้องเฝ้าดูพินใด เรียกฟังก์ชันใดเมื่อเกิดอินเทอร์รัปต์ และใช้เงื่อนไขการทริกเกอร์แบบใด
attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);
บรรทัดนี้แนบอินเทอร์รัปต์เข้ากับพินที่ระบุ ฟังก์ชัน digitalPinToInterrupt() แปลงหมายเลขพินเป็นหมายเลขอินเทอร์รัปต์ที่ถูกต้อง noisy คือชื่อของฟังก์ชันที่จะถูกเรียกเมื่ออินเทอร์รัปต์ถูกทริกเกอร์ สุดท้าย CHANGE คือโหมด ซึ่งทริกเกอร์อินเทอร์รัปต์เมื่อมีการเปลี่ยนแปลงสถานะใดๆ ของพิน คุณสามารถเปลี่ยนเป็น RISING, FALLING หรือ LOW ได้ตามความต้องการของคุณ
ฟังก์ชัน noisy() คือ ISR มันเป็นฟังก์ชันสลับสถานะง่ายๆ ที่พลิกสถานะของออด เมื่อกดปุ่ม อินเทอร์รัปต์จะทริกเกอร์ฟังก์ชันนี้ ซึ่งจะกลับค่าตัวแปร state และเขียนมันไปยังพินของออด ซึ่งช่วยให้คุณเปิดและปิดออดได้ด้วยการกดปุ่มแต่ละครั้ง แม้ว่าลูปหลักจะยุ่งอยู่กับการนับและหน่วงเวลา
เพื่อเปลี่ยนพฤติกรรมของโปรเจกต์ให้เปิดออดในเวลากลางคืนแทนกลางวัน คุณจะต้องแก้ไขตรรกะเงื่อนไขในลูปหลัก โดยสลับคำสั่ง digitalWrite() สำหรับสถานะ HIGH และ LOW
โปรเจกต์สดและการสาธิต
ในการสาธิต คุณจะเห็นการทดลองสำคัญสองอย่าง อันดับแรก วงจรอินเทอร์รัปต์ถูกแสดงโดยไม่ใช้โค้ดอินเทอร์รัปต์ ซึ่งการหน่วงเวลาในลูปทำให้การตอบสนองของปุ่มช้า สิ่งนี้เน้นปัญหาที่อินเทอร์รัปต์แก้ไข
จากนั้น เมื่อโหลดโค้ดอินเทอร์รัปต์แล้ว จอภาพอนุกรมแสดงตัวนับที่เพิ่มขึ้นทุกวินาที เมื่อกดปุ่ม ออดจะสลับเปิดหรือปิดทันที โดยไม่คำนึงถึงการหน่วงเวลาในลูปหลัก สิ่งนี้พิสูจน์ว่าอินเทอร์รัปต์สามารถเลี่ยงเวลารอและทำงานทันที (ในวิดีโอที่ 14:07)
สำหรับส่วน LDR จอภาพอนุกรมพิมพ์ค่าแอนะล็อกดิบ คุณจะเห็นว่าค่ามีค่าสูง (ประมาณ 960) ในแสงสว่าง และลดลงอย่างมาก (ถึงประมาณ 400 หรือต่ำกว่า) เมื่อเซนเซอร์ถูกบัง สิ่งนี้แสดงให้เห็นว่าความต้านทานของ LDR เปลี่ยนแปลงตามความเข้มของแสงอย่างไร จากนั้นโค้ดใช้ค่าเกณฑ์เพื่อกำหนดว่าเป็น "กลางวัน" หรือ "กลางคืน" และควบคุมออดตามนั้น โดยการบังเซนเซอร์เพื่อจำลองกลางคืน คุณสามารถทริกเกอร์ออด และโดยการให้แสงส่อง คุณสามารถปิดมันได้
บทต่างๆ
- [00:00] แนะนำอินเทอร์รัปต์ Arduino และ LDR
- [01:43] ปัญหาของการหน่วงเวลาในโค้ด Arduino
- [03:37] ทำความเข้าใจพินและโหมดอินเทอร์รัปต์
- [04:20] การเดินสายวงจรปุ่มและออด
- [06:22] คำอธิบายโค้ดสำหรับการสาธิตการหน่วงเวลา
- [07:48] การสาธิตปัญหาการหน่วงเวลา
- [09:26] การติดตั้งและเขียนโค้ดอินเทอร์รัปต์
- [11:50] วิธีการทำงานของฟังก์ชันอินเทอร์รัปต์
- [14:26] แนะนำตัวต้านทานไวแสง (LDR)
- [15:44] การวัดความต้านทาน LDR ด้วยมัลติมิเตอร์
- [17:22] การเดินสายวงจร LDR และออด
- [19:55] โค้ดสำหรับอ่านค่า LDR
- [20:49] การสาธิตการเปลี่ยนแปลงค่า LDR
- [22:08] การตั้งค่าเกณฑ์กลางวันและกลางคืน
- [23:40] โค้ดควบคุมออดด้วย LDR
- [25:21] การสาธิตไฟกลางคืนอัตโนมัติ
/*
Lesson 20/31: interrupt a delay in Arduino and Light Dependent Resistor LDR
Get this code and watch video Download and resource page https://robojax.com/RJT600
YouTube video https://www.youtube.com/watch?v=N_L11m1v_yk
* This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been download from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);
Serial.begin(9600);
digitalWrite(buzzerPin, state);
}
void loop() {
count++;
Serial.println(count);
delay(1000);
}
void noisy() {
state = !state;
digitalWrite(buzzerPin, state);
}
Common Course Links
Common Course Files
สิ่งที่คุณอาจต้องการ
-
อเมซอนSunFounder Arduino Learning Kit on AliExpresss.click.aliexpress.com
-
อเมซอน
-
อเมซอน
-
อเมซอน
-
อเมซอน
แหล่งข้อมูลและเอกสารอ้างอิง
-
เอกสารDocumentation for SunFounder 3 in 1 IoT/Smart Car/Learning Kitdocs.sunfounder.com
-
ภายนอกPurchase SunFounder's 3-in-1 Smart car learning kitsunfounder.com
ไฟล์📁
ไลบรารี Arduino (zip)
-
SunFounder's 3-in-1 Smart Car learning kit source code
3in1-kit-main-v2.zip12.80 MB