สารบัญ:

นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องสถานะจำกัด: 6 ขั้นตอน
นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องสถานะจำกัด: 6 ขั้นตอน

วีดีโอ: นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องสถานะจำกัด: 6 ขั้นตอน

วีดีโอ: นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องสถานะจำกัด: 6 ขั้นตอน
วีดีโอ: #6 สอน Arduino :เรียน Arduino ควบคุมขา Digital INPUT 2024, พฤศจิกายน
Anonim
นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องไฟไนต์สเตต
นาฬิกาดิจิตอลบน Arduino โดยใช้เครื่องไฟไนต์สเตต

สวัสดี ฉันจะแสดงให้คุณเห็นถึงวิธีการสร้างนาฬิกาดิจิทัลด้วย YAKINDU Statechart Tools และใช้งานบน Arduino ซึ่งใช้ LCD Keypad Shield

นาฬิกาดิจิตอลรุ่นดั้งเดิมนำมาจาก David Harel เขาได้ตีพิมพ์บทความเกี่ยวกับ

"[…] การขยายความเป็นทางการตามแบบแผนของเครื่องของรัฐและไดอะแกรมของรัฐ"

ในบทความนี้ เขาใช้ตัวอย่างของนาฬิกาดิจิทัลในการค้นคว้า ฉันใช้มันเป็นแรงบันดาลใจและสร้างนาฬิกาขึ้นมาใหม่ด้วย YAKINDU Statechart Tools (เครื่องมือสำหรับสร้างแบบจำลองกราฟิกของ state machine และสร้างโค้ด C/C++ ด้วย) และทำให้ Arduino กลับมามีชีวิตอีกครั้ง

เสบียง

ฮาร์ดแวร์:

  • Arduino Uno หรือ Mega
  • แผงปุ่มกด LCD

ซอฟต์แวร์:

  • YAKINDU Statechart Tools
  • Eclipse C++ IDE สำหรับ Arduino

ขั้นตอนที่ 1: วิธีการทำงานของนาฬิกาดิจิทัล

Image
Image

เริ่มต้นด้วยการกำหนดว่านาฬิกาดิจิทัลควรทำงานอย่างไร คุณจำสิ่งเหล่านี้ได้ไหม สมมติว่า… นาฬิกาดิจิตอล "สุดเท่" ที่ทุกคนมีในยุค 90? นาฬิกาจับเวลาในตัว การปลุกแบบต่างๆ และเสียงบี๊บที่น่ารำคาญทุกชั่วโมงเต็ม ถ้าไม่มี ลองดูสิ: นาฬิกาดิจิตอลยุค 90

โดยพื้นฐานแล้วมันเป็นนาฬิกาที่กำหนดค่าได้ด้วยโหมดต่างๆ โดยหลักแล้ว เวลาปัจจุบันจะแสดงขึ้น แต่ก็มีฟีเจอร์อื่นๆ อยู่บ้าง เมื่อป้อนข้อมูล คุณมีปุ่มเปิด/ปิด โหมด และปุ่มตั้งค่า นอกจากนี้ คุณสามารถเปิดและปิดไฟได้ ด้วยปุ่มโหมด คุณสามารถแยกแยะระหว่างโหมดต่างๆ และเปิด/ปิดคุณสมบัตินาฬิกาได้:

  • แสดงเวลา (นาฬิกา)
  • แสดงวันที่ (วันที่)
  • ตั้งปลุก (ปลุก 1, ปลุก 2)
  • เปิด/ปิดเสียงกระดิ่ง (Set Chime)
  • ใช้นาฬิกาจับเวลา (นาฬิกาจับเวลา)

ภายในเมนู คุณสามารถใช้ปุ่มเปิด/ปิดเพื่อกำหนดค่าโหมดได้ ปุ่มตั้งค่าช่วยให้คุณตั้งเวลาได้ เช่น สำหรับนาฬิกาหรือนาฬิกาปลุก นาฬิกาจับเวลาสามารถควบคุม - เริ่มและหยุด - โดยใช้ปุ่มเปิดและปิดไฟ คุณยังสามารถใช้ตัวนับรอบแบบบูรณาการ

นอกจากนี้ยังมีเสียงกริ่งซึ่งจะส่งเสียงกริ่งทุกชั่วโมงเต็ม และไฟแบ็คไลท์ที่ควบคุมได้ในตัว ในขั้นแรก ฉันไม่ได้ต่อเข้ากับ Arduino

ขั้นตอนที่ 2: เครื่องสถานะ

แผงปุ่มกด LCD
แผงปุ่มกด LCD

ฉันไม่ต้องการอธิบายรายละเอียดมากนักสำหรับคำอธิบายของตัวอย่างนี้ ไม่ใช่เพราะมันซับซ้อนเกินไป มันใหญ่เกินไปนิดหน่อย ฉันจะพยายามอธิบายแนวคิดพื้นฐานเกี่ยวกับวิธีการทำงาน การดำเนินการควรอธิบายตนเองโดยดูที่แบบจำลองหรือดาวน์โหลดและจำลอง บางส่วนของเครื่องสถานะจะสรุปในภูมิภาคย่อย เช่น เขตเวลาที่ตั้งไว้ ด้วยเหตุนี้จึงควรตรวจสอบความอ่านง่ายของเครื่องสถานะ

