E-Paper Display am ESP32 und ESP8266 - [Teil 2] - AZ-Delivery

Introduction

Dans la première partie de cette série de blogs, j'ai montré comment utiliser un affichage e-paper sur un microcontrôleur ESP32. Au cours de ce processus, certains utilisateurs ont déjà remarqué des incohérences. Dans cette partie de la série, je vais d'abord aborder ce point. Ensuite, je montrerai comment afficher ses propres images, les données des capteurs ou les données du réseau du module WLAN. J'utiliserai également la ESP8266 D1 Mini au lieu de la ESP32. Allons-y. 

Besoin de matériel

Number Component Annotation
1 ESP32 NodeMCU ou ESP-32 Dev Kit C V4
1 ESP8266 D1 Mini
1 1.54 "e-paper display
1 DHT11 temperature sensor
PC avec Arduino IDE et connexion Internet


Un conseil avant tout

Si vous ne voulez pas appuyer sur le bouton BOOT de la ESP32 à chaque fois pour télécharger un programme, suivez ces instructions. Vous avez besoin d'un condensateur de 10 µF entre les broches EN (+) et GND (-).

E-Paper Display V1 vs V2

Nous avons reçu quelques réactions à la première partie de cette série. Mes recherches à l'époque étaient donc malheureusement insuffisantes. Maintenant, à ce stade, l'indice pour vous :

Les codes sources et les images de la partie 1 se réfèrent à l'écran ePaper de Waveshare d'une taille de 1,45" et d'une résolution de 200x200 pixels en noir et blanc dans la( ancienne) version 1.

Je tiens à remercier ici Eberhard Werminghoff pour son soutien. J'espère que tout fonctionne maintenant comme il se doit.

Le fabricant Waveshare signale sur son site web que les cartes pilotes de l'écran V1 et V2 sont différentes et que le code source du pilote doit donc être échangé. En outre, la version 1 doit être alimentée avec une tension de 3,3 V, la version 2 tolère jusqu'à 5 V. Pour plus de détails, voir les deux fiches techniques de l'ancienne version 1 et de la nouvelle version 2.

Je montrerai ici brièvement les différences entre les deux affichages :


Vous pouvez voir ici les différences externes de la nouvelle version :

  • La prise est plus petite et se trouve plus loin à l'extérieur
  • Le nombre de composants est étendu et ils sont disposés différemment
  • La broche pour la tension d'alimentation est maintenant appelée VCC, au lieu de 3,3V.
  • Il est nommé Rev2.1
  • Il s'agit d'un autocollant V2, au lieu d'un autocollant PASS.
  • L'option d'interface BS est inversée
  • Une date est imprimée sur le câble ruban. L'affichage le plus récent est celui de 2017 :

Quant aux numéros de broche, je les avais choisis pour pouvoir les placer côte à côte sur le tableau. Cela exclut le SCK et le MOSI, qui ne peuvent être modifiés. Vous pouvez bien sûr utiliser les broches par défaut des exemples. Assurez-vous alors de changer les chiffres de mon code source.

Les cartes ESP32 ou ESP8266 sont disponibles en différentes variantes. Par exemple, avec 30 au lieu de 38, ou la D1 Mini ESP2866 avec encore moins de broches. Consultez les spécifications dans les fiches techniques.

Revenons aux bibliothèques. D'une part, j'utilise la bibliothèque EPD d'Asuki Kono, qui est également spécifiée dans la référence Arduino. Des informations sur son utilisation et le code source se trouvent sur Github. Il peut être utilisé pour les anciens affichages V1 avec une taille d'écran de 1,54" et apporte des exemples pour les trois variantes de module, pour chacune desquelles un fichier d'en-tête différent doit être inclus :

Pour mon affichage, j'avais utilisé l'exemple de ShowRunningTime comme source.

Note : Faites attention si vous avez un affichage en noir/blanc, en noir/blanc/rouge (B) ou en noir/blanc/jaune (C). Ensuite, faites attention à l'utilisation du panneau RAW (c'est-à-dire l'affichage pur) ou de la carte avec interface SPI.

Malheureusement, cette bibliothèque n'a pas été mise à jour et adaptée aux nouvelles versions des affichages. Le fabricant Waveshare propose le code source de la nouvelle version sur Github. Malheureusement, vous ne pouvez pas migrer le code de Waveshare à la bibliothèque EPD aussi facilement.

J'ai adapté la source de partage d'ondes pour l'écran noir et blanc de 1,54" afin que nous puissions l'utiliser, comme la bibliothèque EPD. Vous pouvez télécharger le code source :

Télécharger la bibliothèque epd1in54_V2

Cela ne fonctionne pas avec les écrans multicolores. Pour cela, il faudrait également réécrire les autres fichiers sources.

Brèves instructions pour l'installation :

  • ouvrir le dossier \Sketchbooks\libraries\
  • si vous ne connaissez pas l'emplacement, ouvrez l'IDE Arduino, là le menu Fichier -> Préréparations
  • en haut de la fenêtre, vous trouverez le chemin sous l'emplacement de Sketchbook
  • copier le dossier epd1in54_V2 dans les bibliothèques de "den Ordner"
  • redémarrer l'IDE Arduino
  • Vous trouverez ensuite un exemple de sketch en utilisant le fichier -> Exemples -> Exemples de vos propres bibliothèques -> epd1in54V2 -> epd1in54V2
  • dans la partie supérieure, vous trouverez des informations sur les brochages des différents tableaux
  • commentaire dans la ligne qui correspond à votre tableau
  • après le téléchargement vers le microcontrôleur, la démo de Waveshare devrait fonctionner

Si vous utilisez un affichage de taille différente ou avec plus de couleurs, vous pouvez télécharger les bibliothèques actuelles de Waveshare à partir de Github. Faites attention au pinout qui est donné dans la bibliothèque respective. Si vous souhaitez utiliser d'autres pins, ouvrez le fichier de code source epdif.h et modifiez les lignes suivantes :

// Pin definition
#define RST_PIN 8
#define DC_PIN 9
#define CS_PIN 10
#define BUSY_PIN 7

Il est ensuite codé de manière définitive, mais répond toujours à vos besoins. Si vos compétences en programmation vont au-delà, vous pouvez changer le constructeur de la classe epd afin de pouvoir passer les numéros de pin.

Vous devez également modifier l'emplacement du fichier pgmspace.h dans certains fichiers. La différence réside ici dans l'utilisation de la carte (carte 100% compatible avec Arduino ou ESP32 ou ESP8266).

Ici un extrait du fichier font8.c avant:

#include <avr/pgmspace.h>

et après :

#if defined(__AVR__) || defined(ARDUINO_ARCH_SAMD)
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#endif

Je vais utiliser ma bibliothèque étendue epd1in54_V2 pour l'affichage 1.54" V2 dans cet article.

Comme bibliothèque alternative, je vous avais montré le GxEPD2 de Jean-Marc Zingg. Dans l'exemple GxEPD2_Exemple, vous devez commenter la ligne appropriée qui correspond à votre affichage. En outre, vous devez également choisir le bon processeur (ESP8266, ESP32, STM32 ou carte compatible avec l'Arduino AVR). Pour ce faire, cherchez les lignes suivantes :

#if defined (ESP8266)

ou

#if defined(ESP32)

ou

#if defined(ARDUINO_ARCH_STM32)

ou

#if defined(__AVR)
#if defined (ARDUINO_AVR_MEGA2560)

Les numéros de ligne changent de temps en temps, car le projet est toujours en cours. C'est pourquoi je ne les donne pas ici.

Sous les définitions spécifiées, vous trouverez les déclarations appropriées pour votre affichage. Pour mon exposition, c'était cette ligne :

GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEP015OC1 no longer available

J'avais changé cela pour:

GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(/*CS=*/26, /*DC=*/ 25, /*RST=*/ 33, /*BUSY=*/ 27)); // GDEP015OC1 no longer available

correspondant à mon pinout, que vous trouverez également ci-dessous.

