Πίνακας περιεχομένων:

Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης: 6 βήματα
Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης: 6 βήματα

Βίντεο: Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης: 6 βήματα

Βίντεο: Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης: 6 βήματα
Βίντεο: Digitalηφιακό ρολόι Python 2024, Νοέμβριος
Anonim
Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης
Digitalηφιακό ρολόι στο Arduino χρησιμοποιώντας μηχανή πεπερασμένης κατάστασης

Γεια σας, θα σας δείξω πώς μπορεί να δημιουργηθεί ένα ψηφιακό ρολόι με το YAKINDU Statechart Tools και να λειτουργεί με Arduino, το οποίο χρησιμοποιεί ασπίδα πληκτρολογίου LCD.

Το αρχικό μοντέλο του ψηφιακού ρολογιού λήφθηκε από τον David Harel. Έχει δημοσιεύσει ένα έγγραφο για το

«[…] ευρεία επέκταση του συμβατικού φορμαλισμού των κρατικών μηχανών και των κρατικών διαγραμμάτων.»

Σε αυτήν την εργασία, χρησιμοποίησε το παράδειγμα του ψηφιακού ρολογιού για την έρευνά του. Το χρησιμοποίησα ως έμπνευση και ξαναέχτισα το ρολόι με το YAKINDU Statechart Tools (ένα εργαλείο για τη δημιουργία γραφικών μοντέλων κρατικών μηχανών και τη δημιουργία κώδικα C/C ++ μαζί του) και το έφερα ξανά στη ζωή με ένα Arduino.

Προμήθειες

Σκεύη, εξαρτήματα:

  • Arduino Uno ή Mega
  • Ασπίδα πληκτρολογίου LCD

Λογισμικό:

  • Εργαλεία YAKINDU Statechart
  • Eclipse C ++ IDE για Arduino

Βήμα 1: Πώς λειτουργεί το ψηφιακό ρολόι

Image
Image

Ας ξεκινήσουμε καθορίζοντας τον τρόπο λειτουργίας του ψηφιακού ρολογιού. Τα θυμάστε αυτά… ας πούμε… «εξαιρετικά δροσερά» ψηφιακά ρολόγια που όλοι είχαν στη δεκαετία του’90; Ενσωματωμένο χρονόμετρο, διαφορετικοί συναγερμοί και ο ενοχλητικός ήχος του κάθε ολόκληρη ώρα. Αν όχι, ρίξτε μια ματιά: ψηφιακό ρολόι της δεκαετίας του '90.

Ουσιαστικά είναι ένα διαμορφώσιμο ρολόι με διαφορετικές λειτουργίες. Κυρίως, θα εμφανιστεί η τρέχουσα ώρα, αλλά υπάρχουν και άλλες δυνατότητες. Ως είσοδος, έχετε ένα κουμπί ενεργοποίησης/απενεργοποίησης, μια λειτουργία και ένα κουμπί ρύθμισης. Επιπλέον, μπορείτε να ανάψετε και να σβήσετε το φως. Με το κουμπί λειτουργίας μπορείτε να διακρίνετε μεταξύ των λειτουργιών και να ενεργοποιήσετε/απενεργοποιήσετε τις λειτουργίες του ρολογιού:

  • Εμφάνιση ώρας (Ρολόι)
  • Εμφάνιση ημερομηνίας (ημερομηνία)
  • Ρυθμίστε το ξυπνητήρι (Ξυπνητήρι 1, Ξυπνητήρι 2)
  • Ενεργοποίηση/απενεργοποίηση κουδουνίσματος (Ορισμός κουδουνίσματος)
  • Χρησιμοποιήστε το χρονόμετρο (Stop Watch)

Μέσα στα μενού, μπορείτε να χρησιμοποιήσετε το κουμπί ενεργοποίησης/απενεργοποίησης για να διαμορφώσετε τη λειτουργία. Το κουμπί ρύθμισης σας επιτρέπει να ρυθμίσετε την ώρα - π.χ. για το ρολόι ή τα ξυπνητήρια. Το χρονόμετρο μπορεί να ελεγχθεί - να ξεκινήσει και να σταματήσει - χρησιμοποιώντας το κουμπί ενεργοποίησης και απενεργοποίησης φωτός. Μπορείτε επίσης να χρησιμοποιήσετε έναν ενσωματωμένο μετρητή γύρου

Επιπλέον, υπάρχει ένας ήχος, ο οποίος κουδουνίζει κάθε ολόκληρη ώρα και ένας ελεγχόμενος οπίσθιος φωτισμός ενσωματωμένος. Στο πρώτο βήμα, δεν τα έβαλα στο Arduino.

Βήμα 2: Η κρατική μηχανή

Ασπίδα πληκτρολογίου LCD
Ασπίδα πληκτρολογίου LCD