โมเดลนี้แบ่งออกเป็นสองส่วน - กราฟิกและข้อความ ในส่วนของข้อความ เหตุการณ์ ตัวแปร ฯลฯ จะถูกกำหนด ในส่วนกราฟิก - ไดอะแกรมสถานะ - ระบุการดำเนินการเชิงตรรกะของโมเดล ในการสร้างเครื่องสถานะที่ตอบสนองพฤติกรรมที่ระบุ จำเป็นต้องมีเหตุการณ์อินพุตบางอย่าง ซึ่งสามารถใช้ในแบบจำลอง: onoff, set, mode, light และ light_r ภายในส่วนคำจำกัดความจะใช้เหตุการณ์ภายใน ซึ่งจะเพิ่มค่าเวลาทุกๆ 100 มิลลิวินาที:

ทุกๆ 100 ms / ครั้ง += 1

ตามขั้นตอน 100 ms เวลาปัจจุบันจะถูกคำนวณในรูปแบบ HH:MM:SS:

display.first = (เวลา / 36000) % 24;

display.second = (เวลา / 600) % 60; display.third = (เวลา / 10) % 60;

ค่าต่างๆ จะถูกต่อเข้ากับจอ LCD โดยใช้การอัพเดต LCD ทุกครั้งที่มีการเรียกเครื่องสถานะ:

display.updateLCD (display.first, display.second, display.third, display.text)

การดำเนินการพื้นฐานของเครื่องสถานะถูกกำหนดไว้แล้วในส่วน วิธีการทำงานของนาฬิกาดิจิตอล ภายในเครื่องมือนี้ ฉันได้ใช้องค์ประกอบการสร้างแบบจำลอง "พิเศษ" เช่น CompositeState, History, Sub-Diagrams, ExitNodes เป็นต้น คำอธิบายโดยละเอียดสามารถพบได้ในคู่มือผู้ใช้

ขั้นตอนที่ 3: แผงปุ่มกด LCD

LCD Keypad Shield ค่อนข้างเจ๋งสำหรับโปรเจ็กต์ธรรมดาๆ ซึ่งต้องใช้หน้าจอสำหรับการแสดงภาพและบางปุ่มเป็นอินพุต - HMI ทั่วไป (Human Machine Interface) ทั่วไป LCD Keypad Shield มีปุ่มผู้ใช้ห้าปุ่มและอีกปุ่มหนึ่งสำหรับรีเซ็ต ปุ่มทั้ง 5 ปุ่มเชื่อมต่อกับขา A0 ของ Arduino แต่ละตัวเชื่อมต่อกับตัวแบ่งแรงดันไฟฟ้าซึ่งช่วยให้แยกแยะระหว่างปุ่มต่างๆ

คุณสามารถใช้ analogRead(0) เพื่อค้นหาค่าเฉพาะ ซึ่งแน่นอนว่าอาจแตกต่างกันไปตามผู้ผลิต โครงการง่ายๆ นี้แสดงค่าปัจจุบันบน LCD:

#รวม "Arduino.h"

#include "LiquidCrystal.h" จอแอลซีดี LiquidCrystal (8, 9, 4, 5, 6, 7); การตั้งค่าเป็นโมฆะ () { lcd.begin (16, 2); lcd.setCursor(0, 0); lcd.write("ค่าที่วัดได้"); } วงเป็นโมฆะ () { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(analogRead(0)); ล่าช้า(200); }

นี่คือผลลัพธ์ที่วัดได้ของฉัน:

  • ไม่มี: 1023
  • เลือก: 640
  • ซ้าย: 411
  • ลง: 257
  • ขึ้น: 100
  • ขวา: 0

ด้วยเกณฑ์เหล่านี้ คุณจึงสามารถอ่านปุ่มต่างๆ ได้:

#define NONE 0#define SELECT 1 #define LEFT 2 #define DOWN 3 #define UP 4 #define RIGHT 5 int readButton () { ผลลัพธ์ int = 0; ผลลัพธ์ = analogRead(0); ถ้า (ผลลัพธ์ <50) { กลับขวา; } if (ผลลัพธ์ <150) { return UP; } if (ผลลัพธ์ < 300) { กลับลง; } if (ผลลัพธ์ < 550) { return LEFT; } if (ผลลัพธ์ < 850) { return SELECT; } ส่งคืนไม่มี; }

ขั้นตอนที่ 4: เชื่อมต่อเครื่องสถานะ

การเชื่อมต่อเครื่องสถานะ
การเชื่อมต่อเครื่องสถานะ