Note: Au MCU Noeud ESP32, vous ne devez pas utiliser les pins GPIO0, GPIO2 et GPIO12, sinon le téléchargement ne fonctionne pas. Infos dazu finden Sie ici.

À ce stade, vous pouvez déjà voir dans le commentaire du développeur la note "GDEP015OC1 n'est plus disponible". C'est l'ancienne version de l'écran 1,54" avec la résolution 200x200 pixels. Pour la version actuelle sur l'ESP32, sélectionnez cette ligne :

GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(/*CS=D5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEH0154D67

 sur la ESP8266, c'est celle-ci:

GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(/*CS=D8*/ SS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4)); // GDEH0154D67

Vous pouvez également utiliser les broches des exemples, mais vous devez alors changer les connexions sur le matériel. En y regardant de plus près, vous verrez également que la différence entre ESP32 et ESP8266 n'est que la répartition des broches.

Si vous utilisez un des écrans à trois couleurs, vous devez regarder plus bas pour trouver une telle ligne :

GxEPD2_3C<GxEPD2_154c, GxEPD2_154c::HEIGHT> display(GxEPD2_154c(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4));

Vous devez alors inclure cette bibliothèque pour cela, comme cela est également fait dans le GxEPD2_Exemple.

#include <GxEPD2_3C.h>

Je n'avais pas besoin de cela dans mon code source. Le développeur donne un autre indice important pour l'utilisation de la ESP8266, qui pourrait être important pour vous dans la suite de cet article :

NOTE pour ESP8266 : L'utilisation de SS (GPIO15) pour CS peut causer des problèmes de mode de démarrage, utilisez une broche différente au cas où.

Traduit, cela signifie que la broche CS numéro 15 peut éventuellement entraîner des problèmes de démarrage et que vous devez alors passer à une autre broche.

Afficher ESP32 et ses propres images

La connexion au microcontrôleur ESP32 NodeMCU ressemble à ceci:

EPD Pins ESP32 GPIO
Beschäftigt 27
RST 33
DC 25
CS 26
CLK SCK = 18
DIN MOSI = 23
GND GND
3.3V 3.3V

SCK et MOSI sont prédéfinis par le microcontrôleur. Sur la ESP32, il s'agit de la broche 18 pour SCK et de la broche 23 pour MOSI. Regardez dans le brochage de votre microcontrôleur. Faites attention à la différence entre le numéro GPIO et le numéro imprimé sur le tableau. Busy, RST, DC et CS peuvent être choisis librement (faites attention aux notes de la section précédente).


Remarque: évitez d'utiliser la broche GND à côté de la broche 5V (en bas à gauche sur l'image). Pour plus d'informations, veuillez vous référer à la vue d'ensemble du pinout et à la fiche technique.

Je suppose que les bibliothèques EPD et GxEPD2 de la première partie de cette série de blogs sont installées. Vous aurez également besoin de ma bibliothèque EPD alternative V2 pour l'affichage plus récent.

Créer des images

Nous voulons maintenant montrer notre propre image sur l'écran. J'ai décrit dans la première partie comment charger les données d'image dans le tampon d'image sous la forme d'un tableau de caractères. Nous devons donc extraire les données de l'image souhaitée et les copier dans le tableau. D'abord, trouvons une image. Je vais utiliser le logo de AZ Delivery :

Comme l'affichage est de format carré, l'image doit également être carrée. Pour extraire les données d'image, Waveshare recommande l'outil image2lcd. J'ai trouvé un outil en ligne via Github qui fonctionne aussi très bien. Le fabricant d'écrans Waveshare montre sur son site web comment vous pouvez convertir vos propres images avec un programme graphique.

J'utilise l'outil en ligne ici. À l'étape 1, le fichier image est sélectionné, à l'étape 2, les paramètres peuvent être laissés tels quels. Dans l'aperçu de l'étape 3, l'image devrait maintenant apparaître en noir et blanc. À l'étape 4, nous avons réglé le format de sortie du code sur "Arduino Code". L'identifiant peut être choisi librement par vous. C'est le nom du tableau de données d'images qui suit. Dans notre cas, cela n'est pas pertinent, car nous n'avons besoin que du contenu. Le réseau existe déjà et nous voulons continuer à l'utiliser. Nous réglons le mode de dessin sur Horizontal - 1 bit par pixel et générons le code en cliquant sur le bouton correspondant.

1.54" Display V1

Nous ouvrons l'IDE Arduino et dans celui-ci, à partir de la bibliothèque EPD, nous ouvrons l'exemple EPD1in54ShowRunningTime. Ce sera notre modèle. Nous changeons à nouveau les lignes 43 et 44 :

// EPD1in54 epd; // default reset: 8, dc: 9, cs: 10, busy: 7
EPD1in54 epd(33, 25, 26, 27); // reset, dc, cs, busy

Dans l'exemple, le texte et les symboles géométriques sont affichés en premier, suivis d'un graphique en taille réelle et ensuite de l'affichage de l'heure. Nous commentons les lignes qui ne sont pas nécessaires, ou nous les supprimons simplement. Les lignes 70 à 116 sont la partie qui génère le texte et les symboles et ne sont donc pas nécessaires.


La mesure du temps à la ligne 122 n'est pas non plus nécessaire. Nous supprimons le contenu de la fonction loop() ainsi que la fonction updateTime() complète. Nous sauvons le projet sous un nouveau nom. Les fichiers imagedata.h et .cpp doivent être sauvegardés automatiquement. Le code source semble maintenant raccourci comme suit:

#include <SPI.h>
#include <EPD1in54.h>
#include <EPDPaint.h>
#include "imagedata.h"

#define COLORED 0
#define UNCOLORED 1

unsigned char image[1024];
EPDPaint paint(image, 0, 0); // width should be the multiple of 8

// Die Zeile fuer das gewuenschte Board einkommentieren
// ****************************************************
//
// ESP32:
EPD1in54 epd(33, 25, 26, 27); // reset, dc, cs, busy

// ESP8266:
// EPD1in54 epd(5, 0, SS, 4); // reset, dc, cs, busy


void setup() {
Serial.begin(115200);
if (epd.init(lutFullUpdate) != 0) {
Serial.print("e-Paper init failed");
return;
}

epd.clearFrameMemory(0xFF); // bit set = white, bit reset = black
epd.displayFrame();
epd.clearFrameMemory(0xFF); // bit set = white, bit reset = black
epd.displayFrame();

paint.setRotate(ROTATE_0);

// Demo-Bild
epd.setFrameMemory(IMAGE_DATA);
epd.displayFrame();
}

void loop() {}

Nous copions maintenant à partir de l'outil en ligne le code source généré qui se trouve entre les parenthèses.


Dans l'IDE Arduino, l'onglet pour les imagedata.h / .cpp devrait être disponible dans la partie supérieure de la fenêtre du programme :


Note
: Les fichiers images ont été déplacés vers des fichiers externes, car ils contiennent une quantité relativement importante de code source. Ces fichiers doivent se trouver dans le même dossier. Le fichier .h est inclus entre guillemets. Cela permet de faire connaître le .cpp associé. Son contenu peut ensuite être utilisé dans notre programme. Dans ce cas, sous la forme de tableaux de données d'images. Lorsque vous ouvrez le projet dans l'IDE Arduino, les onglets doivent apparaître comme indiqué dans l'image ci-dessus. De la même manière, vous pouvez échanger des fonctions, des méthodes ou des procédures et les réutiliser dans d'autres programmes.

Nous sélectionnons le fichier imagedata.cpp et nous insérons nos nouvelles données d'image provenant de l'outil en ligne dans le tableau IMAGE_DATA entre les parenthèses.
Une autre possibilité consiste à créer un nouveau tableau.

Pour ce faire, copiez le code source complet précédemment généré à partir de la page web (CTRL + A puis CTRL + C) et collez-le dans le fichier imagedata.cpp à la fin. Voici à quoi ressemble un exemple abrégé :

// 'AZ-Logo', 200x200px
Konst nicht unterzeichnet Char AZLogo[] PROGMEM = {
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  ...
  ...
  ...
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

Les imagedata.h le tableau seront déclaré. Pour ce faire, vous copiez simplement la ligne qui se trouve déjà là et ne modifiez que le nom:

extern const unsigned char AZLogo[];

S'ils ont choisi l'image supplémentaire, nous ajoutons les lignes suivantes à la fin de la fonction setup() :

delay(2000);

epd.clearFrameMemory(0xFF); // bit set = white, bit reset = black
epd.displayFrame();
epd.clearFrameMemory(0xFF); // bit set = white, bit reset = black
epd.displayFrame();

// Eigenes Bild
epd.setFrameMemory(AZLogo);
epd.displayFrame();

Lorsque vous compilez le programme et le chargez sur l'ESP32, l'écran doit afficher l'image que vous utilisez.

Le logo que j'ai utilisé ne comporte que deux couleurs et peu de détails. C'est très bien de l'afficher sur un écran bicolore. Toutefois, si vous souhaitez utiliser des photos avec plus de détails, vous devrez peut-être procéder à quelques ajustements. La plupart du temps, il suffit de modifier le contraste et la luminosité. Pour ce faire, vous pouvez modifier la valeur de "Luminosité / seuil alpha" sur le site web mentionné ci-dessus au point 2. Si cela ne suffit pas, il faut recourir à un programme graphique.

ESP8266 D1 Mini

Le brochage de la ESP8266 est légèrement différent de celui de la ESP32. Nous utilisons les numéros GPIO, indiqués en turquoise dans l'image suivante :


Nous connectons les fils du D1 Mini à l'EPD selon le schéma suivant (l'étiquette avec le D à côté est l'étiquette imprimée sur le microcontrôleur, les numéros GPIO sont ceux que j'utilise dans l'IDE Arduino):

EPD Pins ESP2866 Knoten MCU D1 Mini GPIO
Beschäftigt D2 (GPIO 4)
RST D1 (GPIO 5)
DC D3 (GPIO 0)
CS D8 (GPIO15, SS)
CLK D5 (SCK)
DIN D7 (MOSI)
GND GND
3.3V 3.3V

Dans l'IDE Arduino sous l'élément de menu "Outils", nous changeons la carte soit en NodeMCU 1.0 (modules ESP-12E) soit Wemos D1 R1.

Maintenant, nous commentons dans la ligne appropriée du code source :

// ESP32:
// EPD1in54 epd(33, 25, 26, 27); // reset, dc, cs, busy

// ESP8266:
EPD1in54 epd(5, 0, SS, 4); // reset, dc, cs, busy

Vous pouvez aussi simplement changer les numéros de code. Je l'ai un peu simplifié ici. Vous n'avez besoin de rien de plus que de différents numéros d'identification.
Si nous téléchargeons le programme, l'image que nous avons sélectionnée devrait apparaître à nouveau.

Téléchargement du programme complet: image appartenant à EPDE ESP32ESP8266_V1

Le passage de ESP32 à ESP8266 est relativement simple. Si vous avez trouvé les bonnes broches, les avez connectées et les avez modifiées dans le code source, l'affichage fonctionne comme d'habitude. Les autres exemples de la partie 1 peuvent également être exécutés avec le D1 Mini.

1.54" Display V2 sur ESP32

Nous allons maintenant connecter la nouvelle version de l'écran et y afficher les mêmes images. Le brochage reste le même. J'utilise d'abord la bibliothèque EPD modifiée de Waveshare.


Dans la première section de ce post, je vous ai montré comment télécharger le programme type. Nous utilisons cet exemple comme source. Nous supprimons également ici les variables de timing et presque toutes les lignes de la configuration(). Le code source qui reste maintenant est très clair :

#include <SPI.h>
#include "epd1in54_V2.h"
#include "epdpaint.h"
#include "imagedata.h"

#define COLORED 0
#define UNCOLORED 1

unsigned char image[1024];
Paint paint(image, 0, 0); // width should be the multiple of 8

// Die Zeile fuer das gewuenschte Board einkommentieren
// ****************************************************
//
// ESP32:
Epd epd(33, 25, 26, 27); // my Pins ESP32 (Reset, DC, CS, Busy)
//
// ESP8266:
// Epd epd(5, 0, SS, 4); // my Pins ESP8266 (Reset, DC, CS, Busy)

void setup() {
Serial.begin(115200);
Serial.print(epd.HDirInit());
epd.HDirInit();

// Demo-Bild
epd.Display(IMAGE_DATA);

delay(2000);

// Eigenes Bild
epd.Display(AZLogo);
}

void loop() {}

C'est la même procédure que dans le programme pour l'ancien affichage.

1,54" Display V2 sur ESP8266

Pour le D1 Mini, nous commentons simplement dans une autre ligne en conséquence, où nous initialisons l'affichage :

Epd epd(5, 0, SS, 4); // my Pins ESP8266 (D1, D3, D8, D2)

Ensuite, bien sûr, nous changeons le tableau dans l'EDI Arduino sous Outils et nous téléchargeons le programme. Là encore, l'image de démonstration est affichée en premier et, après une pause de deux secondes, le logo AZ.

Télécharger le programme complet : EPDEigenesBildESP32ESP8266_V2

Comparaison avec la bibliothèque du GxEPD2

#include <GxEPD2_BW.h>
#include "imagedata.h"

// Die Zeile fuer das gewuenschte Board einkommentieren
// ****************************************************
//
// 1,54" 200x200 V1 (old):
// -----------------------
// ESP32:
// GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(26, 25, 33, 27)); // CS, DC, RST, Busy //GDEP015OC1 no longer available
// ESP8266:
// GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(SS, 0, 5, 4)); //CS, DC, RST, BUSY //GDEP015OC1 no longer available
//
// 1,54" 200x200 V2 (new):
// -----------------------
// ESP32:
// GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(26, 25, 33, 27)); // CS, DC, RST, Busy // GDEH0154D67
// ESP8266:
// GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(SS, 0, 5, 4)); // CS, DC, RST, Busy // GDEH0154D67


void setup() {
display.init();
display.setRotation(0);
display.setFullWindow();

// Demo-Bild
display.fillScreen(GxEPD_BLACK);
display.drawBitmap(0, 0, IMAGE_DATA, 200, 200, GxEPD_WHITE);
while (display.nextPage());

delay(2000);

// Eigenes Bild
display.fillScreen(GxEPD_BLACK);
display.drawBitmap(0, 0, AZLogo, 200, 200, GxEPD_WHITE);
while (display.nextPage());
}

void loop() {}

J'ai remplacé les données d'image par des fichiers séparés, équivalents à l'exemple précédent avec la bibliothèque EPD. Vous devez commenter ici la ligne qui correspond à votre configuration. Affichage V1 sur ESP32 ou ESP8266 ou Affichage V2 sur ESP32 ou ESP8266.

Téléchargement du programme complet : GxEPD2EigenesBildESP32ESP8266V1und_V2

Afficher les données des capteurs

Ensuite, nous voulons montrer des données réelles sur l'écran. J'ai choisi le capteur de température DHT11 pour cela. J'utilise toujours le D1 Mini et pour l'instant la bibliothèque EPD pour le Display V1. Nous connectons le capteur comme suit :
DHT11 Pins ESP2866 D1 Mini GPIO
S (DATA) D0 (GPIO 16)
DNB DNB
VCC 5V

Dans la gestion de la bibliothèque, vous devez installer une bibliothèque appropriée. J'utilise la "bibliothèque de capteurs DHT pour ESPx de beegee_tokyo". 

Pour la température et l'humidité, nous déclarons quatre variables :

float temperatur = 0.0;
float temperatur_old = 0.0;
float humidity = 0.0;
float humidity_old = 0.0;

Il y en a deux de chaque type, car nous voulons comparer les anciennes et les nouvelles données plus tard. Cela nous donne la possibilité de mettre à jour l'affichage uniquement lorsque les valeurs ont changé. Une autre possibilité serait de fixer une période de temps après laquelle le capteur est lu et l'affichage est mis à jour.

La ligne suivante crée une instance d'objet DHT :

DHTesp dht;

Dans le setup(), le capteur de température doit maintenant être initialisé. J'utilise un capteur DHT11 à la broche D0. Dans le graphique ci-dessus, vous pouvez voir que le numéro GPIO correspondant est le 16. C'est ici qu'on l'inscrit.

dht.setup(16, DHTesp::DHT11);

Ma séquence de programme consiste maintenant à effacer l'écran, puis à afficher le logo AZ. Ensuite, l'affichage doit être supprimé à nouveau. Ensuite, une image de fond que j'ai créée est affichée. Ensuite, les valeurs de l'humidité et de la température sont affichées. Elles sont mises à jour dès qu'elles changent. L'écran entier ne doit pas être mis à jour, mais seulement les nouvelles données.

J'ai converti l'image en données d'image à l'aide de l'outil en ligne, je l'ai ajoutée à imagedata.cpp/.h et je l'ai nommée "Background" :

imagedata.cpp (extrait):

// 'Background', 200x200px
Konst nicht unterzeichnet Char Hintergrund [] PROGMEM = {
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ...

imagedata.h:

/**
 *  @filename: imagedata.h
 *  @brief: Kopfdatei für imagedata.cpp
*/

extern const unsigned char Background[];
extern const unsigned char AZLogo[];

/* FILE
FIN */

Les loop()-La fonction est maintenant complétée par la lecture du capteur:

void loop() {
temperatur = dht.getTemperature();
humidity = dht.getHumidity();

if (temperatur != temperatur_old) {
temperatur_old = temperatur;
updateTemp(temperatur);
}

if (humidity != humidity_old) {
humidity_old = humidity;
updateHum(humidity);
}
}

En fonction de la modification d'une des valeurs, une fonction associée est appelée. J'ai décidé d'utiliser la fonction updateTime() de l'exemple EPD1in54ShowRunningTime comme modèle et d'en créer deux nouvelles fonctions pour la température et l'humidité.


Les deux valeurs doivent être examinées séparément et également mises à jour séparément sur l'écran. En fonction de la valeur qui a changé. Ensuite, seule une petite fenêtre (zone partielle) est modifiée dans l'affichage, ou deux pour les valeurs respectives. L'image de fond reste et n'est pas réécrite. Cela permet d'économiser de l'énergie et d'être un peu plus rapide. Voici le code source de l'ancien affichage V1 :

void updateTemp(float temperatur) {
char temp_string[] = {'0', '0', '\0'};
dtostrf(temperatur, 2, 0, temp_string);

paint.setWidth(30);
paint.setHeight(21);

paint.clear(UNCOLORED);
paint.drawStringAt(2, 2, temp_string, &Font24, COLORED);
epd.setFrameMemory(paint.getImage(), 30, 159, paint.getWidth(), paint.getHeight());
epd.displayFrame();
epd.setFrameMemory(paint.getImage(), 30, 159, paint.getWidth(), paint.getHeight());
epd.displayFrame();
}

void updateHum(float humidity) {
char temp_string[] = {'0', '0', '\0'};
dtostrf(humidity, 2, 0, temp_string);

paint.setWidth(30);
paint.setHeight(21);

paint.clear(UNCOLORED);
paint.drawStringAt(2, 2, temp_string, &Font24, COLORED);
epd.setFrameMemory(paint.getImage(), 30, 93, paint.getWidth(), paint.getHeight());
epd.displayFrame();
epd.setFrameMemory(paint.getImage(), 30, 93, paint.getWidth(), paint.getHeight());
epd.displayFrame();
}

Les fonctions sont chacune transmises aux données du capteur. Un tableau de caractères est créé, qui est rempli de 0. Ensuite, les données du capteur sont écrites dans le tableau. Dans le processus, les chiffres sont convertis en caractères.


La fonction dtostrf() de conversion peut également écrire des décimales dans le tableau. J'ai choisi d'omettre les décimales parce que le DHT11, contrairement aux autres capteurs, ne fournit pas de décimales (bien que le type de données flottantes le permette). Si vous utilisez un autre capteur, vous aurez la possibilité d'afficher les décimales à ce stade. Pour ce faire, modifiez le deuxième paramètre et spécifiez la longueur totale de la valeur, y compris le point décimal.


Comme troisième paramètre, entrez le nombre de décimales. Dans mon cas, les nombres ont deux chiffres et pas de décimale. Le 2 et le 0 en sont la preuve.

Les dimensions des fenêtres à mettre à jour sont saisies dans l'objet peinture. Il faut essayer un peu jusqu'à ce que tout soit au bon endroit. Cela devient un peu plus facile si vous réglez la couleur sur le noir. Vous pouvez alors voir où se trouve la fenêtre correspondante et la positionner au mieux. Ces zones sont ensuite écrasées par une seule couleur. Ensuite, la chaîne correspondante est générée sous forme de texte, écrite dans la mémoire tampon d'affichage et sortie à la fin.

Les deux fonctions peuvent bien sûr être combinées en une seule afin d'éviter les redondances et de réduire un peu plus le code source. Mais je n'entrerai pas dans le vif du sujet ici et je ne le laisserai pas comme il est.

Si nous chargeons le programme sur le D1-Mini, le logo s'affiche d'abord, puis les valeurs du capteur devraient apparaître. En fonction de la modification de l'une des deux valeurs, elle sera mise à jour sur l'écran.

Deux choses sont immédiatement visibles sur l'image. Tout d'abord, le D1-Mini est sans alimentation électrique et l'écran affiche toujours les dernières valeurs. Deuxièmement, il est actuellement assez chaud.

Pour utiliser le programme avec l'ESP32, il suffit de changer à nouveau les numéros de pin, ou simplement de commenter la ligne correspondante :

// Die Zeile fuer das gewuenschte Board einkommentieren
// ****************************************************
//
// ESP32:
EPD1in54 epd(33, 25, 26, 27); // reset, dc, cs, busy
//
// ESP8266:
// EPD1in54 epd(5, 0, SS, 4); // reset, dc, cs, busy

Vous devrez peut-être changer la broche d'entrée du capteur de température dans setup() si votre carte ESP32 n'a pas de broche portant le numéro 16.

dht.setup(16, DHTesp::DHT11); // Pin D0 / GPIO16

Téléchargement du programme complet: EPDESP32ESP8266V1DHT11

Nous voulons maintenant mettre en œuvre la même chose avec le nouvel affichage V2. Nous revenons à l'exemple de epd1in54_V2. Le code source est relativement similaire à l'ancien affichage. Les noms des fonctions ne diffèrent que légèrement. Les processus sont les mêmes.

Comme nous mettons à jour les données de température sur l'écran dès qu'elles changent, vous devez faire un rafraîchissement partiel. Cela permet de rafraîchir l'affichage avec les nouvelles valeurs à l'endroit où se trouvent les chiffres. C'était également le cas dans l'ancienne version. Dans la nouvelle version de la bibliothèque, vous devez charger l'image de fond statique avec DisplayPartBaseImage(). Les données de température sont affichées avec DisplayPartFrame() au lieu de DisplayFrame().

Testez le programme vous-même:

Téléchargement du programme complet: EPDESP32ESP8266V2DHT11

Résumé intermédiaire

Après plusieurs tests, j'ai dû déterminer que la bibliothèque pour le nouvel affichage ne fonctionne malheureusement pas comme l'ancienne version. Cela m'a amené à constater, lors de mes tests, que l'image était seulement très pâle à voir. Ce n'est qu'après plusieurs mises à jour de la température que l'image de fond s'est également affichée de plus en plus saturée.


Le bord extérieur de l'écran vibre légèrement, même si rien n'est mis à jour. Je n'en suis donc pas vraiment satisfait. Je n'ai pas non plus trouvé d'autres informations sur ce comportement dans les wikis du fabricant. Cependant, cela n'affecte que le rafraîchissement partiel de l'affichage. La sortie normale du contenu en plein écran semblait normale. Peut-être que je n'utilise pas correctement les exécutions des fonctions. Malheureusement, toute la bibliothèque n'est pas bien documentée. À l'exception de quelques conseils sur le site web de Waveshare, vous ne trouverez malheureusement aucune approche.

Encore une fois avec le GxEPD2

Il se cristallise si lentement qu'il est logique d'utiliser cette bibliothèque. Il est très étendu, est actuellement en cours de développement et d'adaptation aux écrans. Je voudrais maintenant mettre en œuvre l'exemple précédent avec cette bibliothèque alternative.
Pour cela, nous fusionnons les codes sources des programmes que nous avons déjà écrits. Nous obtenons le déroulement du programme pour la mesure de la température à partir des croquis précédents dans lesquels nous avons utilisé les autres bibliothèques. Pour la sortie sur l'écran, nous utilisons alors le programme que nous utilisions autrefois pour afficher nos propres images. Nous incluons les bibliothèques suivantes :

#include <GxEPD2_BW.h>
#include <Fonts/FreeSans12pt7b.h>
#include "imagedata.h"
#include "DHTesp.h"

Dans la partie suivante du programme, vous pouvez à nouveau choisir entre l'affichage V1 ou V2, et les processeurs ESP32 ou ESP8266. Commentez la ligne correcte pour cela. Ensuite, faites à nouveau attention au câblage des broches. Ensuite, nous déclarons à nouveau les variables pour la température et l'humidité et une instance d'objet DHTesp.

float temperatur = 0.0;
float temperatur_old = 0.0;
float humidity = 0.0;
float humidity_old = 0.0;

DHTesp dht;

Dans setup(), nous initialisons le capteur de température puis l'affichage. D'abord le logo AZ est affiché et après une courte pause l'image de fond que je vous ai montrée précédemment :

void setup() {
// Serial.begin(115200);
dht.setup(16, DHTesp::DHT11); // Pin D0 / GPIO16
display.init();
display.setRotation(0);
display.setFullWindow();

// AZLogo
display.fillScreen(GxEPD_BLACK);
display.drawBitmap(0, 0, AZLogo, 200, 200, GxEPD_WHITE);
while (display.nextPage());

delay(2000);


 // Background
display.fillScreen(GxEPD_BLACK);
display.drawBitmap(0, 0, Background, 200, 200, GxEPD_WHITE);
while (display.nextPage());

}

Nous pouvons prendre la fonction loop() complètement telle quelle. Je n'ai fait que dupliquer les appels pour la sortie. Il se trouve que les valeurs n'étaient pas affichées correctement. C'est mon contournement :

void loop() {
temperatur = dht.getTemperature();
humidity = dht.getHumidity();

if (temperatur != temperatur_old) {
temperatur_old = temperatur;
updateTemp(temperatur);
updateTemp(temperatur);
}


 if (humidity != humidity_old) {
humidity_old = humidity;
updateHum(humidity);
updateHum(humidity);
}
}

Dans les deux fonctions updateTemp() et updateHum(), la sortie sur l'écran doit être remplacée :

void updateTemp(float temperatur) {
char temp_string[] = {'0', '0', '\0'};
int16_t tbx, tby;
uint16_t tbw, tbh;

dtostrf(temperatur, 2, 0, temp_string);

uint16_t x = 30;
uint16_t y = 178;
display.getTextBounds(temp_string, x, y, &tbx, &tby, &tbw, &tbh);
display.setFont(&FreeSans12pt7b);
display.setTextColor(GxEPD_BLACK);
display.setPartialWindow(tbx, tby, tbw, tbh);
display.firstPage();
do {
display.fillScreen(GxEPD_WHITE);
display.setCursor(x, y);
display.print(temp_string);
} while (display.nextPage());
}

void updateHum(float humidity) {
char temp_string[] = {'0', '0', '\0'};
int16_t tbx, tby;
uint16_t tbw, tbh;

dtostrf(humidity, 2, 0, temp_string);

uint16_t x = 30;
uint16_t y = 112;
display.getTextBounds(temp_string, x, y, &tbx, &tby, &tbw, &tbh);
display.setFont(&FreeSans12pt7b);
display.setTextColor(GxEPD_BLACK);
display.setPartialWindow(tbx, tby, tbw, tbh);
display.firstPage();
do {
display.fillScreen(GxEPD_WHITE);
display.setCursor(x, y);
display.print(temp_string);
} while (display.nextPage());
}

Les variables tbx, tby, tbw et tbh sont remplies avec les valeurs que la fenêtre partielle occupera. L'abréviation "tb" signifie "text boundary". Je vous avais déjà présenté la fonction dtostr().

(Il montre également une manière différente dans l'exemple GxEPD2_. À cette fin, la fonction helloValue() sert.)

Les variables x et y sont le point d'angle de notre fenêtre de sortie. Notez ici qu'il ne s'agit pas du coin supérieur gauche, mais de la ligne de base du texte. Vous trouverez des informations à ce sujet dans le manuel de la bibliothèque Adafruit_GFX, dans la section "Utilisation des polices GFX dans les croquis Arduino".


L'appel de fonction getTextBounds() provient également de cette bibliothèque. On lui transmet la chaîne à sortir et les coordonnées où elle doit être affichée. Les quatre autres paramètres sont les variables limites du texte mentionnées plus haut. Ils ne servent pas de paramètres de passage, mais sont utilisés pour faire connaître la mémoire dans laquelle sont stockés les résultats de la fonction. Il s'agit de quasi quatre valeurs de retour d'une fonction.


L'utilisation des valeurs peut être un peu troublante. En effet, c'est la ligne de base, et non le coin supérieur gauche, qui constitue le point de référence du texte à produire. L'image suivante doit illustrer la signification de ce terme :

Nous précisons avec x et y où le texte doit être situé. La fonction getTextBounds() calcule maintenant à partir du texte la taille de la fenêtre à modifier, dans laquelle le texte est affiché. Les valeurs tbx et tby représentent alors le coin supérieur gauche de la fenêtre calculée. Pour la largeur et la hauteur, on utilise tbw et tbh.

Les lignes suivantes sont probablement explicites. La police de caractères est définie, puis la couleur du texte (bien sûr, nous n'avons le choix qu'entre le noir et le blanc). Avec setPartialWindow(tbx, tby, tbw, tbh), nous définissons ensuite la zone qui changera par la suite. Ici, les coordonnées tbx et tby sont pour le coin supérieur gauche, pas pour la ligne de base.

La dernière chose à faire est de remplir la fenêtre avec une couleur et de placer le curseur, c'est-à-dire le début du texte, aux coordonnées x et y. Là encore, c'est la ligne de base. Ensuite, le texte est écrit.

La police doit être incluse dans un fichier d'en-tête (voir ci-dessus). Vous trouverez ici un aperçu des polices incluses. Si vous avez besoin d'autres tailles ou types de polices, vous pouvez le faire avec ce convertisseur de polices en ligne, qui produit des fichiers d'en-tête prêts à l'emploi. Vous devez les copier dans le dossier des polices de la bibliothèque. Je vous ai déjà dit comment trouver la bibliothèque. Cherchez dans le dossier "libraries" le dossier GxEPD2 et là les polices du dossier.

Un résumé de toutes les fonctions de l'ApafruitGFX finden Sie [hier](http://adafruit.github.io/Adafruit-GFX-Library/html/classAdapruit__gf_x.html). La bibliothèque GxEPD2 est un outil très puissant pour l'affichage sur écrans en conjonction avec la bibliothèque GFX.

Lorsque vous chargez le programme sur le microcontrôleur, le même affichage doit apparaître qu'auparavant avec l'autre croquis.

Téléchargement du programme complet: GxEPD2ESP32ESP8266V1etV2DHT11

J'ai résumé les deux fonctions pour la température et l'humidité, raccourcissant ainsi un peu le code source:

Téléchargement du programme complet: GxEPD2ESP32ESP8266V1etV2DHT11_B

Données WLAN

Nous en arrivons maintenant au dernier point que j'ai annoncé. Avec l'ESP32 et aussi l'ESP8266, il est possible de se connecter à un réseau WLAN. Essayons d'abord d'afficher les données du réseau sur le Serial Monitor. Ensuite, nous veillons à ce que ces données apparaissent sur l'écran de l'E-Paper.

Je veux me connecter à mon WLAN, puis afficher mon IP, le nom du réseau (SSID), le canal utilisé et la puissance du signal (en dBm).

Recommençons avec l'affichage V1. Nous incluons la bibliothèque ESP8266WiFi.h ou WiFi.h, selon la carte que vous utilisez. Dans setup(), nous initialisons la connexion via WLAN :

#if defined(ESP8266)
#include
#elif défini(ESP32)
#include
#endif

void setup() {
Serial.begin(115200);
WiFi.begin("IHRE SSID", "IHR WLAN KEY"); // SSID, KEY
Serial.print("Verbinde");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Verbunden, IP-Adresse: ");
Serial.println(WiFi.localIP());
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("Kanal: ");
Serial.println(WiFi.channel());
Serial.print("Signalstaerke: ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");}

void loop() {

}

Pour le SSID et le KEY, veuillez saisir vos propres données avant de charger le programme sur votre microcontrôleur. Si tout fonctionne, vous devriez voir l'adresse IP, le SSID, le canal et la force du signal dans le moniteur série.

Nous voulons maintenant insérer ce code dans le programme que nous avons utilisé pour l'affichage de l'e-paper. Nous supprimons la deuxième image de fond et remplaçons les données climatiques par les données WLAN. Nous pouvons supprimer les deux fonctions de température et d'humidité. 


La boucle() peut également être laissée vide, puisqu'il suffit de récupérer les données une seule fois. Je continue à utiliser la bibliothèque de l'EPD. Dans l'exemple EPD1in54ShowRunningTime, nous pouvons prendre le code source pour l'affichage du texte dans le setup(). Pour la sortie du texte, nous avons besoin d'un tableau de caractères comme tampon pour certaines données. Nous le déclarons au niveau mondial :

char tempString [] = {'0', '0', '0', '\0'};

Dans le setup(), vous devriez maintenant avoir inséré l'initialisation du réseau WLAN comme je l'ai montré dans l'exemple précédent. Ensuite, l'affichage est initialisé et le logo AZ est édité. Ensuite, nous affichons sur l'EPD les mêmes données que dans le moniteur en série :

paint.setRotate (ROTATE_ 0) ;
paint.setWidth (200);
paint.setHeight (18);
 
paint.clear (COLORED) ;
paint.drawStringAt (0, 2, "WIFI connecté:", &Font16, UNCOLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 0, paint.getWidth (), paint.getHeight ()) ;
  
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, "Adresse IP:", &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 20, paint.getWidth (), paint.getHeight ()) ;
 
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, WiFi.localIP ().toString ().c_str (), &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 40, paint.getWidth (), paint.getHeight ()) ;
 
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, "SSID:", &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 60, paint.getWidth (), paint.getHeight ()) ;
 
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, WiFi.SSID ().c_str (), &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 80, paint.getWidth (), paint.getHeight ()) ;
 
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, "Canal:", &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 100, paint.getWidth (), paint.getHeight ()) ;
 