Δεν θέλω να επεκταθώ σε πολλές λεπτομέρειες για την εξήγηση αυτού του παραδείγματος. Δεν είναι επειδή είναι πολύ περίπλοκο, είναι λίγο πολύ μεγάλο. Θα προσπαθήσω να εξηγήσω τη βασική ιδέα για το πώς λειτουργεί. Η εκτέλεση πρέπει να είναι αυτονόητη, ρίχνοντας μια ματιά στο μοντέλο ή κατεβάστε και προσομοιώστε το. Ορισμένα μέρη της κρατικής μηχανής αθροίζονται σε υποπεριοχές, όπως η καθορισμένη περιοχή ώρας. Με αυτό, πρέπει να διασφαλιστεί η αναγνωσιμότητα της κρατικής μηχανής.

Το μοντέλο χωρίζεται σε δύο μέρη - ένα γραφικό και ένα κείμενο. Στο κειμενικό μέρος θα καθοριστούν τα γεγονότα, οι μεταβλητές κ.λπ. Στο γραφικό μέρος - το διάγραμμα κατάστασης - καθορίζεται η λογική εκτέλεση του μοντέλου. Για να δημιουργήσετε μια μηχανή κατάστασης, η οποία πληροί την καθορισμένη συμπεριφορά, απαιτούνται ορισμένα συμβάντα εισόδου, τα οποία μπορούν να χρησιμοποιηθούν στο μοντέλο: onoff, set, mode, light, and light_r. Στην ενότητα ορισμού χρησιμοποιείται ένα εσωτερικό συμβάν, το οποίο αυξάνει την τιμή χρόνου κάθε 100 ms:

κάθε 100 ms / ώρα += 1

Με βάση τα βήματα των 100 ms, ο τρέχων χρόνος θα υπολογιστεί σε μορφή HH: MM: SS:

display.first = (time / 36000) % 24;

display.second = (time / 600) % 60; display.third = (time / 10) % 60;

Οι τιμές θα συνδεθούν στην οθόνη LCD χρησιμοποιώντας την ενημέρωση λειτουργίαςLCD κάθε φορά που θα καλείται το μηχάνημα κατάστασης:

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

Η βασική εκτέλεση του μηχανήματος κατάστασης έχει ήδη οριστεί στην ενότητα Πώς λειτουργεί το ψηφιακό ρολόι. Μέσα στο εργαλείο έχω χρησιμοποιήσει κάποια "ειδικά" στοιχεία μοντελοποίησης όπως CompositeState, History, Sub-Diagrams, ExitNodes, κλπ. Μια λεπτομερής περιγραφή μπορείτε να βρείτε στον Οδηγό χρήστη.

Βήμα 3: Ασπίδα πληκτρολογίου LCD

Η ασπίδα πληκτρολογίου LCD είναι αρκετά καλή για απλά έργα, τα οποία απαιτούν οθόνη απεικόνισης και ορισμένα κουμπιά ως είσοδο - ένα τυπικό, απλό HMI (Διεπαφή ανθρώπινου μηχανήματος). Η ασπίδα πληκτρολογίου LCD περιέχει πέντε κουμπιά χρήστη και ένα άλλο για επαναφορά. Τα πέντε κουμπιά όλα μαζί συνδέονται με τον ακροδέκτη A0 του Arduino. Κάθε ένα από αυτά είναι συνδεδεμένο με ένα διαχωριστή τάσης, το οποίο επιτρέπει τη διάκριση μεταξύ των κουμπιών.

Μπορείτε να χρησιμοποιήσετε το analogRead (0) για να βρείτε τις συγκεκριμένες τιμές, οι οποίες, φυσικά, μπορεί να διαφέρουν από τον κατασκευαστή. Αυτό το απλό έργο εμφανίζει την τρέχουσα τιμή στην οθόνη LCD:

#include "Arduino.h"

#include "LiquidCrystal.h" LiquidCrystal LCD (8, 9, 4, 5, 6, 7); void setup () {lcd.begin (16, 2); lcd.setCursor (0, 0); lcd.write ("Μετρούμενη Αξία"); } void loop () {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 static int readButton () {int result = 0; αποτέλεσμα = analogRead (0); εάν (αποτέλεσμα <50) {επιστροφή ΔΕΞΙΑ? } if (αποτέλεσμα <150) {return UP; } if (αποτέλεσμα <300) {return DOWN? } if (αποτέλεσμα <550) {return LEFT? } if (αποτέλεσμα <850) {return SELECT; } επιστροφή ΚΑΝΕΝΑ? }

Βήμα 4: Διασύνδεση της κρατικής μηχανής

Διασύνδεση της κρατικής μηχανής
Διασύνδεση της κρατικής μηχανής

