Ρολόι στο Arduino χωρίς τη χρήση μονάδας RTC. Μεγάλο ρολόι τοίχου με αυτόματη φωτεινότητα στο Arduino

Λοιπόν, ρολόι σε πραγματικό χρόνο. Αυτό το χρήσιμο μικρό πράγμα λύνει τα περισσότερα χρήσιμα προβλήματα που σχετίζονται με το χρόνο. Ας υποθέσουμε ότι ελέγχετε το πότισμα στις 5 η ώρα το πρωί στη ντάκα σας. Ή ανάβει και σβήνει τα φώτα σε μια συγκεκριμένη στιγμή. Μέχρι την ημερομηνία μπορείτε να ξεκινήσετε τη θέρμανση σε οποιοδήποτε σπίτι. Το πράγμα είναι αρκετά ενδιαφέρον και χρήσιμο. Και πιο συγκεκριμένα; Θα δούμε το ρολόι σε πραγματικό χρόνο DS1302 για τη δημοφιλή πλατφόρμα Arduino.

Από αυτό το άρθρο θα μάθετε:

Καλημέρα, αγαπητοί αναγνώστες του μπλοκ kip-world! Πώς είσαι? Γράψτε στα σχόλια, σας ενδιαφέρει η ρομποτική; Τι σημαίνει αυτό το θέμα για εσάς;

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

Μπορώ να φανταστώ πόσο πολύπλοκους αλγόριθμους πρέπει να περιέχουν στον «εγκέφαλό» τους.

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

Δείτε τις ταινίες "I-Robot", "Artificial Intelligence", "Star Wars".

Οι Ιάπωνες εφαρμόζουν εδώ και καιρό τις εξελίξεις τους. Γιατί είμαστε χειρότεροι;; Έχουμε πολύ λίγη δημοτικότητα. Ξέρω λίγους προγραμματιστές. Μπορώ να το μετρήσω στα δάχτυλά μου. Κάνουμε κάτι άλλο. Είμαστε μεταπωλητές. Απλώς αγοράζουμε έτοιμα κιτ, ρομπότ, παιχνίδια και κάθε λογής σκουπίδια.

Γιατί δεν το αναπτύσσουμε αυτό:

Ή αυτό:

Τελείωσα τις σκέψεις μου δυνατά. Ας μιλήσουμε για τη σύνδεση του χρονοδιακόπτη πραγματικού χρόνου DS1302 στο Arduino.

Ρολόι πραγματικού χρόνου DS1302

Ο ελεγκτής Arduino δεν έχει δικό του ρολόι. Επομένως, εάν είναι απαραίτητο, πρέπει να συμπληρωθεί με ειδικό μικροκύκλωμα DS1302.

Για τροφοδοσία, αυτές οι πλακέτες μπορούν να χρησιμοποιούν τη δική τους μπαταρία ή να τροφοδοτούνται απευθείας από την πλακέτα Arduino.

Πίνακας pinout:

Διάγραμμα σύνδεσης με το Arduino UNO:


Μέθοδος προγραμματισμού του Arduino για εργασία με DS1302

Είναι επιτακτική ανάγκη να κατεβάσετε μια έγκυρη βιβλιοθήκη από αξιόπιστες πηγές.

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

#περιλαμβάνω // Συνδέστε τη βιβλιοθήκη.
iarduino_RTC ΕΝΑ ΑΝΤΙΚΕΙΜΕΝΟ ( NAME [, RST_OUTPUT [, CLK_OUTPUT [, DAT_OUTPUT ]]] ); // Δημιουργία αντικειμένου.

Λειτουργία αρχίζουν();// Εκκίνηση της λειτουργίας της μονάδας RTC.

Λειτουργία ώρα ρύθμισης( SEC [, MIN [, HOUR [, DAY [, MONTH [, YEAR [, DAY]]]]]] ); // Ρύθμιση της ώρας.

Λειτουργία ώρα να πάρεις([ΓΡΑΜΜΗ] ); // Διαβάστε την ώρα.

λειτουργία ώρα αναλαμπής (ΠΑΡΑΜΕΤΡΟΣ [ΣΥΧΝΟΤΗΤΑ] ); // Προκαλεί τη συνάρτηση gettime να "αναβοσβήνει" την καθορισμένη παράμετρο χρόνου.

λειτουργία περίοδος(ΛΕΠΤΑ ); // Υποδεικνύει την ελάχιστη περίοδο πρόσβασης στη μονάδα σε λεπτά.

Μεταβλητός δευτερόλεπτα// Επιστρέφει δευτερόλεπτα από 0 έως 59.

Μεταβλητός λεπτά// Επιστρέφει λεπτά από 0 έως 59.

Μεταβλητός ώρες// Επιστρέφει ώρες από 1 έως 12.

Μεταβλητός Ωρες// Επιστρέφει ώρες από 0 έως 23.

Μεταβλητός μεσημέρι// Επιστροφές το μεσημέρι 0 ή 1 (0-π.μ., 1-μ.μ.).

Μεταβλητός ημέρα// Επιστρέφει την ημέρα του μήνα από 1 έως 31.

Μεταβλητός καθημερινή// Επιστρέφει την ημέρα της εβδομάδας από 0 έως 6 (0 είναι Κυριακή, 6 είναι Σάββατο).

Μεταβλητός μήνας// Επιστρέφει τον μήνα από 1 έως 12.

Μεταβλητός έτος// Επιστρέφει το έτος από 0 έως 99.

Γράφουμε ένα απλό πρόγραμμα. Ρύθμιση της τρέχουσας ώρας στη μονάδα RTC (DS1302):

Arduino

#περιλαμβάνω χρόνος iarduino_RTC(RTC_DS1302,6,7,8); void setup() ( delay(300); Serial.begin(9600); time.begin(); time.settime(0,51,21,27,10,15,2); // 0 sec, 51 min, 21 ώρες, 27 Οκτωβρίου 2015, Τρίτη ) void loop())( if(millis()%1000==0)( // αν έχει περάσει 1 δευτερόλεπτο Serial.println(time.gettime("d-m-Y, H:i: s, D")); // εμφάνιση της χρονικής καθυστέρησης (1); // παύση για 1 ms, ώστε να μην εμφανίζεται η ώρα πολλές φορές σε 1 ms ) )

#περιλαμβάνω

iarduino_RTCtime(RTC_DS1302, 6, 7, 8);

