View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Horloge à affichage sur écran couleur et réglable à l'aide de l'encodeur rotatif (module S65 shield)

ARDUINO - TFT - ENCODEUR
Par X. HINAULT - Créé le 28/04/2010

Présentation

Ce programme réalise une horloge affichant les secondes, minutes, heures cadencé par une interruption du Timer 2 qui est également utilisée pour l'incrémentation/décrémentation des valeurs des heures, minutes, secondes à l'aide l'encodeur rotatif.

Ce programme utilise les fonctionnalités suivantes :

  • Utilise un afficheur TFT 65536 couleurs Graphique 132x176 type S65
  • Utilise l'Encodeur Rotatif du module S65
  • Utilise interruption du Timer 2 à intervalle régulier

Voir également :

Matériel Nécessaire

L'espace de développement Arduino

  • ... pour éditer, compiler le programme et programmer la carte Arduino.

Le matériel suivant pour réaliser le montage associé

  • un module avec afficheur couleur TFT 176x132

Acheté ici ( 35 Euros TTC seulement !) : http://www.watterott.com/en/Arduino-S65-Shield
Documentation ici : Module d'affichage à écran couleur Arduino S65 shield
Librairie pour afficheur TFT couleur S65

Instructions de montage

Le module S65 Shield est à enficher directement broche à broche sur la carte Arduino réalisant ainsi les connexions suivantes : Ecran graphique S65 TFT contrôlé par 5 broches :

  • broche S65_DAT du module sur la broche 11 de la carte Arduino
  • broche S65_CLK du module sur la broche 13 de la carte Arduino
  • broche S65_RS du module sur la broche 4 de la carte Arduino
  • broche S65_RST du module sur la broche 17 de la carte Arduino
  • broche S65_CS du module sur la broche 16 de la carte Arduino

Encodeur rotatif contrôlé par 3 broches :

  • broche RE_SW du module sur la broche 5 de la carte Arduino
  • broche RE_PhA du module sur la broche 6 de la carte Arduino
  • broche RE_PhB du module sur la broche 7 de la carte Arduino


Le schéma théorique du montage


Le schéma théorique du montage

Le circuit du montage


Le schéma du montage à réaliser

Explication du programme

Structure globale du programme

Ce programme simple comprend :

  • une entête déclarative
  • une partie « configuration » qui ne sera exécutée qu'une fois (fonction setup( ) )
  • une partie constituée d'une boucle sans fin que le programme répètera à l'infini ( fonction loop( ) ) : c'est le coeur du programme.

Déroulement du programme

Le programme se déroule de la façon suivante :

  • Après avoir pris en compte les instructions de la partie déclarative,
  • puis après avoir exécuté la partie configuration ( fonction setup( ) ),
  • le programme bouclera sans fin ( fonction loop ( ) ), exécutant de façon répétée le code compris dans la boucle sans fin.

Une interruption est par ailleurs générée toutes les millisecondes à l'aide du Timer 2 : toutes les millisecondes, l'état de l'encodeur rotatif est analysé et les fonctions de la librairie renvoient la valeur correspondant à l'état de l'encodeur rotatif.

Pour plus de détails, voir :


Le déroulement du programme

Au niveau de la partie déclarative :

Inclusion des librairies utilisées

  • On inclut les librairies des fonctionnalités utilisées :
    • Inclusion de la librairie pour l'afficheur TFT couleur S65 :

#include <S65Display.h> // Inclusion de la librairie pour afficheur TFT couleur S65 

  • Inclusion de la librairie pour encodeur rotatif du module S65 :

#include <RotaryEncoder.h> // Inclusion de la librairie pour encodeur rotatif du module S65 

  • Inclusion de la librairie pour interruption à intervalle régulier avec le Timer 2 :

#include <MsTimer2.h> // inclusion de la librairie Timer2

Déclaration des variables globales

  • Déclaration des variables globales du programmes :