Ο κωδικός C ++ που δημιουργείται στο μηχάνημα κατάστασης παρέχει διεπαφές, οι οποίες πρέπει να εφαρμοστούν για τον έλεγχο του μηχανήματος κατάστασης. Το πρώτο βήμα είναι η σύνδεση των συμβάντων με τα κλειδιά της ασπίδας πληκτρολογίου. Έχω ήδη δείξει πώς να διαβάζετε τα κουμπιά, αλλά για τη διασύνδεσή τους με το μηχάνημα κατάστασης, απαιτείται η κατάργηση του πλήκτρου - διαφορετικά, τα γεγονότα θα εγείρονταν πολλές φορές, γεγονός που οδηγεί σε απρόβλεπτη συμπεριφορά. Η έννοια της κατάργησης λογισμικού δεν είναι καινούργια. Μπορείτε να ρίξετε μια ματιά στην τεκμηρίωση του Arduino.

Κατά την εφαρμογή μου, εντοπίζω πτώση της άκρης (αφήνοντας το κουμπί). Διαβάζω την τιμή του κουμπιού, περιμένω 80 ms (πήρα καλύτερα αποτελέσματα με 80 αντί για 50), αποθηκεύω το αποτέλεσμα και διαβάζω τη νέα τιμή. Εάν το παλιό αποτέλεσμα δεν ήταν ΚΑΝΕΝΑ (χωρίς συμπίεση) και το νέο αποτέλεσμα είναι ΚΑΝΕΝΑ, ξέρω, ότι το κουμπί έχει πατηθεί πριν και τώρα έχει κυκλοφορήσει. Στη συνέχεια, ανεβάζω το αντίστοιχο συμβάν εισόδου της μηχανής κατάστασης.

int oldState = NONE; static void raiseEvents () {int buttonPressed = readButton (); καθυστέρηση (80)? oldState = buttonPressed; if (oldState! = NONE && readButton () == NONE) {switch (oldState) {case SELECT: {stateMachine-> getSCI_Button ()-> raise_mode (); Διακοπή; } περίπτωση ΑΡΙΣΤΕΡΑ: {stateMachine-> getSCI_Button ()-> raise_set (); Διακοπή; } υπόθεση ΚΑΤΩ: {stateMachine-> getSCI_Button ()-> raise_light (); Διακοπή; } case UP: {stateMachine-> getSCI_Button ()-> raise_light_r (); Διακοπή; } περίπτωση ΔΕΞΙΑ: {stateMachine-> getSCI_Button ()-> raise_onoff (); Διακοπή; } προεπιλογή: {break; }}}}

Βήμα 5: Καλωδίωση των πραγμάτων μαζί

Το κύριο πρόγραμμα χρησιμοποιεί τρία μέρη:

  • Η Κρατική Μηχανή
  • Ένα χρονόμετρο
  • Χειριστής οθόνης (τυπικό έντυπο εκτύπωσης LCD (…))

DigitalWatch* stateMachine = νέο DigitalWatch (); CPPTimerInterface* timer_sct = νέο CPPTimerInterface (); DisplayHandler* displayHandler = νέο DisplayHandler ();

Το μηχάνημα κατάστασης χρησιμοποιεί έναν χειριστή οθόνης και πήρε ένα χρονόμετρο, το οποίο θα ενημερωθεί για τον έλεγχο των χρονικών συμβάντων. Στη συνέχεια, η μηχανή κατάστασης αρχικοποιείται και εισέρχεται.

void setup () {stateMachine-> setSCI_Display_OCB (displayHandler); stateMachine-> setTimer (timer_sct); stateMachine-> init (); stateMachine-> enter (); }Ο βρόχος κάνει τρία πράγματα:

  • Αύξηση συμβάντων εισόδου
  • Υπολογίστε τον χρόνο που πέρασε και ενημερώστε το χρονόμετρο
  • Καλέστε το κρατικό μηχάνημα

long current_time = 0; long last_cycle_time = 0; void loop () {raiseEvents (); last_cycle_time = current_time? current_time = millis (); timer_sct-> updateActiveTimer (stateMachine, current_time - last_cycle_time); stateMachine-> runCycle (); }

Βήμα 6: Λάβετε το Παράδειγμα

Αυτό είναι. Πιθανώς, δεν ανέφερα κάθε λεπτομέρεια της εφαρμογής, αλλά μπορείτε να ρίξετε μια ματιά στο παράδειγμα ή να αφήσετε ένα σχόλιο.

Προσθέστε το παράδειγμα σε ένα τρέχον IDE με: Αρχείο -> Νέο -> Παράδειγμα -> Παραδείγματα κρατικών γραφημάτων YAKINDU -> Επόμενο -> Arduino -Watchηφιακό ρολόι (C ++)

> Μπορείτε να κατεβάσετε το IDE εδώ <<

Μπορείτε να ξεκινήσετε με δοκιμή 30 ημερών. Στη συνέχεια, πρέπει να λάβετε μια άδεια, η οποία είναι δωρεάν για μη εμπορική χρήση!

Συνιστάται: