Λοιποοοον....
βρέχει, κάνει κρύο, υπάρχει και λίγος επιπλέον χρόνος λόγω αργιών των ημερών (Πρωτοχρονιά 2016 έφτιαξα τα παρακάτω, 2 του μήνα που έγραψα αυτό το άρθρο, άντε και καλή χρονιά...), ευκαιρία για ένα μικρό και πρόχειρο "weekend project"!
Δεν ξέρω αν το έχετε προσέξει αλλά τα Remote Controls των τηλεοράσεων βρίσκονται να έχουν όλο και περισσότερα κουμπιά πάνω τους.
Κάποτε, ή είχαν τα άκρως απαραίτητα ή ήταν συνηθισμένο να είναι καλυμμένα τα κουμπιά που έδιναν "advanced" λειτουργικότητα τύπου προγραμματισμού καναλιών, teletext κλπ
Τώρα, ένα τυπικό Remote Control είναι έτσι:
Ίσως για τους νέους και για όποιον τα έχει συνηθίσει να είναι ΟΚ, αλλά για κάποιους μεγαλύτερους στην ηλικία (αν είστε πολύ νέοι σκεφτείτε πχ την γιαγιά σας...) όλα αυτά τα κουμπιά ίσως να είναι πρόβλημα.
πχ, για κάποιον που έχει μία γνώση από αεροπλάνα (πραγματική ή μέσω εξομοιωτών), αυτό το cockpit από ένα
super cub φαίνεται πως έχει τα άκρως απαραίτητα
αλλά για τον μέσο οδηγό αυτοκινήτου που έχει συνηθίσει να βλέπει ένα κοντέρ και άντε μία βελόνα που να δείχνει πόση βενζίνη έχει και μερικά ενδεικτικά λαμπάκια, η παραπάνω εικόνα είναι η επιτομή του χάους...
Το ίδιο συμβαίνει και με όσους που αυτό που θέλουν να κάνουν με το τηλεχειριστήριο είναι να πηγαίνουν πάνω/κάτω κανάλια, να αυξομειώνουν την ένταση της φωνής και -eventually- να κλείνουν την τηλεόραση.
Δηλαδή 5 λειτουργίες, 5 κουμπιά. Γιατί να έχουν μπροστά τους 50 κουμπιά????
Με αυτό το σκεπτικό είπα να δω αν είναι εύκολο να φτιάξω ένα απλό τηλεχειριστήριο.
Η ιδέα ήταν να βρω τους κωδικούς που αποστέλνονται όταν πατάω τα κουμπιά Κανάλι+/-, φωνή+/- και Σβήσιμο στο μεγάλο τηλεχειριστήριο της τηλεόρασης και να φτιάξω μία μικρή συσκευή που να έχει μόνο 5 κουμπιά που όταν πατιούνται να στέλνεται ο αντίστοιχος κωδικός ώστε η τηλεόραση να μπορεί να δουλέψει σαν να πατιόνταν τα αντίστοιχα πλήκτρα στο μεγάλο τηλεχειριστήριο.
Σε πρώτη φάση λοιπόν έπρεπε να διαβάσω τι στέλνει το δικό μου τηλεχειριστήριο.
Για να το κάνω αυτό χρησιμοποίησα ένα δέκτη υπερύθρων με 3 pins, όπως φαίνεται εδώ:
Για να διαβάσω το κώδικα που στέλνεται όταν πατιέται ένα κουμπί, θα έπρεπε να γραφτεί ένα πρόγραμμα που να διαβάσει τις παλμοσειρές, να τις αποκωδικοποιήσει, κλπ κλπ
Ένα -πολύ βασικό- πλεονέκτημα του οικοσυστήματος "arduino" είναι πως έχει γραφτεί πολύ λογισμικό και όταν πας να φτιάξεις κάτι, μπορείς να χτίσεις πάνω σε δουλειά που έχουν κάνει κάποιο άλλοι πριν από εσένα.
Πχ, για την διαχείριση κωδικών υπέρυθρης επικοινωνίας έχουν γραφτεί πολλές βιβλιοθήκες πχ
Εγώ αποφάσισα να χρησιμοποιήσω την δεύτερη.
Συνέδεσα την έξοδο του δέκτη υπερύθρων στο pin 10 και έτρεξα το πρόγραμμα που έρχεται σαν παράδειγμα με την βιβλιοθήκη, το IRanalyze.
Οι παλμοσειρές που λαμβάνει ο δέκτης των υπερύθρων, στον παλμογράφο φαίνονται ως εξής:
(πλήκτρο P+)
(πλήκτρο P-)
Χονδρικά, θα μπορούσαμε να το σκεφτούμε κάτι σαν bar code ζωγραφισμένο στον χρόνο με υπέρυθρο φως (γουάου!)
Φορτώνοντας στο arduino το πρόγραμμα/παράδειγμα IRanalyze, πήρα και τα παρακάτω αποτελέσματα:
1. Πατώντας το κουμπί P+ (για μετάβαση στο επόμενο πρόγραμμα)
Αυτό που μας ενδιαφέρει είναι αυτά που έχω μαρκάρει:
το πρώτο είναι η κωδικοποίηση που χρησιμοποιεί ο κατασκευαστής. Στην προκειμένη περίπτωση είναι "RC5". Το δεύτερο είναι ο κωδικός που αντιστοιχεί σε αυτή την λειτουργία (εδώ 1060) και η τρίτη παράμετρος είναι το μήκος του κωδικού σε παλμούς (bits).
2. Πατώντας το πλήκτρο P- (=μετάβαση στο προηγούμενο μενού) τα στοιχεία που λαμβάνουμε έχουν ως εξής:
Το μόνο που αλλάζει είναι ο κωδικός που για την λειτουργία P- είναι 1061
Τρέχοντας την ανάλυση και για τα άλλα κουμπιά, κατέληξα στο εξής:
- Αύξηση της έντασης, πλήκτρο V+, κωδικός 1050
- Μείωση της έντασης, πλήκτρο V-, κωδικός 1051
- Μετάβαση στο επόμενο πρόγραμμα, πλήκτρο P+, κωδικός 1060
- Μετάβαση στο προηγούμενο πρόγραμμα, πλήκτρο P-, κωδικός 1061
- Άναμμα/Σβήσιμο, πλήκτρο "Power", κωδικός 104C
(σημείωση: οι παραπάνω κωδικοί είναι σε δεκαεξαδικό, που σημαίνει ότι το 104C είναι έγκυρος αριθμός και αντιστοιχεί σε δεκαδικό 4172)
ΟΚ, σε αυτή την φάση είχα τους κωδικούς, αυτό που χρειαζόμουν ήταν να βάλω 5 διακοπτάκια που να διαβάζονται από το arduino και να στέλνω με υπέρυθρο τον αντίστοιχο κωδικό όταν πατηθεί κάποιο πλήκτρο.
Για την αποστολή του κωδικού χρησιμοποίησα ένα υπέρυθρο LED. Για να έχω την μέγιστη απόδοση, το οδήγησα με ένα NPN transistor γενικής χρήσης, το BC547 ήταν υπέρ αρκετό, μέσω αυτού του κυκλώματος:
Το ρεύμα που περνά με αυτό τον τρόπο από το LED είναι λίγο εκτός προδιαγραφών αλλά λόγω του ότι περνάνε παλμοί πολύ μικρής διάρκειας, δεν υπάρχει πρόβλημα.
Αν λόγω κάποιου λάθους (στην σύνδεση ή στο πρόγραμμα) το led μείνει αναμμένο για πάνω από δευτερόλεπτο, τότε μπορεί και να καεί, οπότε λίγο προσοχή.
Το φως που παράγει το υπέρυθρο LED είναι προφανώς αόρατο στο ανθρώπινο μάτι. Για λόγους ελέγχου, θα μπορούσε είτε προσωρινά να αντικατασταθεί με ένα απλό LED (ώστε να μπορέσουμε να δούμε ότι "ψιλοανάβει" όταν πατάμε ένα κουμπί) ή να το δούμε μέσα από μία ψηφιακή φωτογραφική μηχανή που έχει ηλεκτρονικό "ματάκι". Τότε το υπέρυθρο φως παρουσιάζεται σαν ένα απαλό μωβ, και με αυτό τον τρόπο μπορούμε να δούμε ότι το σύστημα δουλεύει.
Για μπαταρία χρησιμοποίησα δύο λιθίου 3V ("κουμπιά") σε σειρά, πιασμένες με μονωτική ταινία. Αν είχα (που δεν είχα πρόχειρο) κάποιο arduino στα 3.3V τότε θα μπορούσα με μερικές αλλαγές να χρησιμοποιήσω μία μόνο μπαταρία.
Καθώς η τάση της (διπλής) μπαταρίας είναι κάτι παραπάνω από 6V, το Arduino τροφοδοτείται από την είσοδο "RAW".
Σε αυτή την φάση, το πρόγραμμα που πρέπει να χρησιμοποιηθεί είναι σαφές (θα το δούμε παρακάτω) και το hardware θα μπορούσε και αυτό να είναι απλό, σαν και αυτό που φαίνεται στο παρακάτω διάγραμμα:
Το πρόβλημα είναι πως αν φτιαχτεί έτσι, το σύστημα θα είναι πάντα αναμμένο (power on) και θα τρώει τις μπαταρίες σαν στραγάλια... άρα κάτι άλλο έπρεπε να γίνει.
Το πιο απλό θα ήταν να μπουν διπλά push buttons έτσι ώστε το πάτημα ενός πλήκτρου κλείνει δύο διακόπτες, ο ένας να δίνει ρεύμα στο arduino και ο άλλος να δείχνει ποιό κουμπί έχει πατηθεί:
σε αυτή την περίπτωση θα έπρεπε να αντιμετωπίσουμε κάποια θέματα:
- τα διακοπτάκια που είχα ήταν "μονά", οπότε δεν μπορούσα εύκολα να φτιάξω το παραπάνω
- ακόμα και αν μπορούσα να βρω "διπλά" διακοπτάκια, το κύκλωμα θα ήταν πιο πολύπλοκο και θα κόστιζε περισσότερο.
- δεν θα ήταν "elegant"
Οπότε έπρεπε να βρεθεί μία άλλη λύση.
Εδώ να αναφέρω και ένα άλλο θέμα που με απασχόλησε και αυτό είναι ο χρόνος εκκίνησης του Arduino ή πιο απλά ο χρόνος που απαιτείται για να "μπουτάρει" το arduino.
Το arduino είναι ένας (πολύ) μικρός ηλεκτρονικός υπολογιστής και όταν παίρνει ρεύμα, τρέχει ένα πρόγραμμα που είναι περασμένο στην μόνιμη μνήμη του, το
bootloader. Αυτό μπορεί να δημιουργήσει μία καθυστέρηση μερικών δευτερολέπτων από την στιγμή που πάρει ρεύμα το σύστημα μέχρι την στιγμή που θα αρχίσει να τρέχει το πρόγραμμα που του έχουμε περάσει.
Προφανώς, μία τέτοια καθυστέρηση θα έκανε το τηλεχειριστήριο άχρηστο.
Εγώ έτυχε να χρησιμοποιήσω ένα
pro micro (το οποίο το βλέπω από το περιβάλλον προγραμματισμού σαν το μοντέλο "Arduino Leonardo").
Χρησιμοποιώ τέτοια ή και το ακόμα φτηνότερο αλλά ίδιων διαστάσεων pro mini γιατί
- είναι μικρά
- υπάρχουν στο ebay σε γελοιωδώς χαμηλές τιμές, πχ ένα pro mini μπορεί να κάνει 1 κάτι ευρώ (το pro micro είναι λίγο παραπάνω).
Το μέγεθός τους φαίνεται στην παρακάτω φωτογραφία:
Το Arduino Pro Micro λοιπόν, είχε χρόνο εκκίνησης (μετρημένο με τον παλμογράφο) 65ms που θεωρήθηκε πως δεν δημιουργεί πρόβλημα στην συγκεκριμένη χρήση, οπότε προχωράμε με το πλάνο, δηλαδή να μπουτάρει το σύστημα όταν πατιέται ένα πλήκτρο του τηλεχειριστηρίου καθώς με αυτόν τον τρόπο θα έχουμε την ελάχιστη δυνατή κατανάλωση ρεύματος.
Ομολογουμένως μου πήρε λίγη ώρα να βρω μία πιθανή λύση αλλά τελικά κατέληξα να χρησιμοποιήσω το παρακάτω:
Χρειάστηκαν 5 επιπλέον διοδάκια. Η ιδέα είναι ότι πατώντας ένα πλήκτρο το pin της εισόδου συνδέεται με κάτι σαν την γείωση, και το arduino παίρνει ρεύμα μέσω μίας διόδου που έχει σαν αποτέλεσμα να μην συνδέονται με το "σαν γείωση" τα υπόλοιπα pins....
OK, δουλεύει, είναι λίγο
kludge-ώδες αλλά εμένα μου φαίνεται όμορφο, το πρόβλημα είναι ότι τα διοδάκια κάνουν μία πτώση τάσης που λόγω του λίγου ρεύματος είναι περίπου μισό Volt (αλλιώς θα ήταν 0,7V), που σημαίνει ότι το σήμα που πάει στα pins δεν είναι η γείωση (0 volt) αλλά μία ΑΡΝΗΤΙΚΗ τάση μισού volt... αυτό είναι στα όρια των προδιαγραφών (
σελ. 383, Absolute Maximum Ratings, "Voltage on any Pin except RESET and VBUS with respect to Ground(8):-0.5V to VCC+0.5V") και η κατάσταση θα μπορούσε να βελτιωθεί αν χρησιμοποιηθούν
διοδάκια Schottky που έχουν πολύ μικρή πτώση τάσης (ονομαστική 0,2V αντί για 0,7V που έχει η 1Ν4148). Δυστυχώς εγώ είχα απλά πυριτίου
1N4148, θα ήταν σωστότερο να μπουν schottky πχ
τύπου 1Ν5817
Αλλά για την ώρα και έτσι δουλεύει.
Οπότε συνεχίζουμε.
Το τελικό σχεδιάγραμμα ήταν αυτό:
Εδώ τελειώσαμε με το hardware.
To software που τρέχει το παραπάνω είναι αυτό:
#include <IRLib.h>
IRsend My_Sender;
void setup()
{
int i;
for (i=2;i<=6;i++){
pinMode(i, INPUT); //set pins 2-6 as inputs
digitalWrite(i, HIGH); //and enable internal pull-up resistors
}
}
void loop() {
if (!digitalRead(2)){ // button P+
My_Sender.send(RC5,0x1060, 13);
delay(300);
} else if (!digitalRead(3)){ // button P-
My_Sender.send(RC5,0x1061, 13);
delay(300);
} else if (!digitalRead(4)){ // button Vol-
My_Sender.send(RC5,0x1051, 13);
delay(100);
} else if (!digitalRead(5)){ // button Vol+
My_Sender.send(RC5,0x1050, 13);
delay(100);
} else if (!digitalRead(6)){ // button ON/OFF
My_Sender.send(RC5,0x104C, 13);
delay(400);
}
}
Τα πράγματα που πρέπει να ειπωθούν για το πρόγραμμα είναι τα εξής:
- η πολυπλοκότητα εμπεριέχεται στην βιβλιοθήκη IRLib στην οποία ορίζεται το αντικείμενο IRsend. Εμείς δεν είμαστε εκτεθειμένοι σε αυτή την πολυπλοκότητα λόγω του ότι χρησιμοποιούμε το οικοσύστημα Arduino. Αν θέλαμε να το γράψουμε από την αρχή κατευθείαν σε κάποιο microcontroller, θα χρειαζόταν πολύ παραπάνω χρόνος και γνώση.
- για να έχουμε το δυνατόν απλούστερο κύκλωμα, έχουν ενεργοποιηθεί oι εσωτερικές pull-up αντιστάσεις που έχει ο microcontroller που είναι η καρδιά του arduino. Οι pull-up αντιστάσεις χρειάζονται έτσι ώστε όταν το pin είναι στο αέρα, να εμφανίζεται σαν να είναι συνδεδεμένο στο Vcc και έτσι η συνάρτηση digitalRead(x) να επιστρέφει τιμή "true"
- έχω βάλει μία καθυστέρηση που μπαίνει όταν πατιέται ένα πλήκτρο και έχει να κάνει με τον ρυθμό επανάληψής του όταν κρατιέται πατημένο. Οι τιμές δόθηκαν κατόπιν δοκιμών.
Η κατασκευή σε breadboard έχει ως εξής:
τα μέρη έχουν αριθμηθεί ως εξής:
- τα διακοπτάκια. Κάπου εκεί γύρω είναι και τα διοδάκια, φαίνεται ένα στην πάνω αριστερή γωνία του breadboard. Στο prototype τα κουμπάκια τα πατάω με ένα στυλό γιατί αλλιώς υπάρχει κίνδυνος να ξηλώσω τα καλώδια!
- το arduino
- to transistor που οδηγεί το LED υπερύθρων
- το LED υπερύθρων που είπα πριν
- ο δέκτης των υπερύθρων που είχα αναφέρει στην αρχή, τον έχω αφήσει συνδεδεμένο, στο τελικό δεν χρειάζεται ή ενδεχομένως να χρειαστεί αν θέλουμε ο προγραμματισμός να γίνεται από τον τελικό χρήστη ("on the field") αλλά τότε θα πρέπει να αλλαχτεί το πρόγραμμα και ίσως να πρέπει να μπει ένας επιπλέον διακόπτης που θα ενεργοποιεί τον προγραμματισμό.
- η μπαταρία
όλο το παραπάνω θα μπορούσε να χωρέσει σε ένα κουτί μεγέθους κουτιού σπίρτων, αλλά θα ήταν πιο πρακτικό να έμπαινε σε κάτι μεγαλύτερο ώστε 1)να μην χάνεται εύκολα και 2)να μπορεί αν το χειριστεί κάποιος πιο εύκολα, το κουτί σπίρτων παραείναι μικρό.
Σκέφτηκα ότι θα μπορούσα να το προσαρμόσω σε ένα περίβλημα παλιού χαλασμένου ποντικιού και τότε ίσως να μπορούσα να χρησιμοποιήσω και τα microswitches που θα είχε πάνω το ποντίκι, πχ το δεξί/αριστερό κουμπί του ποντικιού θα μπορούσαν να αλλάζουν κανάλι ενώ το roller θα μπορούσε να ανεβοκατεβάζει την ένταση. κλπ
Το αφήνω σε κάποιον άλλο να φτιάξει το (5) που ανέφερα παραπάνω και ίσως να το βάλει σε κάποια συσκευασία που να επιτρέπει να χρησιμοποιηθεί κανονικά (σε κάποιο κουτί από τσιγάρα, από mouse ή κάποιο 3d printed ίσως???)
Ελπίζω το παραπάνω να σας φάνηκε χρήσιμο.
Ερωτήσεις/σχόλια κλπ mostly welcome.
BR,
GT