dtostrf (WiFi.channel (), 2, 0, tempString) ;
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, tempString, &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 120, paint.getWidth (), paint.getHeight ()) ;
 
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, "Pile de signaux:", &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 140, paint.getWidth (), paint.getHeight ()) ;
 
String signalString = String (WiFi.RSSI ()) + "dBm";
paint.clear (UNCOLORED) ;
paint.drawStringAt (0, 2, signalString.c_str (), &Font16, COLORED) ;
epd.setFrameMemory (paint.getImage (), 0, 160, paint.getWidth (), paint.getHeight ()) ;
 
epd.displayFrame () ;

L'adresse IP peut être renvoyée sous forme de chaîne avec .toString(). Cependant, la fonction drawStringAt() attend un tableau de caractères. Nous ajoutons donc .c_str() à la fin. Ensuite, ça marche. Le SSID est déjà renvoyé sous forme de chaîne. Nous le convertissons également en un tableau de caractères. Pour le canal, nous utilisons à nouveau la fonction dtostrf(), qui a déjà été utilisée pour les données de température. Pour cela, le tableau de caractères précédemment déclaré, que nous avons créé comme tampon, est également nécessaire.

J'ai réécrit le code source afin que vous puissiez voir à votre écran si la connexion WLAN a été établie ou pas. Pour la puissance du signal, j'ai mis en place une autre possibilité de produire des chiffres et du texte. Comme nous voulons ajouter l'unité de mesure dBm à la valeur, j'ai utilisé la classe String et la fonction de conversion String(). Nous pouvons alors facilement enchaîner deux séquences et passer le résultat avec .c_str() à drawStringAt().

Lorsque vous chargez le programme sur le D1 Mini, l'écran doit d'abord afficher le logo AZ, puis les données de votre réseau WLAN. Les mêmes informations sont également affichées dans le Serial Monitor.

Téléchargement du programme complet: EPDESP8266WifiData_V1

Maintenant, vous pouvez aussi écrire la sortie dans la fonction loop(), si la puissance du signal change et que vous voulez avoir ces informations toujours à jour. Le code source pour la sortie des lignes de texte pourrait être raccourci pour éviter le code redondant.

Par souci d'exhaustivité, nous avons réécrit le programme pour l'affichage V2. Nous faisons les mêmes changements que pour le projet DHT11. Nous modifions les includes des bibliothèques. Remarquez les guillemets, au lieu des crochets :

#include "epd1in54_V2.h"
#include "epdpaint.h"

Ensuite, la classe doit être renommée :

// ESP8266:
Epd epd (5, 0, SS, 4); // reset, dc, cs, busy

Nous modifions également l'initialisation de l'affichage, ainsi que l'effacement de l'affichage et la sortie du logo AZ :

epd.HDirInit () ;
epd.Clear () ;
epd.Display (AZLogo) ;
delay (2000);
epd.Clear () ;

Outre les modifications des noms de fonctions déjà mentionnées, nous devons également modifier le positionnement :