รหัส C ++ ที่สร้างขึ้นของเครื่องสถานะมีอินเทอร์เฟซซึ่งต้องใช้งานเพื่อควบคุมเครื่องสถานะ ขั้นตอนแรกคือการเชื่อมต่อเหตุการณ์ด้วยปุ่มของ Keypad Shield ฉันได้แสดงวิธีการอ่านปุ่มแล้ว แต่สำหรับการเชื่อมต่อกับเครื่องสถานะ จำเป็นต้องมีการหักล้างปุ่ม - ไม่เช่นนั้น เหตุการณ์จะเพิ่มขึ้นหลายครั้ง ซึ่งส่งผลให้เกิดพฤติกรรมที่คาดเดาไม่ได้ แนวคิดของซอฟต์แวร์ debounding ไม่ใช่เรื่องใหม่ คุณสามารถดูเอกสาร Arduino ได้

ในการใช้งานของฉัน ฉันตรวจพบขอบตก (ปล่อยปุ่ม) ฉันอ่านค่าของปุ่ม รอ 80 ms (ได้ผลลัพธ์ที่ดีกว่าด้วย 80 แทนที่จะเป็น 50) บันทึกผลลัพธ์และอ่านค่าใหม่ ถ้า oldResult ไม่ใช่ NONE (ไม่ได้กด) และผลลัพธ์ใหม่คือ NONE ฉันรู้ ว่าปุ่มนี้เคยถูกกดมาก่อนและตอนนี้ถูกปล่อยออกมาแล้ว จากนั้นฉันเพิ่มเหตุการณ์อินพุตตามของเครื่องสถานะ

int oldState = ไม่มี; โมฆะยกเหตุการณ์คงที่ () { int buttonPressed = readButton (); ล่าช้า (80); oldState = buttonPressed; if (oldState != NONE && readButton () == NONE) { สวิตช์ (oldState) { case SELECT: { stateMachine->getSCI_Button ()->raise_mode (); หยุดพัก; } กรณีซ้าย: { stateMachine->getSCI_Button()->raise_set(); หยุดพัก; } กรณีลง: { stateMachine->getSCI_Button()->raise_light(); หยุดพัก; } กรณีขึ้น: { stateMachine->getSCI_Button()->raise_light_r(); หยุดพัก; } กรณีขวา: { stateMachine->getSCI_Button()->raise_onoff(); หยุดพัก; } ค่าเริ่มต้น: { แบ่ง; } } } }

ขั้นตอนที่ 5: การเดินสายไฟเข้าด้วยกัน

โปรแกรมหลักใช้สามส่วน:

  • เครื่องรัฐ
  • ตัวจับเวลา
  • ตัวจัดการการแสดงผล (โดยทั่วไป lcd.print(…))

DigitalWatch* stateMachine = DigitalWatch ใหม่ ();CPPTimerInterface* timer_sct = CPPTimerInterface ใหม่ (); DisplayHandler* displayHandler = DisplayHandler ใหม่ ();

เครื่องสถานะใช้ตัวจัดการการแสดงผลและได้รับตัวจับเวลา ซึ่งจะได้รับการอัปเดตเพื่อควบคุมเหตุการณ์ที่ตั้งเวลาไว้ หลังจากนั้น เครื่องสถานะจะเริ่มต้นและป้อน

การตั้งค่าเป็นโมฆะ () { stateMachine->setSCI_Display_OCB (displayHandler); stateMachine->setTimer (timer_sct); stateMachine->init(); stateMachine->enter(); }ลูปทำสามสิ่ง:

  • เพิ่มเหตุการณ์อินพุต
  • คำนวณเวลาที่ผ่านไปและอัปเดตตัวจับเวลา
  • เรียกเครื่องรัฐ

current_time นาน = 0; long last_cycle_time = 0; วงเป็นโมฆะ () { ยกเหตุการณ์ (); last_cycle_time = ปัจจุบัน_เวลา; current_time = มิลลิวินาที (); timer_sct->updateActiveTimer (stateMachine, current_time - last_cycle_time); stateMachine->runCycle(); }

ขั้นตอนที่ 6: รับตัวอย่าง

แค่นั้นแหละ. อาจไม่ได้กล่าวถึงทุกรายละเอียดของการใช้งาน แต่คุณสามารถดูตัวอย่างหรือแสดงความคิดเห็นได้

เพิ่มตัวอย่างให้กับ IDE ที่รันอยู่ด้วย: ไฟล์ -> ใหม่ -> ตัวอย่าง -> YAKINDU Statechart Examples -> ถัดไป -> Arduino - Digital Watch (C ++)

> คุณสามารถดาวน์โหลด IDE ได้ที่นี่ <<

คุณสามารถเริ่มต้นด้วยการทดลองใช้ 30 วัน หลังจากนั้น คุณต้องได้รับใบอนุญาต ซึ่งใช้ได้ฟรีสำหรับการใช้ที่ไม่ใช่เชิงพาณิชย์!

แนะนำ: