jeudi 27 septembre 2018

ESP8266 / ESP32 et afficheur à base de TM1638

Note: Cet article a été mis à jour le 28 juillet 2019 afin d'ajouter des informations concernant l'ESP32.

J'aime bien l'afficheur "LED and KEY" à base de TM1638 qui comporte huit afficheurs numériques à 7 segments, 8 LEDs et 8 boutons. J'avais déjà eu l'occasion d'utiliser ce genre de module avec un Arduino, avec un ATTiny85, et avec un STM32 Nucleo.  Cette fois-ci, en prévision d'un projet d'horloge connectée dont je vous parlerai bientôt, c'est un module ESP8266 (ou ESP32) qui pilotera l'afficheur.


Installation de la bibliothèque dans l'IDE Arduino

J'avais espéré pouvoir utiliser la bibliothèque "tm1638" par Ricardo Batista qui fonctionne très bien avec une carte Arduino mais, malheureusement, elle semble incompatible avec l'ESP8266 (voir message d'erreur ci-dessous).




Je me suis donc résigné à utiliser la bibliothèque "ErriezTM1638" qui, elle, a fonctionné sans problèmes. Malheureusement, cette bibliothèque a été conçue pour utiliser le circuit intégré TM1638 dans n'importe quel circuit, plutôt que pour les cartes de type LED and KEY en particulier.  Pour cette raison, elle est beaucoup moins simple d'utilisation que la bibliothèque de Ricardo Batista.

Tous les sketches présentés dans la suite de ce billet nécessitent la présence de la bibliothèque ErriezTM1638.

Circuit

Si vous utilisez une carte de développement complète munie d'un connecteur USB (genre Wemos, NodeMCU, etc.), les 5 broches du module TM1638 sont branchés à la carte de la façon suivante:
  • La broche VCC du module TM1638 est branchée à 3,3 V.
  • Les la broche GND du module TM1638 est branchée à GND.
  • La broche STB du TM1638 est branchée à la broche GPIO 4 de l'ESP8266 ou de l'ESP32
  • La broche CLK du TM1638 est branchée à la broche GPIO 16 de l'ESP8266 ou de l'ESP32
  • La broche DIO du TM1638 est branchée à la broche GPIO 5 de l'EP8266 ou de l'ESP32
Le schéma ci-dessous montre les connexions pour une carte Wemos D1R1 (la position des broches peut être très différente sur une autre carte):


Le circuit ci-dessous montre les connexions sur ma carte de développement ESP32:


Les instructions suivantes vous seront utiles si vous utilisez un module ESP8266 qui ne fait pas partie d'une carte de développement (un ESP-12, par exemple):
  • La broche VCC du module TM1638 ainsi que les broches VCC, RST et CH_PD (ou "EN") du module ESP8266 sont branchées à 3,3 V.
  • Les la broche GND du module TM1638 et les broches GND et GPIO0 du module ESP8266 sont branchées à la masse.
  • La broche RXD de l'ESP8266 est reliée à la broche TX du convertisseur USB-TTL, et la broche TXD de l'ESP8266 est reliée à la broche RX du convertisseur USB-TTL.

Il ne reste plus que les 3 broches du module TM1638 qui servent à la communication des données:
  • La broche STB du TM1638 est branchée à la broche GPIO 4 de l'ESP8266
  • La broche CLK du TM1638 est branchée à la broche GPIO 16 de l'ESP8266
  • La broche DIO du TM1638 est branchée à la broche GPIO 5 de l'EP8266



Afficher des nombres

Pour afficher un nombre, la bibliothèque ErriezTM1638 met à notre disposition la fonction writeData().  Cette fonction nécessite deux arguments: le premier argument est un nombre qui indique la position du chiffre sur l'afficheur, alors que le deuxième argument est un nombre qui indique lesquels des 7 segments doivent être allumés.

Par exemple, le premier chiffre à gauche de l'afficheur occupe la position "0b00000000".  Si je désire y afficher le chiffre zéro, je dois allumer tous les segments sauf le trait central et le point, ce qui correspond au nombre "0b00111111".  La commande permettant d'afficher zéro à la première position à gauche de l'afficheur sera donc:

tm1638.writeData(0b00000000, 0b00111111);

Comme vous pouvez le constater, ce qui rend l'utilisation de la bibliothèque un brin compliquée, c'est que nous devons gérer nous-mêmes l'affichage des segments (ce que j'accomplis, dans le sketch ci-dessous, à l'intérieur de la routine "afficheChiffre").  De plus, l'adresse correspondant à la position du chiffre sur l'afficheur ne respecte aucune logique. Puisque le premier chiffre à gauche correspond à la position 0b00000000, on pourrait croire que le deuxième chiffre se trouve à l'adresse 0b00000001, mais non... 0b00000001 est l'adresse d'une LED et le deuxième chiffre de l'afficheur numérique se trouve plutôt à l'adresse 0b00000110 !

Voici donc un sketch qui affiche un nombre croissant sur l'afficheur numérique.


/**************************************************
Afficheur TM1638 pour ESP8266
Affichage d'un nombre à huit chiffres sur un module
LED & KEY branché à un ESP8266
https://electroniqueamateur.blogspot.com/2018/09/esp8266-et-afficheur-base-de-tm1638.html
Utilisation de la bibliothèque ErriezTM1638
Source: https://github.com/Erriez/ErriezTM1638
Documentation: https://erriez.github.io/ErriezTM1638
**************************************************/
#include <ErriezTM1638.h> // voir https://github.com/Erriez/ErriezTM1638
// Définition des broches liées au module LED & KEY
#define TM1638_CLK_PIN 16
#define TM1638_DIO_PIN 5
#define TM1638_STB0_PIN 4
// Création d'un objet TM1638
TM1638 tm1638(TM1638_CLK_PIN, TM1638_DIO_PIN, TM1638_STB0_PIN);
int compteur = 0;
void setup()
{
tm1638.begin();
tm1638.clear();
tm1638.setBrightness(3);
tm1638.displayOn();
}
void afficheChiffre(int rang, int valeur)
{
int leRang, laValeur;
switch (rang) {
case 1:
leRang = 0b00000000;
break;
case 2:
leRang = 0b00000010;
break;
case 3:
leRang = 0b00000100;
break;
case 4:
leRang = 0b00000110;
break;
case 5:
leRang = 0b00001000;
break;
case 6:
leRang = 0b000001010;
break;
case 7:
leRang = 0b000001100;
break;
case 8:
leRang = 0b000001110;
break;
}
switch (valeur) {
case 0:
laValeur = 0b00111111;
break;
case 1:
laValeur = 0b00000110;
break;
case 2:
laValeur = 0b01011011;
break;
case 3:
laValeur = 0b01001111;
break;
case 4:
laValeur = 0b01100110;
break;
case 5:
laValeur = 0b01101101;
break;
case 6:
laValeur = 0b01111101;
break;
case 7:
laValeur = 0b00000111;
break;
case 8:
laValeur = 0b01111111;
break;
case 9:
laValeur = 0b01101111;
break;
}
tm1638.writeData(leRang, laValeur);
}
void afficheNombre()
{
int reste;
// premier chiffre
afficheChiffre(1, compteur / 10000000);
// deuxième chiffre
reste = compteur % 10000000;
afficheChiffre(2, reste / 1000000);
// troisième chiffre
reste = reste % 1000000;
afficheChiffre(3, reste / 100000);
// quatrième chiffre
reste = reste % 100000;
afficheChiffre(4, reste / 10000);
// cinquième chiffre
reste = reste % 10000;
afficheChiffre(5, reste / 1000);
// sixième chiffre
reste = reste % 1000;
afficheChiffre(6, reste / 100);
// septième chiffre
reste = reste % 100;
afficheChiffre(7, reste / 10);
//huitième chiffre
reste = reste % 10;
afficheChiffre(8, reste);
}
void loop()
{
afficheNombre();
compteur ++;
delay(300);
}

Allumer des LEDs

Pour contrôler les 8 LEDs, on utilise encore la fonction writeData().  Le premier argument est la position de la LED (qui est, par exemple, "1" pour la première LED à gauche), et le deuxième argument est "1" pour allumer la LED, et "0" pour l'éteindre.

Le sketch ci-dessous allume les 8 LEDs à tour de rôle.


/**************************************************
Afficheur TM1638 pour ESP8266
Allume à tour de rôle les 8 LEDs du module LED & KEY
https://electroniqueamateur.blogspot.com/2018/09/esp8266-et-afficheur-base-de-tm1638.html
Utilisation de la bibliothèque ErriezTM1638
Source: https://github.com/Erriez/ErriezTM1638
Documentation: https://erriez.github.io/ErriezTM1638
**************************************************/
#include <ErriezTM1638.h> // voir https://github.com/Erriez/ErriezTM1638
// Définition des broches liées au module LED & KEY
#define TM1638_CLK_PIN 16
#define TM1638_DIO_PIN 5
#define TM1638_STB0_PIN 4
// Création d'un objet TM1638
TM1638 tm1638(TM1638_CLK_PIN, TM1638_DIO_PIN, TM1638_STB0_PIN);
void setup()
{
tm1638.begin();
tm1638.clear();
tm1638.setBrightness(3);
tm1638.displayOn();
}
void loop()
{
// on allume la première LED
tm1638.writeData(0b00000001, 1);
delay(1000);
// on éteint la première LED
tm1638.writeData(0b00000001, 0);
// on allume la deuxième LED
tm1638.writeData(0b00000011, 1);
delay(1000);
// on éteint la deuxième LED
tm1638.writeData(0b00000011, 0);
// on allume la troisième LED
tm1638.writeData(0b00000101, 1);
delay(1000);
// on éteint la troisième LED
tm1638.writeData(0b00000101, 0);
// on allume la quatrième LED
tm1638.writeData(0b00000111, 1);
delay(1000);
// on éteint la quatrième LED
tm1638.writeData(0b00000111, 0);
// on allume la cinquième LED
tm1638.writeData(0b000001001, 1);
delay(1000);
// on éteint la cinquième LED
tm1638.writeData(0b000001001, 0);
// on allume la sixième LED
tm1638.writeData(0b000001011, 1);
delay(1000);
// on éteint la sixième LED
tm1638.writeData(0b000001011, 0);
// on allume la septième LED
tm1638.writeData(0b000001101, 1);
delay(1000);
// on éteint la septième LED
tm1638.writeData(0b000001101, 0);
// on allume la huitième LED
tm1638.writeData(0b000001111, 1);
delay(1000);
// on éteint la huitième LED
tm1638.writeData(0b000001111, 0);
}

Détecter les boutons enfoncés

Pour détecter si un des 8 boutons est enfoncé, il s'agit d'utiliser la commande getKeys(), qui retourne un nombre à 32 bits dont la valeur dépend de la position du bouton enfoncé.  Si vous enfoncez le bouton "S1", getKeys() retourne "1", alors que si vous enfoncez le bouton "S2", getKeys() retourne 256 (je vous réfère au sketch pour connaître la valeur retournée par chaque bouton).

Si plusieurs boutons sont enfoncés simultanément, getKeys() retourne la somme des valeurs individuelles de chaque bouton.  Si vous enfoncez S1 et S2 en même temps, la valeur retournée sera donc 257 (qui vient de 1 + 256 ).

Le sketch ci-dessous affiche dans le moniteur série le nom du bouton enfoncé.


/**************************************************
Identifie le bouton pressé sur un module
LED & KEY branché à un ESP8266
https://electroniqueamateur.blogspot.com/2018/09/esp8266-et-afficheur-base-de-tm1638.html
Utilisation de la bibliothèque ErriezTM1638
Source: https://github.com/Erriez/ErriezTM1638
Documentation: https://erriez.github.io/ErriezTM1638
**************************************************/
#include <ErriezTM1638.h>
// Définition des broches liées au module LED & KEY
#define TM1638_CLK_PIN 16
#define TM1638_DIO_PIN 5
#define TM1638_STB0_PIN 4
// création d'un objet tm1638
TM1638 tm1638(TM1638_CLK_PIN, TM1638_DIO_PIN, TM1638_STB0_PIN);
void setup()
{
Serial.begin(115200);
tm1638.begin();
tm1638.displayOff();
tm1638.clear();
tm1638.setBrightness(3);
tm1638.displayOn();
}
void loop()
{
static uint32_t boutonsPrecedents = 0;
uint32_t boutons;
// Read 32-bit keys
boutons = tm1638.getKeys();
// Détection du bouton pressé
if (boutonsPrecedents != boutons) {
boutonsPrecedents = boutons;
if (boutons == 1) {
Serial.println("Bouton S1 enfonce");
}
if (boutons == 256) {
Serial.println("Bouton S2 enfonce");
}
if (boutons == 65536) {
Serial.println("Bouton S3 enfonce");
}
if (boutons == 16777216) {
Serial.println("Bouton S4 enfonce");
}
if (boutons == 16) {
Serial.println("Bouton S5 enfonce");
}
if (boutons == 4096) {
Serial.println("Bouton S6 enfonce");
}
if (boutons == 1048576) {
Serial.println("Bouton S7 enfonce");
}
if (boutons == 268435456) {
Serial.println("Bouton S8 enfonce");
}
}
}



À lire également:

Yves Pelletier   (TwitterFacebook)


Aucun commentaire:

Enregistrer un commentaire