paint.DrawStringAt (0, 2, "WIFI connecté:", &Font16, UNCOLORED) ;
epd.SetFrameMemory (paint.GetImage (), 0, 0, paint.GetWidth (), paint.GetHeight ()) ;

devient:

paint.DrawStringAt (0, 2, "WIFI connecté:", &Font16, UNCOLORED) ;
epd.SetFrameMemory (paint.GetImage (), 0, 180, paint.GetWidth (), paint.GetHeight ()) ;

Toutes les positions y ont maintenant des valeurs par pas de 20 vers le bas, au lieu de vers le haut.

Remarque : j'ai remarqué que rien ne peut être affiché au-dessus d'une valeur y de 180. C'est pourquoi l'affichage complet a été déplacé d'une ligne vers le bas. Si vous voulez utiliser l'écran complet, la dernière ligne est coupée.

Téléchargement du programme complet: EPDESP8266WifiData_V2

Enfin, nous allons maintenant réécrire ceci pour la bibliothèque GxEPD2. Nous remplaçons les inlcudes :

#include
#include <Fonts/FreeSans9pt7b.h>
#include "imagedata.h"

Et supprimer toutes les lignes qui appartiennent à la classe epd.


Nous définissons les initialisations pour les classes d'affichage :

// Commenter la ligne pour le tableau en fonction de la pondération
// ****************************************************
//
/ / 1,54 " 200x200 V1 (old):
// -----------------------
// ESP32:
// GxEPD2_BW <GxEPD2_154, GxEPD2_154: :HEIGHT> display (GxEPD2_154 (26, 25, 33, 27)) ; // CS, DC, RST, Busy // GDEP015OC1 non ionger available
// ESP8266:
// GxEPD2_BW <GxEPD2_154, GxEPD2_154: :HEIGHT> display (GxEPD2_154 (SS, 0, 5, 4)) ; // CS, DC, RST, BUSY // GDEP015OC1 no longer available
//
/ / 1,54 " 200x200 V2 (new):
// -----------------------
// ESP32:
GxEPD2_BW <GxEPD2_154_D67, GxEPD2_154_D67: :HEIGHT> display (GxEPD2_154_D67 (26, 25, 33, 27)); // CS, DC, RST, Busy // GDEH0154D67
// ESP8266:
// GxEPD2_BW <GxEPD2_154_D67, GxEPD2_154_D67: :HEIGHT> display (GxEPD2_154_D67 (SS, 0, 5, 4)) ; // CS, DC, RST, Busy // GDEH0154D67

Ensuite, nous remplaçons l'initialisation de l'affichage dans setup() et reprenons la sortie du logo AZ du programme GxEPD pour l'affichage de notre propre image :

display.init () ;
display.setRotation (0);
display.setFullWindow () ;

// AZLogo
display.fillScreen (GxEPD_BLACK) ;
display.drawBitmap (0, 0, AZLogo, 200, 200, GxEPD_WHITE) ;
while (display.nextPage ()) ;

delay (2000);
display.fillScreen (GxEPD_WHITE) ;
while (display.nextPage ()) ;

La bibliothèque GxEPD2 offre la possibilité de sortir des textes de la même manière que vous êtes habitués à le faire à partir du moniteur de série. Tout comme dans la bibliothèque EPD, le tampon d'image peut être écrit d'abord et ensuite être entièrement affiché. Lors de l'appel de la fonction drawPaged(), une autre fonction est passée avec un autre paramètre :

display.drawPaged (Headline, 0);
display.drawPaged (WifiDataPaged, 0);

Examinez de plus près l'exemple GxEPD2_PagedDisplayUsingCallback, nous afficherons deux zones partielles.

Pour ce faire, nous avons besoin de deux fonctions. Un pour le titre, dont le texte est blanc et le fond noir :

void Headline (const void*) {
  int16_t tbx, tby ; uint16_t tbw, tbh ;
display.setFont (&FreeSans9pt7b) ;
display.getTextBounds ("Texte de test", 0, 0, &tbx, &tby, &tbw, &tbh) ;
 
display.setTextColor (GxEPD_WHITE) ;
display.setPartialWindow (0, 0, display.width (), tbh + 3);
display.fillScreen (GxEPD_BLACK) ;
display.setCursor (0, tbh + 1);
display.println ("WIFI connecté:");
}

La seconde fonction va lancer toutes les données Wi-Fi:

void WifiDataPaged (const void*) {
  int16_t tbx, tby ; uint16_t tbw, tbh ;
display.setFont (&FreeSans9pt7b) ;
display.getTextBounds ("Texte de test", 0, 0, &tbx, &tby, &tbw, &tbh) ;
 
display.setTextColor (GxEPD_BLACK) ;
display.setPartialWindow (0, tbh + 3, display.width (), display.height ()-tbh + 3);
display.fillScreen (GxEPD_WHITE) ;
display.setCursor (0, (tbh * 2) + 5);
display.println ("Adresse IP:");
display.println (WiFi.localIP ()) ;
display.println ("SSID:");
display.println (WiFi.SSID ()) ;
display.println ("Canal:");
display.println (WiFi.channel ()) ;
display.println ("Pile de signaux:");
display.print (WiFi.RSSI ()) ;
display.println ("dBm");
}

La fonction du programme devrait maintenant être la même qu'avec la bibliothèque EPD. Chargez le programme sur le tableau de votre choix. N'oubliez pas de commenter la bonne ligne avant.

Téléchargement du programme complet: GxEPD2ESP32ESP8266WifiDataV1undV2

Conclusion

La bibliothèque EPD ne convient qu'à l'affichage ePaper 1.54" de la version 1. Mais il fonctionne très bien. Lorsqu'on l'utilise, il est relativement facile de passer de la ESP32 à la ESP8266. Si vous connectez l'écran avec la version 2, les résultats ne sont plus satisfaisants à 100 %. Pour cela, il n'y a que la bibliothèque directement du fabricant, qui doit encore être adaptée.

Je vous recommande donc d'utiliser la bibliothèque GxEPD2. Vous avez besoin d'un peu de temps pour étudier les exemples et comprendre comment tout fonctionne. Mais vous êtes flexible en ce qui concerne la version de l'écran et le choix du microcontrôleur.


De nombreux autres affichages sont pris en charge. La bibliothèque est très lourde et prend beaucoup plus de temps à compiler. Mais cela en vaut la peine, car il permet de mettre en œuvre de nombreuses idées. Il est intéressant de jeter un coup d'œil aux nombreux exemples.

J'espère pouvoir vous aider avec cette série de blogs à mettre en œuvre des projets similaires, ou à inspirer votre créativité.

Andreas Wolter

pour AZ-Delivery Blog

DisplaysEsp-32Projekte für anfängerSensoren

15 commentaires

Andreas Wolter

Andreas Wolter

@R.Parusel: ja das ist es in der Tat. Daher auch die Probleme, die aus dem ersten Teil dieser Blogreihe resultierten. Es ist wichtig zu wissen, welches Display das ist, wie viele Farben es unterstützt. Ich würde mich dann durch die Beispiele hangeln. Dort muss man eigentlich nur die passende Zeile für das Board einkommentieren und natürlich auch die Pinbelegung passend konfigurieren. Ich tippe bei Ihrem Board auf die V1.

Grüße,
Andreas Wolter
AZ-Delivery Blog

R.Parusel

R.Parusel

Hallo,
ich habe hier eine 1.54" ePaper mit einem Kontrollerboard V2 und einem Display von V1, auf dem Flachbandkabel steht 2015 08.01. Mit verlaub, alles sehr verwirrend.
Ich versuche schon einige Zeit es zum Laufen zu bekommen. Bisher ohne Erfolg.
Viele Grüsse

Gerd

Gerd

Vielen Dank für deinen ausführlichen Artikel!
Ich habe eine neuere Variante des waveshare 1,54“ BW Displays am esp8266 D1 mini. Aufkleber V2, Rev.2.1.
Mit der Deklaration GxEPD2_BW<GxEPD2_154_D67 funktionieren die partiellen Fenster nicht. Keine Anzeige im partiellen Fenster.
In diesen Fall ist GxEPD2_BW<GxEPD2_150_BW zu verwenden. Siehe https://forum.arduino.cc/t/waveshare-e-paper-displays-with-spi/467865/3125
Um einen Sensor BME280 per i2c anschließen zu können, änderte ich die Pin’s am esp für RST und Busy des ePaper-Moduls. RST an D4 (GPIO 2) und Busy an D6 (GPIO 12).
display(GxEPD2_DRIVER_CLASS(/CS=15/ EPD_CS, /DC=D3/ 0, /RST=D4/ 2, /BUSY=D6/ 12));
Bei dieser Belegung ist ein Widerstand 4k7 von D8 gegen GND und ein Widerstand 1k von D4 an 3,3V anzuschließen.

Andreas Wolter

Andreas Wolter

@Carl Werner: Vielen Dank für den Hinweis. Wurde korrigiert.

Grüße,
Andreas Wolter
AZ-Delivery Blog

Carl Werner

Carl Werner

Die letzte Version des Skriptes (WifiData) ist wohl falsch verlinkt:
es erscheint nochmal die Version für die epd-Bibliothek, statt der für Gxepd2

Andreas Wolter

Andreas Wolter

@Georg: Vielen Dank. Nach meinem Kenntnisstand kann man die SPI-Schnittstelle teilen. Lediglich des CS Pin muss sich unterscheiden. Es gibt für die GxEPD2 Bibliothek ein Beispiel namens GxEPD2_MultiDisplay. Ich würde sagen, es ist sehr wahrscheinlich, dass es funktioniert. 100%ig sicher bin ich mir jedoch nicht.
Hier wurde diese Frage auch gestellt: https://forum.arduino.cc/t/two-pcd8544-on-wemos-d1-mini/484521/2
und mit Ja beantwortet.
Probieren Sie es aus und lassen uns wissen, ob es funktioniert hat.

Grüße,
Andreas Wolter
AZ-Delivery Blog

