บทเรียน 14/31-3: ตัวอย่างการเขียนโค้ด millis() ของ Arduino ครั้งที่ 3 ร่วมกับปุ่มกด
คุณเคยต้องการให้ Arduino ของคุณจำได้ไหมว่าเมื่อไหร่ที่บางสิ่งเกิดขึ้น—เช่นการกดปุ่ม—แล้วดำเนินการตามในช่วงเวลาที่แม่นยำในภายหลัง โดยที่โปรแกรมส่วนที่เหลือยังทำงานได้อย่างราบรื่น? นี่คือความท้าทายคลาสสิกในการเขียนโปรแกรม Arduino และวิธีแก้ไขคือฟังก์ชัน millis() บทช่วยสอนนี้ ซึ่งเป็นส่วนหนึ่งของคอร์ส Arduino ของ Robojax สาธิตตัวอย่างที่ใช้งานได้จริง: การตรวจจับว่าปุ่มกดถูกกดครั้งที่สองหลังจากเวลาหน่วง 5 วินาทีผ่านไปนับตั้งแต่การกดครั้งแรก เทคนิคนี้เป็นพื้นฐานสำหรับการสร้างโปรเจกต์ที่ไม่บล็อกการทำงานและตอบสนองได้ดี ซึ่งเวลามีความสำคัญอย่างยิ่ง
รูปแบบการใช้ millis() เพื่อติดตามเวลาโดยไม่หยุดโปรแกรมนี้มีความจำเป็นสำหรับการใช้งานจริงที่หลากหลาย นี่คือแนวคิดบางประการเพื่อสร้างแรงบันดาลใจให้กับโปรเจกต์ของคุณเอง:
- อินเทอร์เฟซปุ่มกดแบบ Debounced: ใช้ระบบที่ต้องกดปุ่มค้างไว้ตามระยะเวลาที่กำหนด (เช่น 3 วินาที) เพื่อเปิดเครื่องอุปกรณ์ ป้องกันการกดโดยไม่ตั้งใจ
- การดำเนินการตามลำดับ: สร้างระบบที่เหตุการณ์หนึ่ง เช่น การตรวจจับการเคลื่อนไหว กระตุ้นการทำงานรองที่จะเกิดขึ้นก็ต่อเมื่อมีเหตุการณ์อื่นเกิดขึ้นภายในกรอบเวลาที่กำหนด
- ตัวจับเวลาการโต้ตอบกับผู้ใช้: สร้างโปรเจกต์ที่ต้องมีการป้อนข้อมูล "ยืนยัน" (เช่นการกดปุ่มครั้งที่สอง) ภายในเวลาที่กำหนดเพื่อดำเนินการฟังก์ชันที่สำคัญ เช่นการส่งคำสั่งหรือเริ่มมอเตอร์
- การควบคุมเซนเซอร์: ใช้สัญญาณแรกจากเซนเซอร์เพื่อเริ่มกรอบเวลา ซึ่งในช่วงเวลานั้น การอ่านค่าจากเซนเซอร์ตัวที่สองที่แตกต่างกันจะถือว่าถูกต้องหรือถูกเพิกเฉย
ฮาร์ดแวร์ที่ต้องใช้
โปรเจกต์นี้ใช้ชิ้นส่วนจากชุด Arduino 3-in-1 ของ SunFounder ซึ่งเป็นแหล่งเรียนรู้ที่ดี คุณจะต้องมี:
- บอร์ด Arduino (Uno, Nano ฯลฯ)
- ปุ่มกดแบบชั่วขณะ
- สายจัมเปอร์
คู่มือการเดินสายไฟ
การเดินสายไฟสำหรับตัวอย่างนี้ง่ายมาก ต้องขอบคุณตัวต้านทาน pull-up ภายในของ Arduino ซึ่งไม่จำเป็นต้องใช้ตัวต้านทานภายนอก (ในวิดีโอที่เวลา 08:29)
- เชื่อมต่อขาหนึ่งของปุ่มกดเข้ากับพิน GND บน Arduino
- เชื่อมต่อขาอีกข้างของปุ่มกดเข้ากับ ดิจิทัลพิน 2 บน Arduino
โดยการใช้ INPUT_PULLUP พินจะเชื่อมต่อภายในกับ 5V ดังนั้นจึงอ่านค่าได้เป็น HIGH โดยปกติ เมื่อกดปุ่ม จะเชื่อมต่อพินกับ GND ทำให้อ่านค่าเป็น LOW นี่คือตรรกะที่เราจะใช้ในโค้ด
คำอธิบายโค้ด
หัวใจของโปรเจกต์นี้คือตรรกะที่ติดตามการกดปุ่มครั้งแรก จากนั้นตรวจสอบการกดครั้งที่สองหลังจากช่วงเวลาที่กำหนด โค้ดถูกออกแบบให้ไม่บล็อกการทำงาน หมายความว่าจะไม่หยุดการทำงานของงานอื่น ๆ ใน loop() ของคุณ
ที่ด้านบนของสเก็ตช์ คุณจะพบตัวแปรสำคัญที่ผู้ใช้สามารถกำหนดค่าได้ ซึ่งควบคุมพฤติกรรมด้านเวลา:
unsigned long event = 5000;// 5 วินาที
unsigned long buttonPushed =0;
event: นี่คือตัวแปรเวลาที่สำคัญ โดยกำหนดระยะเวลาหน่วงเป็นมิลลิวินาที ในตัวอย่างนี้ตั้งค่าเป็น5000ซึ่งเท่ากับ 5 วินาที คุณสามารถเปลี่ยนค่านี้เป็นระยะเวลาอื่น ๆ ได้ตามความต้องการของโปรเจกต์buttonPushed: ตัวแปรนี้ใช้เป็นทั้งแฟล็กและตัวบันทึกเวลา เริ่มต้นที่0และจะถูกอัปเดตเป็นค่าของmillis()ในครั้งแรกที่กดปุ่ม เวลาที่เก็บไว้นี้จะถูกใช้เพื่อคำนวณความแตกต่างสำหรับการตรวจสอบการกดครั้งที่สอง
ตรรกะในฟังก์ชัน loop() ทำงานเป็นสองขั้นตอน ขั้นแรก อ่านสถานะของปุ่ม และหากถูกกดเป็นครั้งแรก (pb == LOW && buttonPushed == 0) จะบันทึกเวลาปัจจุบันผ่าน millis() ลงในตัวแปร buttonPushed ขั้นตอนที่สองตรวจสอบว่าปุ่มยังถูกกดอยู่หรือไม่ และมีการบันทึกการกดครั้งแรกแล้วหรือไม่ หากใช่ จะคำนวณความแตกต่างของเวลาระหว่างเวลาปัจจุบันกับเวลาของการกดครั้งแรก หากความแตกต่างนี้มากกว่าหรือเท่ากับเวลา event ของคุณ จะดำเนินการตามที่กำหนด—ในกรณีนี้คือการพิมพ์ข้อความไปยัง Serial Monitor
การสาธิตโปรเจกต์สด
ในวิดีโอ โค้ดถูกอัปโหลดไปยัง Arduino และเปิด Serial Monitor เพื่อสังเกตพฤติกรรม (ในวิดีโอที่เวลา 16:03) คุณจะเห็นค่าของ millis() พิมพ์ออกมาอย่างต่อเนื่อง แสดงเวลาตั้งแต่โปรแกรมเริ่มทำงาน เมื่อคุณกดปุ่มครั้งแรก ข้อความเช่น First push at:5019 จะถูกพิมพ์ หากคุณกดปุ่มอีกครั้งและค้างไว้นานกว่า 5 วินาทีนับจากการกดครั้งแรก ข้อความ Action after 5 seconds of first push จะถูกพิมพ์ ซึ่งแสดงให้เห็นว่าการดำเนินการจะถูกกระตุ้นก็ต่อเมื่อการกดครั้งที่สองเกิดขึ้นหลังจากเวลาที่กำหนดผ่านไปแล้ว
พลังของวิธีการนี้คือบรรทัด Serial.println(millis()) ที่ด้านบนของลูปยังคงทำงานต่อไปโดยไม่หยุดชะงัก พิสูจน์ว่าตรรกะการจับเวลาไม่ได้บล็อกการทำงานของโค้ดอื่น ๆ นี่คือข้อได้เปรียบพื้นฐานของการใช้ millis() แทนฟังก์ชัน delay()
โปรเจกต์ที่เกี่ยวข้องจากวิดีโอนี้
- บทเรียน 14/31-1: ฟังก์ชัน Arduino Millis (ไม่ใช้ delay) และ map | SunFounder Robojax
- บทเรียน 14/31-2: ตัวอย่างการเขียนโค้ด Arduino millis() ครั้งที่ 2 พร้อมเหตุการณ์
- บทเรียน 14/31-4: ตัวอย่างการเขียนโค้ด Arduino map() ครั้งที่ 1
- บทเรียน 14/31-5: ตัวอย่างการเขียนโค้ด Arduino map() ครั้งที่ 2
บทต่างๆ
- [00:00] แนะนำ millis() และหลักสูตร
- [01:19] millis() คืออะไรและทำไมต้องใช้?
- [03:06] ตัวอย่างปฏิบัติแรก: การพิมพ์ millis()
- [05:46] การใช้ millis() เพื่อเรียกเหตุการณ์หลังจาก 5 วินาที
- [08:29] ตัวอย่างที่ 2: การกดปุ่มพร้อมดีเลย์ 5 วินาที
- [12:14] ตัวอย่างที่ 3: การตรวจจับการกดปุ่มครั้งที่สองหลังจากดีเลย์
- [17:20] แนะนำฟังก์ชัน map()
- [19:47] ตัวอย่างปฏิบัติของการแมปเปอร์เซ็นต์ความสว่าง LED
/*
Lesson 14/31: Arduino coding millis() example 3 with push button
Get this code and watch video Download and resource page https://robojax.com/RJT597
YouTube video https://www.youtube.com/watch?v=lqgzQohNiIM
* 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/>.
*/
unsigned long event = 5000;// 5 seconds
unsigned long buttonPushed =0;
void setup() {
Serial.begin(9600);//initialize serial monitor
Serial.println("Introduction to millis");
pinMode(2,INPUT_PULLUP);
}
void loop() {
// ilmoFan.com example-2 millis()
Serial.println(millis());
int pb = digitalRead(2);// read pin 2
if(pb ==LOW && buttonPushed ==0)
{
buttonPushed =millis();
Serial.print("First push at:");
Serial.println(buttonPushed);
}
if( pb ==LOW && buttonPushed >0 )
{
unsigned long difference = millis()- buttonPushed;
if( difference >= event)
{
Serial.println("Action after 5 seconds of first push");
}
}
}
สิ่งที่คุณอาจต้องการ
-
อเมซอน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
ไฟล์📁
คู่มือผู้ใช้
-
SunFounder 3-in-1 Arduino Smart Car assembly manualThis document shows step by step assembly of SunFounder 3-in-1 Arduino Smart Car
SunFounder_car_assembly_manual.pdf1.20 MB