On crée plusieurs variables utiles pour le comptage des heures, minutes, secondes, etc... On déclare également plusieurs variables utiles pour l'affichage de l'heure.


volatile int seconde=0; 
volatile int compt_millisec=0; // variable de comptage des millisecondes

volatile int seconde0=1; // variable mémorisation seconde courante
volatile int minute=0;
volatile int heure=0 ;

volatile int etat_encodeur; 

int xo=23; // abscisse de base pour affichage heure
int yo=53; // ordonnée de base pour affichage heure

int taille=2; // taille police utilisée

int debord=5; // distance au bord du cadre en pixel

int fond_heure=bleu;
int fond_minute=bleu;
int fond_seconde=bleu;

volatile int selection=0; // variable indiquant la sélection courante selon appui encodeur
// 0: aucune sélection 1: heures 2:minutes 3: secondes

int selection0=0; // variable mémorisation selection courante

Déclarations des objets utiles pour les fonctionnalités utilisées

  • Déclaration des objets utiles pour les fonctionnalités utilisées :
    • Déclaration d'un objet afficheur TFT couleur S65 :

S65Display lcd; // Création d'un objet afficheur S65 appelé lcd 


  • Déclaration d'un objet encodeur rotatif :

RotaryEncoder encodeur; // Création d'un objet RotaryEncoder appelé encodeur 

Au niveau de la fonction d'initialisation setup( ) :

Initialisation des fonctionnalités utilisées :

  • On initialise les différentes fonctionnalités utilisées :
    • Initialisation de l'afficheur TFT couleur S65 : on initialise l'afficheur et on réalise un test de fonctionnement en affichant des couleurs d'écran différentes.
lcd.init(4); // initialise l'afficheur TFT couleur S65 avec communication SPI à Fosc/4 = 4 Mhz

// test de l'afficheur 
lcd.clear(RGB(255,0,0)); // efface ecran en rouge
delay (1000); // pause
lcd.clear(RGB(0,255,0)); // efface ecran en vert
delay (1000); // pause
lcd.clear(RGB(0,0,255)); // efface ecran en bleu
delay (1000); // pause
lcd.clear(RGB(255,255,255)); // efface ecran en blanc

  • Initialisation de l'encodeur rotatif du module S65

encodeur.init(); // initialise l'encodeur rotatif du module S65 sur les broches 5,6,7.

  • Initialisation de l'interruption à intervalle régulier avec le Timer 2 : on initialise pour une interruption toutes les millisecondes. On appelle InterruptTimer2 la fonction de gestion de l'interruption qui sera utilisée. On active le Timer 2.

// initialisation interruption Timer 2
MsTimer2::set(1, InterruptTimer2); // période 1ms 
MsTimer2::start(); // active Timer2 

  • On réalise l'affichage initial sur l'écran :

// affichage du cadre  
lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, jaune); 

Au niveau de la boucle principale, la fonction loop ( ) :

  • Dans une première condition, on teste si la variable des secondes a été modifiée. Si c'est le cas, on met à jour l'affichage.

// ------- gestion affichage de l'heure --------- 
if (seconde0!=seconde) { // si incrémentation seconde a eu lieu

  afficheHeure(); // appel fonction affichage de l'heure

  seconde0=seconde; 

}

  • Dans une seconde condition, on teste l'état de la variable sélection qui prend en compte les appuis sur le bouton poussoir d'axe de l'encodeur. En fonction du nombre d'appui, on modifie l'affichage en surlignant la valeur en cours de réglage :

// --------- gestion de l'encodeur rotatif -----
if (selection0!=selection) // si un appui BP encodeur a eu lieu
{
  //lcd.drawInteger(0, 0, selection, DEC, 1, rouge, bleu); //debug

  if (selection==0){ // aucune sélection en cours
   fond_heure=bleu, fond_minute=bleu, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, jaune); // retrace le cadre entier

  }

  if (selection==1){ // sélection heures en cours
   fond_heure=vert, fond_minute=bleu, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  if (selection==2){ // sélection minutes en cours
   fond_heure=bleu, fond_minute=vert, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  if (selection==3){ // sélection secondes en cours
   fond_heure=bleu, fond_minute=bleu, fond_seconde=vert; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  afficheHeure; // actualise affichage
  selection0=selection; // mémorise valeur courante sélection
}

  • Le programme recommence en boucle les instructions de la fonction loop( ).

Se reporter aux commentaires présents dans le programme pour plus de détails.

Autres Fonctions du programme :

  • Dans la fonction InterruptTimer2, on assure :
    • la gestion de l'encodeur à l'aide de la fonction service de la librairie RotaryEncoder.
    • on assure également le comptage des secondes et la gestion des variables des heures, minutes et secondes.
  • Dans la fonction afficheHeure(), on réalise l'affichage de l'heure.

Voir le programme ci-dessous pour plus de détails.

Mise en oeuvre du programme

Préparation du montage et programmation de la carte Arduino :

  • Commencer par réaliser le montage indiqué sur plaque d'expérimentation
  • Ensuite, programmer la carte Arduino avec ce programme (en bas de page) selon la procédure habituelle

Fonctionnement

  • L'heure s'affiche avec comptage des secondes.
  • le réglage est assuré par appui sur l'axe de l'encodeur ce qui sélectionne les heures. La rotation incrémente la valeur. Idemn pour les minutes et les secondes.
  • L'heure une fois réglée, l'affichage se poursuit avec décomptage des secondes.

Le programme complet en langage Arduino :

A copier/coller directement dans l'éditeur Arduino


// --- Programme Arduino ---
// Copyright X. HINAULT - Créé le 28/04/2010
// www.mon-club-elec.fr 

//  Code sous licence GNU GPL : 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//  

// --- Que fait ce programme ? ---
/* Horloge  à affichage couleur et réglage par encodeur rotatif 
basée sur un module S65 shield*/

// --- Fonctionnalités utilisées ---
// Utilise un afficheur TFT 65536 couleurs Graphique 132x176 type S65
// Utilise l'Encodeur Rotatif du module S65 
// Utilise interruption du Timer 2 à intervalle régulier

// --- Circuit à réaliser ---
// Le module S65 Shield est à enficher directement broche à broche  
// sur la carte Arduino réalisant ainsi les connexions suivantes : 
// Ecran graphique S65 TFT contrôlé par 5 broches : 
// 	> broche S65_DAT du module sur la broche 11 de la carte Arduino 
// 	> broche S65_CLK du module sur la broche 13 de la carte Arduino 
// 	> broche S65_RS du module sur la broche 4 de la carte Arduino 
// 	> broche S65_RST du module sur la broche 17 de la carte Arduino 
// 	> broche S65_CS du module sur la broche 16 de la carte Arduino 
//
// Encodeur rotatif contrôlé par 3 broches : 
// 	> broche RE_SW du module sur la broche 5 de la carte Arduino 
// 	> broche RE_PhA du module sur la broche 6 de la carte Arduino 
// 	> broche RE_PhB du module sur la broche 7 de la carte Arduino 

//**************** Entête déclarative *******
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables...

// --- Inclusion des librairies utilisées ---

#include <S65Display.h> // Inclusion de la librairie pour afficheur TFT couleur S65 

#include <RotaryEncoder.h> // Inclusion de la librairie pour encodeur rotatif du module S65 
#include <MsTimer2.h> // inclusion de la librairie Timer2

// --- Déclaration des constantes ---

// --- constantes des broches ---


// --- Déclaration des variables globales ---
volatile int seconde=0; 
volatile int compt_millisec=0; // variable de comptage des millisecondes

volatile int seconde0=1; // variable mémorisation seconde courante
volatile int minute=0;
volatile int heure=0 ;

volatile int etat_encodeur; 

int xo=23; // abscisse de base pour affichage heure
int yo=53; // ordonnée de base pour affichage heure

int taille=2; // taille police utilisée

int debord=5; // distance au bord du cadre en pixel

int fond_heure=bleu;
int fond_minute=bleu;
int fond_seconde=bleu;

volatile int selection=0; // variable indiquant la sélection courante selon appui encodeur
// 0: aucune sélection 1: heures 2:minutes 3: secondes

int selection0=0; // variable mémorisation selection courante

// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---

S65Display lcd; // Création d'un objet afficheur S65 appelé lcd 


RotaryEncoder encodeur; // Création d'un objet RotaryEncoder appelé encodeur 


//**************** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

// --- ici instructions à exécuter au démarrage --- 

lcd.init(4); // initialise l'afficheur TFT couleur S65 avec communication SPI à Fosc/4 = 4 Mhz

// test de l'afficheur 
lcd.clear(RGB(255,0,0)); // efface ecran en rouge
delay (1000); // pause 
lcd.clear(RGB(0,255,0)); // efface ecran en vert
delay (1000); // pause 
lcd.clear(RGB(0,0,255)); // efface ecran en bleu
delay (1000); // pause 


encodeur.init(); // initialise l'encodeur rotatif du module S65 sur les broches 5,6,7.


// ------- Broches en sortie -------  


// ------- Broches en entrée -------  


// ------- Activation du rappel au + interne des broches en entrée si nécessaire -------  

// initialisation interruption Timer 2
  MsTimer2::set(1, InterruptTimer2); // période 1ms 
  MsTimer2::start(); // active Timer 2 

// affichage du cadre  
lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, jaune); 

} // fin de la fonction setup()
// ********************************************************************************

