Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
RTC set up with rotary encoder
Topic last updated 08 Jan 2014, by BOBILLIER Eric.
3
replies
Hello forum,
I have written a program that displays time on a LCD screen by using the RTC in mbed library and TextLCD library.
What I would like to do now is to using a rotary encoder to set time on the LCD screen. I'm using a nice guy, Karl's rotary encoder library. http://mbed.org/users/charly/libraries/mRotaryEncoder/lmcj2u
Can anyone give me tips on how to get started?
Here's the RTC code with LCD screen;
<<code>>
#include "mbed.h"
#include "TextLCD.h"
TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
InterruptIn plus(p6);
void set_time(time_t t);
int main() {
struct tm t;
t.tm_sec = 40; // 0-59
t.tm_min = 22; // 0-59
t.tm_hour = 3; // 0-23
t.tm_mday = 17; // 1-31
t.tm_mon = 10; // 0-11
t.tm_year = 111; // year since 1900
time_t seconds = mktime(&t);
set_time(seconds); // Set time to Thu, 17 Nov 2011 03:22:40
lcd.cls();
while (1) {
time_t seconds = time(NULL);
char buffer[32];
strftime(buffer, 32, "%a %d/%m/%Y\n%I:%M:%S %p\n", localtime(&seconds));
lcd.locate(0,0);
lcd.printf("%s", buffer);
}
}
<</code>>
Hi i can propose one solution to this old post. Because for one of my project, i have write something similar . But i use mRotaryEncoder Library in place of QEI (more stable with low quality encoder). When you run my code, "OK" blink, if you push the rotary encoder you quit the Time Update function and go to the end of program (led blinking), but if you turn rotary," NON" Blink and if you push now you can modify Date and Time.(sorry for French comments)
include the mbed,mRotaryEncoder.h,TextLCD.h libraries with this snippet
/* Ce programme est un exemple permettant de mettre à l'heure et à la date une RTC à l'aide d'un bouton encodeur quadratique. Ce programme , après une demande d'initialisation su de l'heure via un programme type hyper terminal (Ex:Hterm)sur PC, permet de modifier chacun des paramètres de la date et de l'heure en utilisant le bouton encodeur et d'afficher le résultat sur un afficheur 2X20. Chaque champ à modifier se met à clignoter pour indiquer qu'il est modifiable. une rotation du bouton permet alors de modifier cette valeur , puis un appui sur le bouton permet de valider son choix. Le clignotement passe alors au paramètre suivant. Nota: L'appui lorsque l'affichage clignote sur "OK" permet de quitter la fonction de mise à l'heure. Alors que l'appui sur"NON", permet de passer à la modification des paramètres de dates et heures. */ #include "mbed.h" #include "mRotaryEncoder.h" #include "TextLCD.h" #include <time.h> // prototype void Define_Date (char *Buff_Afficheur); void BlinkLcdText (char *buffer_Lcd,int Index_1erChar, int Nb_Char); //I/O DigitalOut myled(LED1); TextLCD lcd(p26, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // rs, e, d4-d7TextLCD lcd(p26, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // rs, e, d4-d7 //mRotaryEncoder(PinName pinA, PinName pinB, PinName pinSW, PinMode pullMode=PullUp, int debounceTime_us=1000) mRotaryEncoder wheel(p11, p12, p13); // Défini les entrées associées au Bouton encodeur (A,B,Bp) //Variables Globales utilisées par la bibliothèque mRotaryEncoder int lastGet; int thisGet; bool enc_pressed = false; // Button of rotaryencoder was pressed bool enc_rotated = false; // rotary encoder was totaded left or right //Variables Globales utilisées pour définir le buffer d'affichage char Buff_Afficheur[41]; //Variables Globales utilisées pour stocker le temps de la RTC struct tm t; // Structure stockant le temps //interrup-Handler for button on rotary-encoder void trigger_sw() { enc_pressed = true; // just set the flag, rest is done outside isr } //interrup-Handler for rotary-encoder rotation void trigger_rotated() { enc_rotated = true; // just set the flag, rest is done outside isr } int main() { // Initialisation de la structure de temps pour la RTC: time_t seconds = time(NULL); if ((seconds < 1388534400)|| (seconds == -1)){ // si la RTC à été reseter sans sauvegarde, elle peut renvoyer -1 ou une faible valeur t.tm_year = 2014-1900; // Donc on la force avec la date 1.1.2014 00:00:00 t.tm_mon = 1-1; t.tm_mday = 1; t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; set_time(mktime(&t)); // Crée et défini la valeurs de temps à partir de la structure de temps t } else tm t= *localtime(&seconds); // Met à jour la structure tm.t avec la valeur de la RTC.// Initialisation de la structure de temps pour la RTC: //Int-Handler Déclare les vecteur d'interruption lorsque l'on touche le bouton encodeur // call trigger_sw() when button of rotary-encoder is pressed wheel.attachSW(&trigger_sw); // call trigger_rot() when the shaft is rotaded left or right wheel.attachROT(&trigger_rotated); lastGet = 0; // display the time update menu Define_Date(Buff_Afficheur); // Fait clignoter les leds pour indiquer que la fin du programme est atteind. while(1) { myled = 1; wait(0.2); myled = 0; wait(0.2); } } //Clignotement de certaine zone de l'afficheur. void BlinkLcdText (char *buffer_Lcd,int Index_1erChar, int Nb_Char){ char Buff_copy[41]; int i=0; strcpy(Buff_copy,buffer_Lcd); // recopie la chaine originale dans le tampon Buff_copy for (i = Index_1erChar; i<(Nb_Char + Index_1erChar);i++) Buff_copy[i]= ' '; // Efface les caractères indiqués //pc.printf ("%s",Buff_copy); lcd.locate(0,0); lcd.printf("%s",Buff_copy); wait(0.2); strcpy(Buff_copy,buffer_Lcd); // recopie la chaine originale dans le tampon Buff_copy lcd.locate(0,0); lcd.printf("%s",Buff_copy); wait(0.2); } //Fonction modification de l'heure. void Define_Date (char *Buff_Afficheur){ bool Again = true; int Modif_selection = 0; enc_rotated = false; enc_pressed = false; wheel.Set(0); // Reset du compteur du bouton encodeur pour repartir propre lcd.cls(); while(Again) { lcd.locate (0,0); wait(0.1); // Indispensable: permet de laissé au µp Le temps pour la mise à jour de la RTC et d'éviter ainsi la mise en défaut de celle-ci. time_t seconds = time(NULL); // Récupère dans seconds la valeur de la RTC tm t= *localtime(&seconds); //met à jour la structure de temps tm à partir de l'heure courante strftime(Buff_Afficheur, 41, "Date:%d-%m-%Y %H:%M NON/OK", localtime(&seconds)); // construit la chaine à afficher en intégrant une structure de temps (d'ou le strftime) lcd.printf("%s", Buff_Afficheur); // Affiche cette chaine switch (Modif_selection) { case 0 : BlinkLcdText ( Buff_Afficheur,38,2); //Fait clignoter le "OK" if (enc_rotated) { // Test si bouton encodeur tourné enc_rotated = false; // Reset le flag de rotation Modif_selection = 1; // Force le menu Modif sélection à revenir dans ce case aprés avoir effectuer ce test wheel.Set(0); // Reset du compteur du bouton encodeur pour repartir propre } if (enc_pressed) { // Test si bouton encodeur enfoncé enc_pressed = false; // si oui reset le flag de Bouton enfoncé // mettre ici Quitter la fonction Again = false; } break; case 1 : BlinkLcdText ( Buff_Afficheur,34,3); //Fait clignoter le "NON" if (enc_rotated) { enc_rotated = false; Modif_selection = 0; } if (enc_pressed) { enc_pressed = false; Modif_selection = 5; // si appuyer va modifier les minutes wheel.Set(0); } break; case 2 : BlinkLcdText ( Buff_Afficheur,5,2); //Fait clignoter le "Jour" if (enc_rotated) { enc_rotated = false; Modif_selection = 2; t.tm_mday = t.tm_mday + wheel.Get(); // Met à jour le Jour en ajoutant ou retranchant la valeur de rotation du bouton encodeur set_time(mktime(&t)); // Met à jour la RTC interne pour tenir compte du changement } if (enc_pressed) { enc_pressed = false; Modif_selection = 3; // si appuyé va modifier les Mois } wheel.Set(0); break; case 3 : BlinkLcdText ( Buff_Afficheur,8,2); //Fait clignoter le "Mois" if (enc_rotated) { enc_rotated = false; Modif_selection = 3; t.tm_mon = t.tm_mon + wheel.Get(); set_time(mktime(&t)); } if (enc_pressed) { enc_pressed = false; Modif_selection = 4; // si appuyé va modifier les années } wheel.Set(0); break; case 4 : BlinkLcdText ( Buff_Afficheur,11,4); //Fait clignoter l' "Année" if (enc_rotated) { enc_rotated = false; Modif_selection = 4; t.tm_year = t.tm_year + wheel.Get(); set_time(mktime(&t)); } if (enc_pressed) { enc_pressed = false; Modif_selection = 1; // si appuyé retour en "NON" } wheel.Set(0); break; case 5 : BlinkLcdText ( Buff_Afficheur,28,2); //Fait clignoter les "minutes" if (enc_rotated) { enc_rotated = false; Modif_selection = 5; t.tm_sec = 0; t.tm_min = t.tm_min + wheel.Get(); set_time(mktime(&t)); } if (enc_pressed) { enc_pressed = false; // si appuyé va modifier les heures Modif_selection = 6; } wheel.Set(0); break; case 6 : BlinkLcdText ( Buff_Afficheur,25,2); //Fait clignoter les "heures" if (enc_rotated) { enc_rotated = false; Modif_selection = 6; t.tm_hour = t.tm_hour + wheel.Get(); set_time(mktime(&t)); } if (enc_pressed) { enc_pressed = false; Modif_selection = 2; // si appuyé va modifier les jours } wheel.Set(0); break; } } }
Hi i can propose one solution to this old post. Because for one of my project, i have write something similar . But i use mRotaryEncoder Library in place of QEI (more stable with low quality encoder). When you run my code, "OK" blink, if you push the rotary encoder you quit the Time Update function and go to the end of program (led blinking), but if you turn rotary," NON" Blink and if you push now you can modify Date and Time.(sorry for French comments)
<<code title=include the mbed,mRotaryEncoder.h,TextLCD.h libraries with this snippet>>
/* Ce programme est un exemple permettant de mettre à l'heure et à la date une RTC à l'aide d'un bouton encodeur quadratique.
Ce programme , après une demande d'initialisation su de l'heure via un programme type hyper terminal (Ex:Hterm)sur PC,
permet de modifier chacun des paramètres de la date et de l'heure en utilisant le bouton encodeur et d'afficher le résultat sur un afficheur 2X20.
Chaque champ à modifier se met à clignoter pour indiquer qu'il est modifiable. une rotation du bouton permet alors de modifier
cette valeur , puis un appui sur le bouton permet de valider son choix. Le clignotement passe alors au paramètre suivant.
Nota: L'appui lorsque l'affichage clignote sur "OK" permet de quitter la fonction de mise à l'heure. Alors que l'appui sur"NON", permet de passer
à la modification des paramètres de dates et heures.
*/
#include "mbed.h"
#include "mRotaryEncoder.h"
#include "TextLCD.h"
#include <time.h>
// prototype
void Define_Date (char *Buff_Afficheur);
void BlinkLcdText (char *buffer_Lcd,int Index_1erChar, int Nb_Char);
//I/O
DigitalOut myled(LED1);
TextLCD lcd(p26, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // rs, e, d4-d7TextLCD lcd(p26, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // rs, e, d4-d7
//mRotaryEncoder(PinName pinA, PinName pinB, PinName pinSW, PinMode pullMode=PullUp, int debounceTime_us=1000)
mRotaryEncoder wheel(p11, p12, p13); // Défini les entrées associées au Bouton encodeur (A,B,Bp)
//Variables Globales utilisées par la bibliothèque mRotaryEncoder
int lastGet;
int thisGet;
bool enc_pressed = false; // Button of rotaryencoder was pressed
bool enc_rotated = false; // rotary encoder was totaded left or right
//Variables Globales utilisées pour définir le buffer d'affichage
char Buff_Afficheur[41];
//Variables Globales utilisées pour stocker le temps de la RTC
struct tm t; // Structure stockant le temps
//interrup-Handler for button on rotary-encoder
void trigger_sw() {
enc_pressed = true; // just set the flag, rest is done outside isr
}
//interrup-Handler for rotary-encoder rotation
void trigger_rotated() {
enc_rotated = true; // just set the flag, rest is done outside isr
}
int main() {
// Initialisation de la structure de temps pour la RTC:
time_t seconds = time(NULL);
if ((seconds < 1388534400)|| (seconds == -1)){ // si la RTC à été reseter sans sauvegarde, elle peut renvoyer -1 ou une faible valeur
t.tm_year = 2014-1900; // Donc on la force avec la date 1.1.2014 00:00:00
t.tm_mon = 1-1;
t.tm_mday = 1;
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
set_time(mktime(&t)); // Crée et défini la valeurs de temps à partir de la structure de temps t
}
else tm t= *localtime(&seconds); // Met à jour la structure tm.t avec la valeur de la RTC.// Initialisation de la structure de temps pour la RTC:
//Int-Handler Déclare les vecteur d'interruption lorsque l'on touche le bouton encodeur
// call trigger_sw() when button of rotary-encoder is pressed
wheel.attachSW(&trigger_sw);
// call trigger_rot() when the shaft is rotaded left or right
wheel.attachROT(&trigger_rotated);
lastGet = 0;
// display the time update menu
Define_Date(Buff_Afficheur);
// Fait clignoter les leds pour indiquer que la fin du programme est atteind.
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}
//Clignotement de certaine zone de l'afficheur.
void BlinkLcdText (char *buffer_Lcd,int Index_1erChar, int Nb_Char){
char Buff_copy[41];
int i=0;
strcpy(Buff_copy,buffer_Lcd); // recopie la chaine originale dans le tampon Buff_copy
for (i = Index_1erChar; i<(Nb_Char + Index_1erChar);i++) Buff_copy[i]= ' '; // Efface les caractères indiqués
//pc.printf ("%s",Buff_copy);
lcd.locate(0,0);
lcd.printf("%s",Buff_copy);
wait(0.2);
strcpy(Buff_copy,buffer_Lcd); // recopie la chaine originale dans le tampon Buff_copy
lcd.locate(0,0);
lcd.printf("%s",Buff_copy);
wait(0.2);
}
//Fonction modification de l'heure.
void Define_Date (char *Buff_Afficheur){
bool Again = true;
int Modif_selection = 0;
enc_rotated = false;
enc_pressed = false;
wheel.Set(0); // Reset du compteur du bouton encodeur pour repartir propre
lcd.cls();
while(Again) {
lcd.locate (0,0);
wait(0.1); // Indispensable: permet de laissé au µp Le temps pour la mise à jour de la RTC et d'éviter ainsi la mise en défaut de celle-ci.
time_t seconds = time(NULL); // Récupère dans seconds la valeur de la RTC
tm t= *localtime(&seconds); //met à jour la structure de temps tm à partir de l'heure courante
strftime(Buff_Afficheur, 41, "Date:%d-%m-%Y %H:%M NON/OK", localtime(&seconds)); // construit la chaine à afficher en intégrant une structure de temps (d'ou le strftime)
lcd.printf("%s", Buff_Afficheur); // Affiche cette chaine
switch (Modif_selection)
{
case 0 : BlinkLcdText ( Buff_Afficheur,38,2); //Fait clignoter le "OK"
if (enc_rotated) { // Test si bouton encodeur tourné
enc_rotated = false; // Reset le flag de rotation
Modif_selection = 1; // Force le menu Modif sélection à revenir dans ce case aprés avoir effectuer ce test
wheel.Set(0); // Reset du compteur du bouton encodeur pour repartir propre
}
if (enc_pressed) { // Test si bouton encodeur enfoncé
enc_pressed = false; // si oui reset le flag de Bouton enfoncé
// mettre ici Quitter la fonction
Again = false;
}
break;
case 1 : BlinkLcdText ( Buff_Afficheur,34,3); //Fait clignoter le "NON"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 0;
}
if (enc_pressed) {
enc_pressed = false;
Modif_selection = 5; // si appuyer va modifier les minutes
wheel.Set(0);
}
break;
case 2 : BlinkLcdText ( Buff_Afficheur,5,2); //Fait clignoter le "Jour"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 2;
t.tm_mday = t.tm_mday + wheel.Get(); // Met à jour le Jour en ajoutant ou retranchant la valeur de rotation du bouton encodeur
set_time(mktime(&t)); // Met à jour la RTC interne pour tenir compte du changement
}
if (enc_pressed) {
enc_pressed = false;
Modif_selection = 3; // si appuyé va modifier les Mois
}
wheel.Set(0);
break;
case 3 : BlinkLcdText ( Buff_Afficheur,8,2); //Fait clignoter le "Mois"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 3;
t.tm_mon = t.tm_mon + wheel.Get();
set_time(mktime(&t));
}
if (enc_pressed) {
enc_pressed = false;
Modif_selection = 4; // si appuyé va modifier les années
}
wheel.Set(0);
break;
case 4 : BlinkLcdText ( Buff_Afficheur,11,4); //Fait clignoter l' "Année"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 4;
t.tm_year = t.tm_year + wheel.Get();
set_time(mktime(&t));
}
if (enc_pressed) {
enc_pressed = false;
Modif_selection = 1; // si appuyé retour en "NON"
}
wheel.Set(0);
break;
case 5 : BlinkLcdText ( Buff_Afficheur,28,2); //Fait clignoter les "minutes"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 5;
t.tm_sec = 0;
t.tm_min = t.tm_min + wheel.Get();
set_time(mktime(&t));
}
if (enc_pressed) {
enc_pressed = false; // si appuyé va modifier les heures
Modif_selection = 6;
}
wheel.Set(0);
break;
case 6 : BlinkLcdText ( Buff_Afficheur,25,2); //Fait clignoter les "heures"
if (enc_rotated) {
enc_rotated = false;
Modif_selection = 6;
t.tm_hour = t.tm_hour + wheel.Get();
set_time(mktime(&t));
}
if (enc_pressed) {
enc_pressed = false;
Modif_selection = 2; // si appuyé va modifier les jours
}
wheel.Set(0);
break;
}
}
}
<</code>>
Hello forum,
I have written a program that displays time on a LCD screen by using the RTC in mbed library and TextLCD library.
What I would like to do now is to using a rotary encoder to set time on the LCD screen. I'm using a nice guy, Karl's rotary encoder library. http://mbed.org/users/charly/libraries/mRotaryEncoder/lmcj2u
Can anyone give me tips on how to get started?
Here's the RTC code with LCD screen;