void setup() (

καθυστέρηση (300);

Κατα συρροη. start(9600);

χρόνος. αρχίζουν();

χρόνος. χρόνος ρύθμισης(0, 51, 21, 27, 10, 15, 2); // 0 δευτ., 51 λεπτά, 21 ώρες, 27 Οκτωβρίου 2015, Τρίτη

void loop() (

αν (millis() % 1000 == 0 ) ( // αν έχει περάσει 1 δευτερόλεπτο

Κατα συρροη. println (time . gettime ( "d-m-Y, H:i:s, D" ) ; // ώρα εμφάνισης

καθυστέρηση(1); // παύση για 1 ms, ώστε να μην εμφανίζεται η ώρα πολλές φορές σε 1 ms

Διαβάζουμε την τρέχουσα ώρα από τη μονάδα RTC (DS1302) και την εξάγουμε στη "Serial port":

#περιλαμβάνω χρόνος iarduino_RTC(RTC_DS1302,6,7,8); void setup() ( delay(300); Serial.begin(9600); time.begin(); ) void loop())( if(millis()%1000==0)( // αν έχει περάσει 1 δευτερόλεπτο Σειριακή .println (time.gettime("d-m-Y, H:i:s, D")); // εμφάνιση της χρονικής καθυστέρησης(1); // παύση για 1 ms, ώστε να μην εμφανίζεται η ώρα πολλές φορές σε 1 ms ) )

Σε αυτό το άρθρο θα δούμε πώς να φτιάξουμε ένα ακριβές ρολόι με βάση ένα τσιπ ρολογιού πραγματικού χρόνου Arduino ή AVR μικροελεγκτή DS1307. Η ώρα θα εμφανιστεί στην οθόνη LCD.

Αυτό που είναι απαραίτητο

  • υπολογιστής με εγκατεστημένο το Arduino IDE.
  • Τσιπ DS1307 ή μονάδα RTC που βασίζεται σε αυτό.
  • στοιχεία από τη λίστα στοιχείων.

Μπορείτε να αντικαταστήσετε την πλακέτα Arduino με έναν ελεγκτή Atmel, αλλά βεβαιωθείτε ότι έχει αρκετές ακίδες εισόδου και εξόδου και έχει εφαρμογή υλικού της διεπαφής I2C. Χρησιμοποιώ το ATMega168A-PU. Εάν θα χρησιμοποιήσετε ξεχωριστό μικροελεγκτή, τότε θα χρειαστείτε έναν προγραμματιστή, για παράδειγμα, AVR MKII ISP.

Υποτίθεται ότι ο αναγνώστης είναι εξοικειωμένος με το breadboarding, τον προγραμματισμό στο Arduino IDE και έχει κάποια γνώση της γλώσσας προγραμματισμού C. Και τα δύο παρακάτω προγράμματα δεν χρειάζονται περαιτέρω επεξήγηση.

Εισαγωγή

Πώς οι μικροελεγκτές παρακολουθούν την ώρα και την ημερομηνία; Ένας συμβατικός μικροελεγκτής έχει μια λειτουργία χρονοδιακόπτη που ξεκινά από το μηδέν όταν εφαρμόζεται η τάση τροφοδοσίας και στη συνέχεια αρχίζει να μετράει. Στον κόσμο του Arduino, μπορούμε να χρησιμοποιήσουμε τη συνάρτηση millis() για να μάθουμε πόσα χιλιοστά του δευτερολέπτου έχουν περάσει από την εφαρμογή του τροφοδοτικού. Όταν αφαιρέσετε και εφαρμόσετε ξανά την τροφοδοσία, θα αρχίσει να μετράει από την αρχή. Αυτό δεν είναι πολύ βολικό όταν πρόκειται για εργασία με ρολόγια και ημερομηνίες.

Εδώ είναι βολικό να χρησιμοποιήσετε ένα τσιπ RTC (Ρολόι πραγματικού χρόνου). Αυτό το μικροκύκλωμα με μπαταρία 3V ή κάποια άλλη πηγή ρεύματος παρακολουθεί την ώρα και την ημερομηνία. Το ρολόι/ημερολόγιο παρέχει πληροφορίες για δευτερόλεπτα, λεπτά, ώρες, ημέρα της εβδομάδας, ημερομηνία, μήνα και έτος. Το τσιπ λειτουργεί σωστά με μήνες διάρκειας 30/31 ημερών και με δίσεκτα έτη. Η επικοινωνία γίνεται μέσω του διαύλου I2C (ο δίαυλος I2C δεν συζητείται σε αυτό το άρθρο).

Εάν η τάση Vcc της κύριας ράγας τροφοδοσίας πέσει κάτω από την τάση της μπαταρίας Vbat, το RTC μεταβαίνει αυτόματα σε λειτουργία χαμηλής ισχύος από την εφεδρική μπαταρία. Η εφεδρική μπαταρία είναι συνήθως μια μικροσκοπική μπαταρία σε σχήμα νομίσματος 3 volt που συνδέεται μεταξύ της ακίδας 3 και της θήκης. Με αυτόν τον τρόπο, το τσιπ θα εξακολουθεί να παρακολουθεί την ώρα και την ημερομηνία, και όταν εφαρμόζεται ρεύμα στο κύριο κύκλωμα, ο μικροελεγκτής θα λάβει την τρέχουσα ώρα και ημερομηνία.

Σε αυτό το έργο θα χρησιμοποιήσουμε το DS1307. Για αυτό το τσιπ, η ακίδα 7 είναι η ακίδα SQW/OUT (έξοδος τετραγωνικού κύματος). Μπορείτε να χρησιμοποιήσετε αυτήν την ακίδα για να αναβοσβήνει ένα LED και να ειδοποιεί τον μικροελεγκτή για να καταγράψει την ώρα. Θα κάνουμε και τα δύο. Ακολουθεί μια επεξήγηση της λειτουργίας του ακροδέκτη SQW/OUT.

Ο καταχωρητής ελέγχου DS1307 χρησιμοποιείται για τον έλεγχο της λειτουργίας του ακροδέκτη SQW/OUT.

Bit 7: Έλεγχος εξόδου (OUT) Αυτό το bit ελέγχει το επίπεδο εξόδου του ακροδέκτη SQW/OUT όταν η έξοδος τετραγώνου κύματος είναι απενεργοποιημένη. Εάν SQWE = 0, το λογικό επίπεδο στον ακροδέκτη SQW/OUT είναι 1 εάν OUT = 1, και 0 εάν OUT = 0. Αρχικά, αυτό το bit είναι κανονικά 0. Bit 4: Square Wave Enable (SQWE) Αυτό το bit, όταν έχει οριστεί στο λογικό 1, ενεργοποιεί τη γεννήτρια εξόδου. Η συχνότητα των παλμών τετραγωνικών κυμάτων εξαρτάται από τις τιμές των bit RS0 και RS1. Όταν η συχνότητα τετραγωνικού κύματος έχει ρυθμιστεί στο 1 Hz, οι καταχωρητές ρολογιού ενημερώνονται κατά την πτώση του τετραγωνικού κύματος. Αρχικά, αυτό το bit είναι συνήθως 0. Bit 1 και 0: Επιλογή συχνότητας (RS) Αυτά τα bit ελέγχουν τη συχνότητα της εξόδου τετραγωνικού κύματος όταν είναι ενεργοποιημένη η έξοδος τετραγώνου κύματος. Ο παρακάτω πίνακας παραθέτει τις συχνότητες τετραγωνικών κυμάτων που μπορούν να επιλεγούν χρησιμοποιώντας αυτά τα bit. Αυτά τα bit συνήθως ορίζονται αρχικά σε 1.

Αυτός ο πίνακας θα σας βοηθήσει με τη συχνότητα:

Επιλογή συχνότητας τετραγωνικών κυμάτων DS1307
Συχνότητα παλμώνBit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
1 Hz0 0 0 1 0 0 0 0
4,096 kHz0 0 0 1 0 0 0 1
8,192 kHz0 0 0 1 0 0 1 0
32.768 kHz0 0 0 1 0 0 1 1

Εάν συνδέσατε ένα LED και μια αντίσταση στον ακροδέκτη 7 και θέλετε το LED να αναβοσβήνει σε συχνότητα 1 Hz, πρέπει να γράψετε την τιμή 0b00010000 στον καταχωρητή ελέγχου. Εάν θέλετε παλμούς 4,096 kHz, τότε θα γράφατε 0b000100001. Σε αυτή την περίπτωση, θα χρειαστείτε έναν παλμογράφο για να δείτε τους παλμούς, καθώς το LED θα αναβοσβήνει τόσο γρήγορα που θα φαίνεται να είναι συνεχώς αναμμένο. Θα χρησιμοποιήσουμε παλμούς με συχνότητα 1 Hz.

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

Παρακάτω είναι ένα μπλοκ διάγραμμα του τι χρειαζόμαστε.

Χρειαζόμαστε:

  • Υποδοχή ISP (στον προγραμματισμό συστήματος, προγραμματισμός εντός κυκλώματος) για το φλας του υλικολογισμικού του μικροελεγκτή.
  • κουμπιά για ρύθμιση ώρας και ημερομηνίας.
  • μικροελεγκτής για επικοινωνία με RTC μέσω διαύλου I2C.
  • οθόνη για εμφάνιση ημερομηνίας και ώρας.

Σχηματικό διάγραμμα:


Κατάλογος στοιχείων

Παρακάτω είναι ένα στιγμιότυπο από το Eagle:


Λογισμικό

Σε αυτό το σεμινάριο θα χρησιμοποιήσουμε δύο διαφορετικά σκίτσα: ένα που γράφει την ώρα και την ημερομηνία στο RTC και ένα που διαβάζει την ώρα και την ημερομηνία από το RTC. Το κάναμε αυτό γιατί σας δίνει μια καλύτερη ιδέα για το τι συμβαίνει. Θα χρησιμοποιήσουμε το ίδιο σχήμα και για τα δύο προγράμματα.

Πρώτα θα γράψουμε την ώρα και την ημερομηνία στο RTC, κάτι που μοιάζει με τη ρύθμιση της ώρας σε ένα ρολόι.

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

Ο παρακάτω κώδικας ορίζει τις τιμές και τις γράφει στο RTC:

#περιλαμβάνω // Ορισμός ακίδων LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Η διακοπή 0 είναι η ακίδα 4 του μικροελεγκτή (Arduino digital pin 2) int btnSet = 0; // Η διακοπή 1 είναι η ακίδα 5 του μικροελεγκτή (ψηφιακή ακίδα Arduino 3) int btnSel = 1; // Σημαίες διακοπής volatile int togBtnSet = false; volatile int togBtnSel = false; volatile int counterVal = 0; // Μεταβλητές για να παρακολουθείτε πού στο "μενού" είμαστε πτητικές int menuCounter = 0; // Πίνακας πτητικών τιμών Int menuValues; // 0=ώρες, 1=λεπτά, 2=ημέρα του μήνα, 3=μήνας, 4=έτος, 5=ημέρα της εβδομάδας // Τίτλοι μενού char* menuTitles = ( "Ρύθμιση ώρας.", "Ρύθμιση λεπτών.", "Set date.", "Set month.", "Set year.", "Set day (1=mon)." ); // Πίνακας ημερών της εβδομάδας char* days = ( "NA", "Mon", "Tue", "Wed", "Thu", "Fre", "Sat", "Sun" ); void setup() ( // Δήλωση διακοπών, εκτέλεση συναρτήσεων αυξανόμενη τιμή/nextItem // σε ανερχόμενη άκρη στο btnXXX attachInterrupt(btnSet, αύξηση Τιμή, RISING); attachInterrupt(btnSel, nextItem, RISING); Wire.begin(); lcd.begin. ( 16,2); showWelcome(); ) // Συνάρτηση διακοπής void riseValue() ( // Μεταβλητές static unsigned long lastInterruptTime = 0; // Δημιουργία χρονικής σήμανσης ανυπόγραφο long interruptTime = millis(); // Εάν η χρονική σήμανση - lastInterruptTime είναι μεγαλύτερο, από 200 εάν (interruptTime - lastInterruptTime > 200) ( togBtnSet = true; // Αύξηση counterVal κατά 1 counterVal++; ) // Ορισμός lastInterruptTime ίσο με τη χρονική σήμανση // ώστε να γνωρίζουμε ότι έχουμε προχωρήσει περισσότερο lastInterruptTime = /interruptTime; / Συνάρτηση διακοπής για το επόμενο στοιχείο μενού void nextItem() ( στατικό ανυπόγραφο long lastInterruptTime = 0; ανυπόγραφο μεγάλο interruptTime = millis(); if (interruptTime - lastInterruptTime > 200) ( togBtnSel = true; // Αύξηση του μετρητή μενού, οπότε πηγαίνουμε στο επόμενο στοιχείο μενού menuCounter++ ; εάν (menuCounter > 6) menuCounter = 0; // Τοποθετήστε το counterVal στο μενού μετρητών του στοιχείου του πίνακα menuValues ​​= counterVal; // Επαναφορά counterVal, τώρα ξεκινάμε από το 0 για το επόμενο στοιχείο μενού counterVal = 0; ) lastInterruptTime = InterruptTime; ) // Λειτουργία για τη μετατροπή δεκαδικών αριθμών σε BCD byte decToBCD(byte val) ( return ((val/10*16) + (val%10)); ) // Λειτουργία για έλεγχο εάν έχουν πατηθεί τα κουμπιά κύλισης μενού, / / και ενημερώστε τον τίτλο στην οθόνη. void checkCurrentMenuItem() ( if (togBtnSel) ( togBtnSel = false; lcd.setCursor(0,0); lcd.print(menuTitles); ) ) // Λειτουργία για έλεγχο αν έχει πατηθεί το κουμπί αύξησης, // και ενημέρωση της μεταβλητής στο αντίστοιχο στοιχείο πίνακα, // συν την εμφάνιση της νέας τιμής. void checkAndUpdateValue() ( // Ελέγξτε εάν ενεργοποιείται η διακοπή = πατηθεί το κουμπί εάν (togBtnSet) ( // Ενημέρωση της τιμής του στοιχείου πίνακα με counterVal menuValues ​​= counterVal; // Επαναφορά της σημαίας διακοπής togBtnSet = false; lcd.setCursor(7,1); // Εκτυπώστε τη νέα τιμή lcd.print(menuValues); lcd.print(" "); ) ) // Ένα σύντομο μήνυμα καλωσορίσματος, τώρα ξέρουμε ότι όλα είναι εντάξει void showWelcome() ( LCD (); ) // Εγγραφή δεδομένων στο RTC void writeRTC() ( Wire.beginTransmission(0x68); Wire.write(0); // διεύθυνση έναρξης Wire.write(0x00); // δευτερόλεπτα Wire.write(decToBCD(menuValues )); // μετατρέψτε τα λεπτά σε κώδικα BCD και γράψτε Wire.write(decToBCD(menuValues)); // μετατρέψτε τις ώρες σε κώδικα BCD και γράψτε Wire.write(decToBCD(menuValues)); // μετατρέψτε την ημέρα της εβδομάδα σε κωδικό BCD και γράψτε Wire.write(decToBCD( menuValues)); // μετατρέψτε την ημέρα του μήνα σε κωδικό BCD και γράψτε Wire.write(decToBCD(menuValues)); // μετατρέψτε το μήνα σε κώδικα BCD και γράψτε Wire.write(decToBCD(menuValues)); // μετατρέψτε το έτος σε κωδικό BCD και γράψτε Wire.write(0b00010000); // ενεργοποίηση τετραγωνικών κυμάτων 1 Hz στον ακροδέκτη 7 Wire.endTransmission(); // κλείσιμο μεταφοράς ) // Εμφάνιση ώρας // Για να δείτε ότι το RTC λειτουργεί, πρέπει να δείτε ένα άλλο πρόγραμμα void showTime() ( lcd.setCursor(0,0); lcd.print(" "); lcd.print (menuValues); lcd.print(":"); // ώρες lcd.print(menuValues); lcd.print(":"); lcd.print("00"); // λεπτά lcd.setCursor(3, 1) ; lcd.print(ημέρες); lcd.print(" "); // ημέρα της εβδομάδας lcd.print(menuValues); lcd.print("."); // ημερομηνία lcd.print(menuValues); lcd.print( "."); // μήνας lcd.print(menuValues); lcd.print(" "); // έτος // καλέστε τη συνάρτηση writeRTC writeRTC(); ) void loop() ( if (menuCounter< 6) { checkCurrentMenuItem(); checkAndUpdateValue(); } else { showTime(); } }

Αυτό το πρόγραμμα ξεκινά με ένα σύντομο μήνυμα καλωσορίσματος. Αυτό το μήνυμα μας λέει ότι η τροφοδοσία είναι ενεργοποιημένη, η οθόνη LCD λειτουργεί και ότι το πρόγραμμα έχει ξεκινήσει. Δεδομένου ότι το σκίτσο χρησιμεύει μόνο για να δείξει πώς να γράψετε δεδομένα από το Arduino στο RTC DS1307, στερείται βοηθητικής λειτουργικότητας (έλεγχος εάν οι τιμές εμπίπτουν σε αποδεκτά εύρη, επαναφορά κατά το πάτημα του κουμπιού για αύξηση της τιμής, δηλαδή επαναφορά στο 0, όταν η τιμή, για παράδειγμα, λεπτά υπερβαίνει τα 60, κ.λπ.)

// Συμπεριλαμβανομένων των αρχείων κεφαλίδας #include #περιλαμβάνω // Ορισμός ακίδων LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Pin που θα λαμβάνει παλμούς από το RTC volatile int clockPin = 0; // Μεταβλητές ώρας και ημερομηνίας byte second. byte λεπτό byte ώρα? byte ημέρα? byte ημερομηνία? byte μήνα? byte έτος? // Πίνακας ημερών της εβδομάδας char* days = ( "NA", "Mon", "Tue", "Wed", "Thu", "Fre", "Sat", "Sun" ); // Μια συνάρτηση που εκτελείται μόνο κατά την εκκίνηση void setup() ( pinMode(clockPin, INPUT); pinMode(clockPin, LOW); Wire.begin(); lcd.begin(16,2); showWelcome(); ) / / Ένα σύντομο μήνυμα καλωσορίσματος, τώρα ξέρουμε ότι όλα είναι καλά, void showWelcome() ( lcd.setCursor(2,0); lcd.print("Hello world."); lcd.setCursor(3,1); lcd.print( "I"m alive."); delay(500); lcd.clear(); ) byte bcdToDec(byte val) ( return ((val/16*10) + (val%16)); ) // Αυτό εκτελείται συνεχώς void loop() ( // Εάν το clockPin είναι υψηλό εάν (digitalRead(clockPin)) ( // Εκκίνηση μετάδοσης I2C στη διεύθυνση 0x68 Wire.beginTransmission(0x68); // Έναρξη στη διεύθυνση 0 Wire.write(0); // Κλείσιμο μεταφοράς Wire.endTransmission(); // Έναρξη ανάγνωσης 7 δυαδικών δεδομένων από το 0x68 Wire.requestFrom(0x68, 7); second = bcdToDec(Wire.read()); λεπτό = bcdToDec(Wire.read()); ώρα = bcdToDec(Wire.read()); day = bcdToDec(Wire.read()); ημερομηνία = bcdToDec(Wire.read()); μήνας = bcdToDec(Wire.read()); έτος = bcdToDec(Wire.read ( )); // Μορφοποίηση και εμφάνιση χρόνου lcd.setCursor(4,0); αν (ώρα< 10) lcd.print("0"); lcd.print(hour); lcd.print(":"); if (minute < 10) lcd.print("0"); lcd.print(minute); lcd.print(":"); if (second < 10) lcd.print("0"); lcd.print(second); lcd.setCursor(2,1); // Форматирование и отображение даты lcd.print(days); lcd.print(" "); if (date < 10) lcd.print("0"); lcd.print(date); lcd.print("."); if (month < 10) lcd.print("0"); lcd.print(month); lcd.print("."); lcd.print(year); } }

συμπέρασμα

Σε αυτό το άρθρο, εξετάσαμε το τσιπ DS1307 από την Maxim Integrated και γράψαμε δύο προγράμματα επίδειξης: ένα για τη ρύθμιση της ώρας και της ημερομηνίας και ένα για την ανάγνωση της ώρας και της ημερομηνίας. Για να ελέγξουμε αν πατήθηκαν κουμπιά, χρησιμοποιήσαμε διακοπές, οι οποίες εξάλειψαν επίσης την επίδραση της αναπήδησης της επαφής.

Φωτογραφία και βίντεο

Ρύθμιση της ώρας

Διάβασμα χρόνου

Σε πολλά έργα Arduino, απαιτείται η παρακολούθηση και η καταγραφή του χρόνου εμφάνισης ορισμένων γεγονότων. Η μονάδα ρολογιού πραγματικού χρόνου, εξοπλισμένη με πρόσθετη μπαταρία, σας επιτρέπει να αποθηκεύετε την τρέχουσα ημερομηνία χωρίς να εξαρτάται από τη διαθεσιμότητα ρεύματος της ίδιας της συσκευής. Σε αυτό το άρθρο θα μιλήσουμε για τις πιο κοινές μονάδες RTC DS1307, DS1302, DS3231 που μπορούν να χρησιμοποιηθούν με την πλακέτα Arduino.

Η μονάδα ρολογιού είναι μια μικρή πλακέτα που περιέχει, κατά κανόνα, ένα από τα μικροκυκλώματα DS1307, DS1302, DS3231. Επιπλέον, στην πλακέτα μπορείτε πρακτικά να βρείτε έναν μηχανισμό εγκατάστασης μπαταρίας. Τέτοιοι πίνακες χρησιμοποιούνται συχνά για την παρακολούθηση της ώρας, της ημερομηνίας, της ημέρας της εβδομάδας και άλλων χρονομετρικών παραμέτρων. Οι μονάδες λειτουργούν με αυτόνομη τροφοδοσία - μπαταρίες, συσσωρευτές και συνεχίζουν να μετρούν ακόμα κι αν η τροφοδοσία του Arduino είναι απενεργοποιημένη. Τα πιο συνηθισμένα μοντέλα ρολογιών είναι τα DS1302, DS1307, DS3231. Βασίζονται σε μια μονάδα RTC (ρολόι πραγματικού χρόνου) συνδεδεμένη στο Arduino.

Τα ρολόγια υπολογίζονται σε μονάδες που είναι βολικές για τον μέσο άνθρωπο - λεπτά, ώρες, ημέρες της εβδομάδας και άλλες, σε αντίθεση με τους συμβατικούς μετρητές και τις γεννήτριες ρολογιών που διαβάζουν "τικ". Το Arduino έχει μια ειδική συνάρτηση millis() που μπορεί επίσης να διαβάσει διαφορετικά χρονικά διαστήματα. Αλλά το κύριο μειονέκτημα αυτής της λειτουργίας είναι ότι μηδενίζεται όταν είναι ενεργοποιημένος ο χρονοδιακόπτης. Με τη βοήθειά του μπορείτε μόνο να διαβάσετε την ώρα· είναι αδύνατο να ορίσετε την ημερομηνία ή την ημέρα της εβδομάδας. Για την επίλυση αυτού του προβλήματος χρησιμοποιούνται μονάδες ρολογιού πραγματικού χρόνου.

Το ηλεκτρονικό κύκλωμα περιλαμβάνει μικροκύκλωμα, τροφοδοτικό, αντηχείο χαλαζία και αντιστάσεις. Ο συντονιστής χαλαζία λειτουργεί σε συχνότητα 32768 Hz, η οποία είναι βολική για έναν συμβατικό δυαδικό μετρητή. Το κύκλωμα DS3231 έχει ενσωματωμένο χαλαζία και θερμική σταθεροποίηση, που επιτρέπει τιμές υψηλής ακρίβειας.

Σύγκριση δημοφιλών μονάδων RTC DS1302, DS1307, DS3231

Σε αυτόν τον πίνακα παρέχουμε μια λίστα με τα πιο δημοφιλή modules και τα κύρια χαρακτηριστικά τους.

Ονομα Συχνότητα Ακρίβεια Υποστηριζόμενα πρωτόκολλα
DS1307 1 Hz, 4,096 kHz, 8,192 kHz, 32,768 kHz Εξαρτάται από τον χαλαζία - συνήθως η τιμή φτάνει τα 2,5 δευτερόλεπτα την ημέρα, είναι αδύνατο να επιτευχθεί ακρίβεια μεγαλύτερη από 1 δευτερόλεπτο την ημέρα. Επίσης, η ακρίβεια εξαρτάται από τη θερμοκρασία. I2C
DS1302 32.768 kHz 5 δευτερόλεπτα την ημέρα I2C, SPI
DS3231 Δύο έξοδοι - η πρώτη στα 32,768 kHz, η δεύτερη προγραμματιζόμενη από 1 Hz έως 8,192 kHz ±2 ppm σε θερμοκρασίες από 0C έως 40C.

±3,5 ppm σε θερμοκρασίες από -40C έως 85C.

Ακρίβεια μέτρησης θερμοκρασίας – ±3С

I2C

Ενότητα DS1307

Το DS1307 είναι μια μονάδα που χρησιμοποιείται για χρονισμό. Συναρμολογείται με βάση το τσιπ DS1307ZN, η τροφοδοσία παρέχεται από μπαταρία λιθίου για να διασφαλιστεί η αυτόνομη λειτουργία για μεγάλο χρονικό διάστημα. Η μπαταρία στην πλακέτα είναι τοποθετημένη στην πίσω πλευρά. Η μονάδα διαθέτει τσιπ AT24C32 - αυτή είναι μια μη πτητική μνήμη EEPROM 32 KB. Και τα δύο μικροκυκλώματα συνδέονται με δίαυλο I2C. Το DS1307 έχει χαμηλή κατανάλωση ενέργειας και περιέχει ρολόι και ημερολόγιο για το έτος 2100.

Η ενότητα έχει τις ακόλουθες παραμέτρους:

  • Τροφοδοτικό – 5V;
  • Εύρος θερμοκρασίας λειτουργίας από -40C έως 85C.
  • 56 byte μνήμης.
  • Μπαταρία λιθίου LIR2032;
  • Υλοποιεί λειτουργίες 12 και 24 ωρών.
  • Υποστήριξη διεπαφής I2C.

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

Η αλληλεπίδραση με άλλες συσκευές και η ανταλλαγή πληροφοριών μαζί τους πραγματοποιείται χρησιμοποιώντας τη διεπαφή I2C από τις ακίδες SCL και SDA. Το κύκλωμα περιέχει αντιστάσεις που σας επιτρέπουν να παρέχετε το απαιτούμενο επίπεδο σήματος. Η πλακέτα διαθέτει επίσης ειδική θέση για την τοποθέτηση του αισθητήρα θερμοκρασίας DS18B20. Οι επαφές κατανέμονται σε 2 ομάδες, βήμα 2,54 mm. Η πρώτη ομάδα επαφών περιέχει τις ακόλουθες ακίδες:

  • DS – έξοδος για αισθητήρα DS18B20;
  • SCL – γραμμή ρολογιού.
  • SDA – γραμμή δεδομένων.
  • VCC – 5V;

Η δεύτερη ομάδα επαφών περιλαμβάνει:

  • SQ – 1 MHz;
  • BAT – είσοδος για μπαταρία λιθίου.

Για να συνδεθείτε στην πλακέτα Arduino, χρειάζεστε την ίδια την πλακέτα (στην περίπτωση αυτή εξετάζουμε το Arduino Uno), μια μονάδα ρολογιού πραγματικού χρόνου RTC DS1307, καλώδια και ένα καλώδιο USB.

Για τη σύνδεση του ελεγκτή στο Arduino, χρησιμοποιούνται 4 ακίδες - VCC, γείωση, SCL, SDA.. Το VCC από το ρολόι συνδέεται στα 5V στο Arduino, η γείωση από το ρολόι συνδέεται με τη γείωση από το Arduino, SDA - A4, SCL - Α5.

Για να ξεκινήσετε να εργάζεστε με τη μονάδα ρολογιού, πρέπει να εγκαταστήσετε τις βιβλιοθήκες DS1307RTC, TimeLib και Wire. Μπορείτε επίσης να χρησιμοποιήσετε το RTCLib για εργασία.

Έλεγχος της μονάδας RTC

Όταν εκτελείτε τον πρώτο κωδικό, το πρόγραμμα θα διαβάζει δεδομένα από τη μονάδα μία φορά ανά δευτερόλεπτο. Αρχικά, μπορείτε να δείτε πώς συμπεριφέρεται το πρόγραμμα εάν αφαιρέσετε την μπαταρία από τη μονάδα και την αντικαταστήσετε με άλλη ενώ η πλακέτα Arduino δεν είναι συνδεδεμένη στον υπολογιστή. Πρέπει να περιμένετε μερικά δευτερόλεπτα και να αφαιρέσετε την μπαταρία, τελικά το ρολόι θα επανεκκινήσει. Στη συνέχεια, πρέπει να επιλέξετε ένα παράδειγμα από το μενού Παραδείγματα→RTClib→ds1307. Είναι σημαντικό να ρυθμίσετε σωστά την ταχύτητα μετάδοσης στα 57600 bps.

Όταν ανοίγετε το παράθυρο Serial Monitor, θα πρέπει να εμφανιστούν οι ακόλουθες γραμμές:

Η ώρα θα δείξει 0:0:0. Αυτό συμβαίνει επειδή το ρολόι χάνει την ισχύ και θα σταματήσει να μετράει το χρόνο. Για το λόγο αυτό, η μπαταρία δεν πρέπει να αφαιρείται ενώ λειτουργεί η μονάδα.

Για να ρυθμίσετε την ώρα στη μονάδα, πρέπει να βρείτε τη γραμμή στο σκίτσο

RTC.adjust(DateTime(__DATE__, __TIME__));

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

Η ρύθμιση έχει γίνει σωστά και δεν χρειάζεται να ρυθμίσετε επιπλέον το ρολόι πραγματικού χρόνου.

Διάβασμα χρόνου. Μόλις διαμορφωθεί η μονάδα, μπορούν να σταλούν αιτήματα χρόνου. Αυτό γίνεται χρησιμοποιώντας τη συνάρτηση now(), η οποία επιστρέφει ένα αντικείμενο DateTime που περιέχει πληροφορίες ώρας και ημερομηνίας. Υπάρχει ένας αριθμός βιβλιοθηκών που χρησιμοποιούνται για την ανάγνωση του χρόνου. Για παράδειγμα, RTC.year() και RTC.hour() - λαμβάνουν ξεχωριστά πληροφορίες σχετικά με το έτος και την ώρα. Όταν εργάζεστε μαζί τους, μπορεί να προκύψει ένα πρόβλημα: για παράδειγμα, ένα αίτημα για εμφάνιση της ώρας θα υποβληθεί στις 1:19:59. Πριν από την εμφάνιση της ώρας 1:20:00, το ρολόι θα εμφανίσει την ώρα 1:19:00, που σημαίνει ότι στην ουσία θα χαθεί ένα λεπτό. Επομένως, συνιστάται η χρήση αυτών των βιβλιοθηκών σε περιπτώσεις όπου η ανάγνωση γίνεται σπάνια - μία φορά κάθε λίγες μέρες. Υπάρχουν και άλλες λειτουργίες για το χρόνο κλήσης, αλλά εάν χρειάζεται να μειώσετε ή να αποφύγετε σφάλματα, είναι καλύτερο να χρησιμοποιήσετε το now() και να εξαγάγετε τις απαραίτητες μετρήσεις από αυτό.

Παράδειγμα έργου με μονάδα ρολογιού και οθόνη i2C

Το έργο είναι ένα κανονικό ρολόι· η ακριβής ώρα θα εμφανίζεται στην ένδειξη και η άνω και κάτω τελεία μεταξύ των αριθμών θα αναβοσβήνει ανά διαστήματα μία φορά κάθε δευτερόλεπτο. Για να υλοποιήσετε το έργο, θα χρειαστείτε μια πλακέτα Arduino Uno, μια ψηφιακή ένδειξη, ένα ρολόι πραγματικού χρόνου (στην περίπτωση αυτή, η ενότητα ds1307 που περιγράφεται παραπάνω), μια ασπίδα σύνδεσης (στην περίπτωση αυτή χρησιμοποιείται το Troyka Shield), μια μπαταρία για το ρολόι και τα καλώδια.

Το έργο χρησιμοποιεί έναν απλό τετραψήφιο δείκτη στο τσιπ TM1637. Η συσκευή διαθέτει διεπαφή δύο καλωδίων και παρέχει 8 επίπεδα φωτεινότητας οθόνης. Χρησιμοποιείται μόνο για την εμφάνιση του χρόνου σε μορφή ώρες: λεπτά. Η ένδειξη είναι εύκολη στη χρήση και εύκολη στη σύνδεση. Είναι επωφελές να χρησιμοποιείται για έργα όπου δεν απαιτείται επαλήθευση δεδομένων σε λεπτά ή ωριαία. Για να αποκτήσετε πληρέστερες πληροφορίες σχετικά με την ώρα και την ημερομηνία, χρησιμοποιούνται οθόνες LCD.

Η μονάδα ρολογιού συνδέεται με τους ακροδέκτες SCL/SDA, οι οποίοι ανήκουν στον δίαυλο I2C. Πρέπει επίσης να συνδέσετε τη γείωση και την τροφοδοσία. Συνδέεται στο Arduino με τον ίδιο τρόπο που περιγράφηκε παραπάνω: SDA – A4, SCL – A5, γείωση από τη μονάδα σε γείωση από το Arduino, VCC -5V.

Η ένδειξη συνδέεται απλά - οι ακίδες CLK και DIO συνδέονται σε οποιεσδήποτε ψηφιακές ακίδες στην πλακέτα.

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

#περιλαμβάνω #include "TM1637.h" #include "DS1307.h" //πρέπει να συμπεριλάβετε όλες τις απαραίτητες βιβλιοθήκες για την εργασία με το ρολόι και την οθόνη. char compileTime = __TIME__; //χρόνος μεταγλώττισης. #define DISPLAY_CLK_PIN 10 #define DISPLAY_DIO_PIN 11 //αριθμοί από τις εξόδους Arduino στις οποίες είναι συνδεδεμένη η οθόνη. void setup() ( display.set(); display.init(); //σύνδεση και διαμόρφωση της οθόνης. clock.begin(); //ενεργοποίηση του ρολογιού. byte hour = getInt(compileTime, 0); byte λεπτό = getInt( compileTime, 2); byte second = getInt(compileTime, 4); //λήψη χρόνου. clock.fillByHMS(ώρα, λεπτό, δευτερόλεπτο); //προετοιμασία για εγγραφή στη μονάδα χρόνου. clock.setTime(); //η εγγραφή σε εξέλιξη έλαβε πληροφορίες στην εσωτερική μνήμη, έναρξη της ώρας ανάγνωσης. ) void loop() ( int8_t timeDisp; //εμφάνιση σε καθένα από τα τέσσερα bit. clock.getTime();//αίτημα λήψης χρόνου. timeDisp = clock .hour / 10; timeDisp = clock.hour % 10; timeDisp = clock.minute / 10; timeDisp = clock.minute % 10; //διάφορες λειτουργίες για τη λήψη δεκάδων, μονάδων ωρών, λεπτών και ούτω καθεξής. display.display( timeDisp); //εμφάνιση χρόνου στην ένδειξη ένδειξης.σημείο(clock.second % 2 ? POINT_ON: POINT_OFF);//ενεργοποίηση και απενεργοποίηση της άνω και κάτω τελείας μετά από ένα δευτερόλεπτο. ) char getInt(const char* string, int startIndex) ( επιστροφή int(string - "0") * 10 + int(string) - "0"; //ενέργειες για τη σωστή εγγραφή του χρόνου σε έναν διψήφιο ακέραιο. Διαφορετικά, θα εμφανιστούν μόνο μερικά σύμβολα στην οθόνη. )

Μετά από αυτό, το σκίτσο πρέπει να φορτωθεί και η ώρα θα εμφανιστεί στην οθόνη.

Το πρόγραμμα θα μπορούσε να εκσυγχρονιστεί ελαφρώς. Όταν η τροφοδοσία είναι απενεργοποιημένη, το σκίτσο που γράφτηκε παραπάνω θα κάνει την οθόνη να εμφανίσει την ώρα που ρυθμίστηκε κατά τη μεταγλώττιση μετά την ενεργοποίησή της. Στη λειτουργία εγκατάστασης, κάθε φορά θα υπολογίζεται ο χρόνος που έχει περάσει από τις 00:00:00 έως την έναρξη της μεταγλώττισης. Αυτός ο κατακερματισμός θα συγκριθεί με αυτό που είναι αποθηκευμένο στο EEPROM, το οποίο διατηρείται όταν αφαιρείται η τροφοδοσία.

Για να γράψετε και να διαβάσετε χρόνο από ή προς τη μη πτητική μνήμη, πρέπει να προσθέσετε τις συναρτήσεις EEPROMWriteInt και EEPROMReadInt. Απαιτούνται για να ελεγχθεί εάν ο κατακερματισμός ταιριάζει/αναντιστοιχεί με τον κατακερματισμό που έχει καταγραφεί στο EEPROM.

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

Ως αποτέλεσμα, ο κώδικας θα πρέπει να καθορίσει μια νέα βιβλιοθήκη (για οθόνες υγρών κρυστάλλων αυτή είναι η LiquidCrystal) και να προσθέσει γραμμές στη συνάρτηση loop() για να λάβει την ημερομηνία.

Ο αλγόριθμος λειτουργίας είναι ο εξής:

  • Σύνδεση όλων των εξαρτημάτων.
  • Έλεγχος - η ώρα και η ημερομηνία στην οθόνη της οθόνης πρέπει να αλλάζουν κάθε δευτερόλεπτο. Εάν η ώρα στην οθόνη είναι λανθασμένη, πρέπει να προσθέσετε τη συνάρτηση RTC.write (tmElements_t tm) στο σκίτσο. Τα προβλήματα με λανθασμένους χρόνους οφείλονται στο γεγονός ότι η μονάδα ρολογιού επαναφέρει την ημερομηνία και την ώρα στις 00:00:00 01/01/2000 όταν είναι απενεργοποιημένη.
  • Η λειτουργία εγγραφής σάς επιτρέπει να λαμβάνετε την ημερομηνία και την ώρα από τον υπολογιστή, μετά την οποία θα εμφανίζονται οι σωστές παράμετροι στην οθόνη.

συμπέρασμα

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

Το ρολόι πραγματικού χρόνου είναι μια μονάδα που αποθηκεύει την τρέχουσα ημερομηνία και δεν την επαναφέρει όταν απενεργοποιείται η τροφοδοσία χάρη στην ενσωματωμένη μπαταρία. Ίσως έχετε ακούσει για ρολόγια που βασίζονται στο τσιπ DS1307. Αυτό το τσιπ έχει εξαιρετικά χαμηλή ακρίβεια ρολογιού. Μια καθυστέρηση μιας ώρας την ημέρα είναι υπερβολική. Συνιστώ τη χρήση μιας μονάδας που βασίζεται σε ένα τσιπ υψηλής ακρίβειας DS3231, το οποίο είναι εξοπλισμένο με ένα θερμόμετρο για τη ρύθμιση του ρολογιού ανάλογα με τη θερμοκρασία. Η ακρίβεια ρολογιού αυτού του τσιπ είναι στο επίπεδο ενός καλού ρολογιού χειρός και είναι 2 ppm σε θερμοκρασία περιβάλλοντος 0°-40°. Ταυτόχρονα, η μονάδα είναι συμβατή με όλες τις βιβλιοθήκες που είναι γραμμένες για τη μονάδα που βασίζονται στο τσιπ DS1307. Το άρθρο μιλά για τη σύνδεση της μονάδας με το Arduino και την αλληλεπίδραση μαζί τους χρησιμοποιώντας τη βιβλιοθήκη Time. Μπορείτε να αγοράσετε μια τέτοια μονάδα από έναν πωλητή που έχω επαληθεύσει.

Σύνδεση ρολογιού σε πραγματικό χρόνο

Το ρολόι συνδέεται χρησιμοποιώντας το πρωτόκολλο I2C με δύο μόνο καλώδια. Είναι απαραίτητο να σφίξετε επιπλέον τους ακροδέκτες στους οποίους είναι συνδεδεμένο το ρολόι στη ράγα ισχύος χρησιμοποιώντας αντιστάσεις 2 KΩ. Οι έξοδοι του ρολογιού μοιάζουν με αυτό:

Οι ακίδες 32K και SQW μπορούν να αγνοηθούν. Ο σκοπός τους δεν συζητείται σε αυτό το άρθρο. Το SCL και το SDA είναι οι ακίδες διασύνδεσης I2C. Πρέπει να συνδεθούν με τον ελεγκτή. Το VCC και το GND είναι +5V και γείωση αντίστοιχα.

Το SCL και το SDA βρίσκονται σε διαφορετικές ακίδες σε διαφορετικές πλακέτες:

Ούνο, Νάνο A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Λεονάρντο 2 (SDA), 3 (SCL)

Ο ακροδέκτης SDA του ρολογιού συνδέεται με τον ακροδέκτη SDA του ελεγκτή. Ρολόι SDL, αντίστοιχα, στον ελεγκτή SDL. Αφού συνδέσετε τα καλώδια, θα πρέπει να έχετε την ακόλουθη εικόνα:

Ο πιο βολικός τρόπος για να εργαστείτε με τη μονάδα ρολογιού σε πραγματικό χρόνο είναι η χρήση της βιβλιοθήκης. Το πιο βολικό από αυτή την άποψη ονομάζεται: Χρόνος ( Αγγλικά χρόνος).
Η βιβλιοθήκη είναι ένα "περιτύλιγμα" για μια άλλη δημοφιλή βιβλιοθήκη για εργασία με τη μονάδα ρολογιού: DS1307RTC. Παρά το γεγονός ότι η βιβλιοθήκη αναπτύχθηκε για το τσιπ DS1307, λειτουργεί άψογα με το DS3231, αφού τα πρωτόκολλα επικοινωνίας είναι συμβατά.

Κατεβάστε και τις δύο βιβλιοθήκες.

Μετά τη λήψη, τοποθετήστε τα περιεχόμενα των αρχείων στο φάκελο βιβλιοθήκες, ο οποίος βρίσκεται στο φάκελο με το περιβάλλον ανάπτυξης Arduino. Εκκινήστε το Arduino IDE και ανοίξτε την τυπική βιβλιοθήκη παραδειγμάτων: Examples->Time->TimeRTC
Ή απλώς αντιγράψτε αυτόν τον κωδικό:

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω void setup() ( Serial.begin(9600); ενώ (!Serial) ; // περιμένετε έως ότου το Arduino Serial Monitor ανοίξει το setSyncProvider(RTC.get); // τη συνάρτηση για λήψη του χρόνου από το RTC if(timeStatus()! = timeSet) Serial.println("Δεν είναι δυνατός ο συγχρονισμός με το RTC"); αλλιώς Serial.println("Το RTC έχει ορίσει την ώρα του συστήματος"); ) void loop() ( if (timeStatus() == timeSet) ( digitalClockDisplay( ); ) else ( Serial.println("Η ώρα δεν έχει οριστεί. Παρακαλώ εκτελέστε την ώρα"); Serial.println("Παράδειγμα TimeRTCSet ή DS1307RTC SetTime παράδειγμα."); Serial.println(); καθυστέρηση(4000) . " ); Serial.print(day()); Serial.print(" "); Serial.print(month()); Serial.print(" "); Serial.print(year()); Serial.println( ).< 10) Serial.print("0"); Serial.print(digits); }

#περιλαμβάνω

#περιλαμβάνω

#περιλαμβάνω

void setup() (

Κατα συρροη. start(9600);

ενώ (! Serial ) ; // περιμένετε μέχρι να ανοίξει το Arduino Serial Monitor

setSyncProvider(RTC.get); // η συνάρτηση για λήψη της ώρας από το RTC

if (timeStatus() != timeSet)

Κατα συρροη. println("Δεν είναι δυνατός ο συγχρονισμός με το RTC");

αλλού

Κατα συρροη. println("Το RTC έχει ορίσει την ώρα του συστήματος");

void loop()

if (timeStatus() == timeSet) (

digitalClockDisplay();

) άλλο (

Κατα συρροη. println( "Η ώρα δεν έχει οριστεί. Παρακαλώ εκτελέστε την ώρα") ;

Κατα συρροη. println( "Παράδειγμα TimeRTCSet ή παράδειγμα DS1307RTC SetTime.") ;

Κατα συρροη. println();

καθυστέρηση (4000);

καθυστέρηση (1000);

void digitalClockDisplay() (

// Ψηφιακό ρολόι απεικόνιση της ώρας

Κατα συρροη. print(hour());

printDigits(minute());

printDigits(second());

Κατα συρροη. Τυπώνω (" " ) ;

Κατα συρροη. print(day());

Κατα συρροη. Τυπώνω (" " ) ;

Κατα συρροη. print(month());

Κατα συρροη. Τυπώνω (" " ) ;

Κατα συρροη. εκτύπωση(έτος());

Κατα συρροη. println();

void printDigits(int ψηφία) (

// βοηθητική λειτουργία για προβολή ψηφιακού ρολογιού: εκτυπώσεις πριν από την άνω και κάτω τελεία και το 0

Κατα συρροη. Τυπώνω(":");

εάν (ψηφία< 10 )

Κατα συρροη. print("0");

Κατα συρροη. εκτύπωση (ψηφία);

Αφού φορτώσετε το σκίτσο στον πίνακα, εκκινήστε το port monitor (Tools->port monitor). Θα δείτε μηνύματα από τη βιβλιοθήκη. Η ώρα που εμφανίζεται θα είναι λανθασμένη ή η βιβλιοθήκη θα παραπονεθεί ότι το ρολόι δεν έχει ρυθμιστεί. Για να ρυθμίσετε το ρολόι, φορτώστε ένα παράδειγμα από τη βιβλιοθήκη "SetTime" του DS1307RTC στην πλακέτα (Παραδείγματα->DS1307RTC->SetTime). Φορτώστε αυτό το παράδειγμα στον πίνακα σας. Μετά τη λήψη, το ρολόι θα ρυθμιστεί σε χρόνος σύνταξης σκίτσου. Η καθυστέρηση μεταξύ της μεταγλώττισης και της πλήρους λήψης θα είναι πολύ μικρή, η οποία θα είναι αρκετή για ένα καλά συντονισμένο ρολόι. Αλλά αν αποσυνδέσετε και επανασυνδέσετε την τροφοδοσία της πλακέτας, ακόμα και μετά από αρκετές ώρες, η ώρα του ρολογιού θα εξακολουθεί να επαναφέρεται στην ώρα της μεταγλώττισης και θα είναι λανθασμένη. Επομένως, χρησιμοποιήστε αυτό το παράδειγμα μόνο για εγκατάσταση, μετά τη ρύθμιση, απενεργοποιήστε το ρολόι ή ανεβάστε ένα άλλο σκίτσο στον πίνακα.

Καλησπέρα, σήμερα θα μοιραστώ οδηγίες για να φτιάξετε ένα ρολόι με θερμόμετρο δωματίου( Ρολόι DIY Arduino). Το ρολόι λειτουργεί στο Arduino UNO· η οθόνη γραφικών WG12864B χρησιμοποιείται για την εμφάνιση της ώρας και της θερμοκρασίας. Ως αισθητήρας θερμοκρασίας - ds18b20. Σε αντίθεση με τα περισσότερα άλλα ρολόγια, δεν θα χρησιμοποιήσω το RTS (Ρολόι σε πραγματικό χρόνο), αλλά θα προσπαθήσω να το κάνω χωρίς αυτήν την πρόσθετη ενότητα.

Τα κυκλώματα Arduino διακρίνονται για την απλότητά τους και ο καθένας μπορεί να αρχίσει να μαθαίνει Arduino. Μπορείτε να διαβάσετε σχετικά με τον τρόπο σύνδεσης βιβλιοθηκών και flash Arduino στο άρθρο μας.

Ας αρχίσουμε.

Για να δημιουργήσουμε αυτό το ρολόι θα χρειαστούμε:

Arduino UNO (ή οποιαδήποτε άλλη συμβατή πλακέτα Arduino)
- Γραφική οθόνη WG12864B
- Αισθητήρας θερμοκρασίας ds18b20
- Αντίσταση 4,7 Kom 0,25 W
- Αντίσταση 100 ohm 0,25 W
- Θήκη μπαταριών για 4 μπαταρίες ΑΑ
- ασορτί κουτί
- Τέλειο αρχείο
- Βερνίκι νυχιών (μαύρο ή χρώμα σώματος)
- Λίγο λεπτό πλαστικό ή χαρτόνι
- Ηλεκτρική ταινία
- Καλώδια σύνδεσης
- Ηλεκτρονική πλακέτα
- Κουμπιά
- Κολλητήρι
- Κόλλημα, κολοφώνιο
- Ταινία διπλής όψης

Προετοιμασία της οθόνης γραφικών.
Με την πρώτη ματιά, η σύνδεση της οθόνης δημιουργεί πολλά προβλήματα και δυσκολίες. Αλλά αν πρώτα κατανοήσετε τους τύπους τους, θα γίνει πολύ πιο εύκολο και ξεκάθαρο. Υπάρχουν πολλές ποικιλίες και τύποι οθονών στον ελεγκτή ks0107/ks0108. Όλες οι οθόνες χωρίζονται συνήθως σε 4 τύπους:
Επιλογή Α: HDM64GS12L-4, Crystalfontz CFAG12864B, Sparkfun LCD-00710CM, NKC Electronics LCD-0022, WinStar WG12864B-TML-T
Επιλογή B: HDM64GS12L-5, Lumex LCM-S12864GSF, Futurlec BLUE128X64LCD, Οθόνες AZ AGM1264F, Displaytech 64128A BC, Adafruit GLCD, DataVision DG12864 LDMW28, Topop. Y-128 64F, TM12864L-2, 12864J-1
Επιλογή Γ: Shenzhen Jinghua Displays Co Ltd. JM12864
Επιλογή Δ: Wintek-Cascades WD-G1906G, Wintek - GEN/WD-G1906G/KS0108B, Wintek/WD-G1906G/S6B0108A, TECDIS/Y19061/HD61202, Varitronix/MGLSHD202

Η λίστα δεν είναι πλήρης, υπάρχουν πολλά. Το πιο κοινό και, κατά τη γνώμη μου, βολικό είναι το WG12864B3 V2.0. Η οθόνη μπορεί να συνδεθεί στο Arduino μέσω σειριακής ή παράλληλης θύρας. Όταν χρησιμοποιείτε το Arduino UNO, είναι προτιμότερο να επιλέξετε σύνδεση μέσω σειριακής θύρας - τότε θα χρειαστούμε μόνο 3 εξόδους του μικροελεγκτή, αντί για τουλάχιστον 13 γραμμές κατά τη σύνδεση μέσω παράλληλης θύρας. Όλα συνδέονται πολύ απλά. Υπάρχει μια ακόμη απόχρωση: μπορείτε να βρείτε δύο επιλογές οθόνης σε προσφορά, με ενσωματωμένο ποτενσιόμετρο (για ρύθμιση της αντίθεσης) και χωρίς αυτό. Επέλεξα, και σας συμβουλεύω να κάνετε το ίδιο, με το ενσωματωμένο.


Αυτό μειώνει τον αριθμό των εξαρτημάτων και τον χρόνο συγκόλλησης. Αξίζει επίσης να εγκαταστήσετε μια αντίσταση περιορισμού ρεύματος 100 Ohm για τον οπίσθιο φωτισμό. Συνδέοντας απευθείας 5 βολτ, υπάρχει κίνδυνος να καεί ο οπίσθιος φωτισμός.
WG12864B – Arduino UNO
1 (GND) - GND
2 (VCC) - +5V
4 (RS) – 10
5 (R/W) – 11
6 (Ε) – 13
15 (PSB) – GND
19 (BLA) – μέσω αντίστασης - +5V
20 (BLK) – GND

Ο πιο βολικός τρόπος είναι να συναρμολογήσετε τα πάντα πίσω από την οθόνη και να βγάλετε 5 καλώδια από αυτήν που συνδέονται με το Arduino UNO. Το τελικό αποτέλεσμα θα πρέπει να μοιάζει κάπως έτσι:


Για όσους εξακολουθούν να επιλέξουν παράλληλη σύνδεση, θα παράσχω έναν πίνακα συνδέσεων.

Και το διάγραμμα για οθόνες της επιλογής Β:



Πολλοί αισθητήρες μπορούν να συνδεθούν σε μία γραμμή επικοινωνίας. Ένα είναι αρκετό για τα ρολόγια μας. Συνδέουμε το καλώδιο από την ακίδα «DQ» του ds18b20 στην «ακίδα 5» του Arduino UNO.

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


Συνδέουμε ως εξής: συνδέουμε το κοινό καλώδιο και στα τρία κουμπιά στο "GND" του Arduino. Το πρώτο κουμπί, το οποίο χρησιμοποιείται για την είσοδο στη λειτουργία ρύθμισης ώρας και την εναλλαγή κατά ώρα και ημερομηνία, συνδέεται στο "Pin 2". Το δεύτερο, το κουμπί για την αύξηση της τιμής, είναι στο "Pin 3", και το τρίτο, το κουμπί για τη μείωση της τιμής, είναι στο "Pin 4".

Βάζοντάς τα όλα μαζί.
Για την αποφυγή βραχυκυκλωμάτων, η οθόνη πρέπει να είναι μονωμένη. Το τυλίγουμε κυκλικά με ηλεκτρική ταινία, και στο πίσω μέρος στερεώνουμε μια λωρίδα μονωτικού υλικού με ταινία διπλής όψεως, κομμένη στο μέγεθος. Χοντρό χαρτόνι ή λεπτό πλαστικό θα κάνει. Χρησιμοποίησα πλαστικό από tablet για χαρτί. Το αποτέλεσμα είναι το εξής:


Μπροστά από την οθόνη, κατά μήκος της άκρης, κολλάμε ταινία αφρού διπλής όψης, κατά προτίμηση μαύρη.


Συνδέστε την οθόνη στο Arduino:


Συνδέουμε το συν από τη θήκη της μπαταρίας στο "VIN" του Arduino, το μείον στο "GND". Το τοποθετούμε πίσω από το Arduino. Πριν το τοποθετήσετε στη θήκη, μην ξεχάσετε να συνδέσετε τον αισθητήρα θερμοκρασίας και την πλακέτα με κουμπιά.


Προετοιμασία και συμπλήρωση του σκίτσου.
Ο αισθητήρας θερμοκρασίας απαιτεί τη βιβλιοθήκη OneWire.

Η έξοδος στην οθόνη πραγματοποιείται μέσω της βιβλιοθήκης U8glib:

Για να επεξεργαστείτε και να συμπληρώσετε ένα σκίτσο, πρέπει να εγκαταστήσετε αυτές τις δύο βιβλιοθήκες. Υπάρχουν δύο τρόποι για να γίνει αυτό. Απλώς αποσυμπιέστε αυτά τα αρχεία και τοποθετήστε τα αποσυμπιεσμένα αρχεία στο φάκελο "libraries" που βρίσκεται στο φάκελο εγκατάστασης Arduino IDE. Ή η δεύτερη επιλογή είναι να εγκαταστήσετε τις βιβλιοθήκες απευθείας στο περιβάλλον προγραμματισμού. Χωρίς να αποσυσκευάσετε τα ληφθέντα αρχεία, στο Arduino IDE, επιλέξτε το μενού Sketch - Connect Library. Στην κορυφή της αναπτυσσόμενης λίστας, επιλέξτε "Προσθήκη βιβλιοθήκης Zip". Στο παράθυρο διαλόγου που εμφανίζεται, επιλέξτε τη βιβλιοθήκη που θέλετε να προσθέσετε. Ανοίξτε ξανά το μενού Σκίτσο – Σύνδεση βιβλιοθήκης. Στο κάτω μέρος της αναπτυσσόμενης λίστας θα πρέπει να δείτε τη νέα βιβλιοθήκη. Τώρα η βιβλιοθήκη μπορεί να χρησιμοποιηθεί σε προγράμματα. Μην ξεχάσετε να κάνετε επανεκκίνηση του Arduino IDE μετά από όλα αυτά.

Ο αισθητήρας θερμοκρασίας λειτουργεί χρησιμοποιώντας το πρωτόκολλο One Wire και έχει μια μοναδική διεύθυνση για κάθε συσκευή - έναν κωδικό 64 bit. Δεν είναι πρακτικό να αναζητάτε αυτόν τον κωδικό κάθε φορά. Επομένως, πρέπει πρώτα να συνδέσετε τον αισθητήρα στο Arduino, να ανεβάσετε το σκίτσο που βρίσκεται στο μενού Αρχείο – Παραδείγματα – Θερμοκρασία Ντάλας – OneWireSearch. Στη συνέχεια, εκκινήστε το Tools - Port Monitor. Το Arduino πρέπει να βρει τον αισθητήρα μας, να γράψει τη διεύθυνσή του και τις τρέχουσες ενδείξεις θερμοκρασίας. Αντιγράφουμε ή απλώς σημειώνουμε τη διεύθυνση του αισθητήρα μας. Ανοίξτε το σκίτσο Arduino_WG12864B_Term, αναζητήστε τη γραμμή:

Byte addr=(0x28, 0xFF, 0xDD, 0x14, 0xB4, 0x16, 0x5, 0x97);//διεύθυνση του αισθητήρα μου

Γράφουμε τη διεύθυνση του αισθητήρα σας ανάμεσα στα σγουρά στηρίγματα, αντικαθιστώντας τη διεύθυνση του αισθητήρα μου.

Στοκ:

//u8g.setPrintPos(44, 64); u8g.print(sec); // Έξοδος δευτερολέπτων για έλεγχο της ορθότητας της κίνησης

Χρησιμεύει για την εμφάνιση των δευτερολέπτων δίπλα στην επιγραφή "Δεδομένα". Αυτό είναι απαραίτητο για να ρυθμίσετε με ακρίβεια το πέρασμα του χρόνου.
Εάν το ρολόι είναι γρήγορο ή πίσω, θα πρέπει να αλλάξετε την τιμή στη γραμμή:

Αν (micros() - prevmicros >494000) ( // αλλαγή σε κάτι άλλο για να διορθωθεί ήταν 500000

Προσδιόρισα εμπειρικά τον αριθμό με τον οποίο λειτουργεί το ρολόι με μεγάλη ακρίβεια. Εάν το ρολόι σας είναι γρήγορο, θα πρέπει να αυξήσετε αυτόν τον αριθμό· εάν είναι πίσω, μειώστε τον. Για να προσδιορίσετε την ακρίβεια της κίνησης, πρέπει να εμφανίσετε τα δευτερόλεπτα. Μετά από ακριβή βαθμονόμηση του αριθμού, τα δευτερόλεπτα μπορούν να σχολιαστούν και έτσι να αφαιρεθούν από την οθόνη.