//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

// --- ici instructions à exécuter par le programme principal --- 

//variable = encodeur.step(); // renvoie état courant de l'encodeur = valeur 0,1 ou -1
//variable = encodeur.sw(); // renvoie état courant du BP de l'axe de l'encodeur = valeur 0, SW_PRESSED, SW_PRESSEDLONG

// ------- gestion affichage de l'heure --------- 
if (seconde0!=seconde) { // si incrémentation seconde a eu lieu

  afficheHeure(); // appel fonction affichage de l'heure

  seconde0=seconde; 

}


// --------- gestion de l'encodeur rotatif -----
if (selection0!=selection) // si un appui BP encodeur a eu lieu
{
  //lcd.drawInteger(0, 0, selection, DEC, 1, rouge, bleu); //debug

  if (selection==0){ // aucune sélection en cours
   fond_heure=bleu, fond_minute=bleu, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, jaune); // retrace le cadre entier

  }

  if (selection==1){ // sélection heures en cours
   fond_heure=vert, fond_minute=bleu, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  if (selection==2){ // sélection minutes en cours
   fond_heure=bleu, fond_minute=vert, fond_seconde=bleu; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  if (selection==3){ // sélection secondes en cours
   fond_heure=bleu, fond_minute=bleu, fond_seconde=vert; 
   lcd.drawRect(xo-debord-1, yo-debord-1, xo+debord+(taille*8*8)-1, yo+debord+(taille*12)-1, bleu); // efface le cadre entier
  }

  afficheHeure; // actualise affichage
  selection0=selection; // mémorise valeur courante sélection
}

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

//*************** Autres Fonctions du programme *************

void afficheHeure(void) // début fonction d'affichage de l'heure
{
   //-- affichage de l'heure --
  if (heure<10)
  { // si inférieur à 10, on affiche un 0 devant
    lcd.drawInteger(xo, yo, 0, DEC, taille, jaune, fond_heure);
    lcd.drawInteger(xo+(taille*8*1), yo, heure, DEC, taille, jaune, fond_heure); 
  }
  else 
  {// sinon affiche directement la valeur
    lcd.drawInteger(xo, yo, heure, DEC, taille, jaune, fond_heure);
  }

  lcd.drawText(xo+(taille*8*2), yo, ":", taille, jaune, bleu); // affiche :

  //-- affichage des minutes --
  if (minute<10)  
  { // si inférieur à 10, on affiche un 0 devant
    lcd.drawInteger(xo+(taille*8*3), yo, 0, DEC, taille, jaune, fond_minute);
    lcd.drawInteger(xo+(taille*8*4), yo, minute, DEC, taille, jaune, fond_minute);
  }
  else 
  {// sinon affiche directement la valeur
    lcd.drawInteger(xo+(taille*8*3), yo, minute, DEC, taille, jaune, fond_minute);
  }

  lcd.drawText(xo+(taille*8*5), yo, ":", taille, jaune, bleu); // affiche :

  //-- affichage des secondes --
  if (seconde<10)
  { // si inférieur à 10, on affiche un 0 devant
    lcd.drawInteger(xo+(taille*8*6), yo, 0, DEC, taille, jaune, fond_seconde);
    lcd.drawInteger(xo+(taille*8*7), yo, seconde, DEC, taille, jaune, fond_seconde);
  }
  else 
  {// sinon affiche directement la valeur
    lcd.drawInteger(xo+(taille*8*6), yo, seconde, DEC, taille, jaune, fond_seconde);
  }

} // fin affichage heure

//========== fonction gestion interruption timer 2 =============
void InterruptTimer2() { // debut de la fonction d'interruption Timer2

// gestion de l'heure
compt_millisec=compt_millisec+1; // s'incrémente toutes les millisecondes

if (compt_millisec==1000)seconde=seconde+1, compt_millisec=0; // incrémentation des secondes... toutes les 1000 millisecondes et RAZ

//--- gestion des variables de l'heure ---
if (seconde==60)minute=minute+1,seconde=0;
if (minute==60) heure=heure+1, minute=0;
if (heure==24) heure=0;


// gestion de l'encodeur 
encodeur.service(); // appel de la routine de gestion de l'encodeur = analyse état encodeur

//------- gestion appui BP ------- 
if (encodeur.sw()==SW_PRESSED) // si appui sur BP encodeur, on incrémente la variable sélection
{
  selection=selection+1; 
  if (selection>3) selection=0; //RAZ selection
  afficheHeure(); // met à jour l'affichage de l'heure
}

etat_encodeur=encodeur.step(); 

//---------- gestion incrémentation ---------- 
if (etat_encodeur==1) { // si incrémentation

   if (selection==1) { // si heures sélectionnées
      heure=heure+1; // incrémente variable heure
      if (heure>23)heure=0; // RAZ heure
    }

   if (selection==2) { // si minutes sélectionnées
      minute=minute+1; // incrémente variable minute
      if (minute>59) minute=0; // RAZ minute
    }

  if (selection==3) { // si sélection secondes et incrémentation 
      seconde=seconde+1; // incrémente variable seconde
      if (seconde>59) seconde=0; // RAZ seconde
    }

    afficheHeure(); // met à jour l'affichage de l'heure

} // fin if step== +1

/*
//---------- gestion décrémentation --------- 
if (etat_encodeur==-1) { // si décrémentation

   if (selection==1) { // si heures sélectionnées
      heure=heure-1; // incrémente variable heure
      if (heure<0)heure=23; // RAZ heure
    }

   if (selection==2) { // si minutes sélectionnées
      minute=minute-1; // incrémente variable minute
      if (minute<0) minute=59; // RAZ minute
    }

  if (selection==3) { // si sélection secondes et incrémentation 
      seconde=seconde-1; // incrémente variable seconde
      if (seconde<0) seconde=59; // RAZ seconde
    }

  afficheHeure(); // met à jour l'affichage de l'heure

} // fin if step== -1

*/

}
// --- Fin programme ---