Joachim

Joachim

Toller Beitrag, herzlichen Dank zunächst! Ich erwäge, zwei Module an einem Board abzuschließen (vermutlich auch zwei größere, bspw. 4,3 Zoll). Das soll später per MQTT durch den home Assistant mit Daten gefüttert werden.
Meldet Frage: ist es grundsätzlich möglich, zwei epaper an ein Board anzuschließen und welches hätte ausreichend Anschlüsse? Das D1 dürfte wohl zu klein dafür sein…

Andreas Wolter

Andreas Wolter

@Dalwinder: There is no complete download of all sketches in a ZIP at this moment. If you click on all download links you will get all files.
It then depends on which microcontroller and display you are currently using.

im Moment gibt es keinen kompletten Download von allen Sketches in einer ZIP. Wenn Sie alle Download-Links anklicken, erhalten Sie alle Dateien.
Es hängt dann davon ab, welchen Mikrocontroller und welches Display Sie momentan verwenden.

Andreas Wolter
AZ-Delivery Blog

Dalwinder

Dalwinder

i want to see how e-paper display works. it is putting me close loop. some time this , some time that file is not included. i need a complete zip to download and see how does it looks like , please give me some way out . THANKS every body over there.

Markus Walsleben

Markus Walsleben

Hallo Herr Taz,
hier meine späte Antwort auf ihre Frage, die ich aber möglicherweise auch nicht richtig verstanden habe.
Die Library binde ich ich PIO-üblich über die Suche und dann “Add to Project” ein.
Dann habe ich in meinem Quelltext nur noch die Einbindung der passenden Variante (“#include ”) und dann definiere ich die Pins mittels
#define CS_PIN 26
#define DC_PIN 16
#define RST_PIN 22
#define BUSY_PIN 21
und der passenden Zeile
GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(CS_PIN, DC_PIN, RST_PIN, BUSY_PIN)); // GDEH0154D67

Für die Initialisierung habe ich eine eigene Routine:
void initDisplay()
{
display.init(); // uses standard SPI pins, e.g. SCK, MISO, MOSI, SS
// * special handling for Waveshare ESP32 Driver board * //
// ********************************************************* //
SPI.end(); // release standard SPI pins, e.g. SCK, MISO, MOSI, SS
//SPI: void begin(int8_t sck=-1, int8_t miso=-1, int8_t mosi=-1, int8_t ss=-1);
SPI.begin(18, 12, 23, 15); // map and init SPI pins SCK, MISO, MOSI, SS
// * end of special handling for Waveshare ESP32 Driver board * //
// **************************************************************** //
display.setRotation(0);
display.setFullWindow();
display.fillScreen(FillColor);
display.nextPage();
}
Danach ist das Display mit den display-Routinen wie gewünscht zu nutzen.

@Andreas Wolter: Sorry für die Verzögerung, die Mail ist einfach zu weit nach unten gerutscht.

uwetaz

uwetaz

Hallo Hr. Walsleben,
vielleicht hätten Sie einen Tipp für die Portierung nach PlatformIO für mich.
Nachdem mit einem V2-Display das Beispiel GxEPD2_Example in der Arduino IDE bei mir läuft wollte ich das Ganze auch nach PlatformIO portieren. Ich arbeite seit längerem mit den ESPs damit, weiß aber nicht wie ich das mit den Files für die Display selection machen muss. Ich habe zwar im Unterordner .pio\libdeps\esp32dev\GxEPD2 das Beispiel wiedergefunden, aber es gibt die selection Files für jedes Beispiel. Wo muss denn nun ein File angelegt werden? Könnten Sie vielleicht Ihre Struktur hier schreiben?

Das wäre sehr nett!

Christian Seel

Christian Seel

Vielen Dank für das Update zu “epd1in54V2”, ich dachte zunächst schon, das Display sei defekt! Um den Code zum Laufen zu bringen, war allerdings in epdif.h Zeile 34 arduino.h in Arduino.h zu ändern, in Datei epdif.h Zeile 32 spi.h in SPI.h. Vermutlich ist die Windows-IDE bei der Behandlung von Groß- und Kleinschreibung großzügiger als die Linux-Version.

Matthias Kasper

Matthias Kasper

Hallo,
habe dafür ein Gehäuse für den 3D-Druck erstellt. Es muss allerdings ein Board ohne Stiftleisten genutzt und die Leitungen angelötet werden.
Hier geht’s zur Druckvorlage → https://www.thingiverse.com/thing:4738646
Das Gehäuse besteht aus verschiedenen Unter und Oberteilen, die miteinander kombiniert werden können.
Viele Grüße
Matthias

csierra67

csierra67

Great tutorial, many thanks !
With these additonal explanations I have been able to put my display at work and try all of the proposed sketches.
For the information of other users, I own a b/w/r display and the driver that works best is
EPD2_154_Z90c
May save you some trials.

Markus Walsleben

Markus Walsleben

Ich freue mich sehr, dass die Artikelreihe fortgeführt wird. Ja, mit der EPD-Library hatte ich (wohl insb. wegen meines v2-Displays) so meine Probleme und bin deshalb gleich zur GxEPD2 gewechselt.
Hier möchte ich nun meine Erfahrungen teilen und Anmerkungen zum Artikel anbringen.
1. Das betrifft jetzt weder das Display noch eine der Libraries, sondern den Tipp mit dem Kondensator am ESP32. Die gleichen Probleme hatte ich anfangs auch mit der Arduino-IDE. Und diese Probleme waren komischerweise direkt nach dem Wechsel auf PlatformIO weg. Ich kann das nicht erklären, bin aber mit der aktuellen Situation zufrieden. Die Arduino-IDE ist ja auch um viele Längen langsamer, insbesondere beim kompilieren. Mit der GxEPD2 und PlatformIO fällt nicht auf, dass diese größer ist und länger benötigt.

2. Jetzt zum Display als solches. Ein E-Paper-Display wird ja vermutlich gerade in Hinblick auf den Stromsparenden Einsatz verwendet. Also Fälle, in denen der ESP nur zyklisch etwas erledigt, also Werte holt und/oder schickt und dann anzeigt und dann für eine Zeitlang wieder ruht. Dafür ist ja gerade der ESP32 mit dem Deep Sleep sehr gut geeignet. Hier sind dann auch die EPD zusammen mit der GxEPD2-Library sehr gut für vorbereitet, denn in dieser Library gibt es die Funktionen .powerOff() und .hibernate(). Diese schicken die Elektronik des Display schlafen und sorgen so für 1) noch weniger Stromverbrauch und 2) wird so verhindert, dass die beim “Schlafengehen” des ESP noch fließenden Spannungen den Inhalt des Display hässlich verändern.
Mit aktiviertem .hibernate() kann ich das komplette System (ESP+EPD) vom Strom nehmen und das Display zeigt über viele Stunden (ich habe keine Grenze gefunden, vielleicht ja unendlich?) das zuletzt ausgegebene Bild an.

3. Wer den ESP für längere Zeit schlafen legt, wird möglicherweise darüber stolpern, dass der ESP schon nach ~45 Minuten aufwacht. Das liegt am scheinbar oft verwendeten Beispiel zu liegen:

#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP 7200
RTC_DATA_ATTR int bootCount = 0;

void setup(){
Serial.begin(115200);
delay(200);
++bootCount;
Serial.println("Boot number: " + String(bootCount));
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

Serial.println(“Going to sleep now”); esp_deep_sleep_start();

}
void loop(){
}

Die Lösung liegt darin, die Zeile in
esp_sleep_enable_timer_wakeup((uint64_t)(TIME_TO_SLEEP) * uS_TO_S_FACTOR);
zu ändern. Den Tipp fand ich nach langem Suchen hier: https://github.com/espressif/arduino-esp32/issues/796#issuecomment-347516325

Wer seinen ESP also nur für kurze Zeit schlafen legt, wird also damit keine Probleme bekommen. Es kann aber nicht schaden, das immer so zu programmieren.

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Articles de blog recommandés

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery