ESP32 écran, affichage d'un fond de carte
L'objectif serait de pouvoir afficher un fond de carte sur un module ESP32 écran, par exemple pour suivre des positions GPS.
Pour l'instant il ne s'agit que de la partie affichage, mais qui ne fonctionne pas. Le test porte sur la récupération d'une tuile (un morceau de carte), c'est à dire d'un fichier d'une image en format PNG. La récupération se fait bien, mais pas l'affichage. C'est la bibliothèque PNGdec qui est utilisée.
Exemple d'URL de récupération de tuile :
https://tile.openstreetmap.org/15/16614/11304.png
Voici le code, à ce stade,
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <TFT_eSPI.h>
#include <PNGdec.h>
const char* ssid = "2.4GHz-MEMOIRE-VIVE";
const char* password = "************";
TFT_eSPI tft = TFT_eSPI();
PNG png;
int pngDraw(PNGDRAW *pDraw) {
static int offsetX = 0;
static int offsetY = 0;
if (pDraw->y == 0) {
int width = pDraw->iWidth;
int height = png.getHeight();
offsetX = (tft.width() - width) / 2;
offsetY = (tft.height() - height) / 2;
Serial.printf("Image %dx%d centrée à (%d,%d)\n", width, height, offsetX, offsetY);
}
static uint16_t lineBuffer[512]; // en principe l'image est <= 256
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_LITTLE_ENDIAN, 0xFFFF);
tft.pushImage(offsetX, offsetY + pDraw->y, pDraw->iWidth, 1, lineBuffer);
return 1;
}
void showTile(int zoom, int x, int y) {
Serial.printf("Free heap avant téléchargement: %d\n", ESP.getFreeHeap());
WiFiClientSecure client;
client.setInsecure();
HTTPClient https;
char url[128];
sprintf(url, "https://tile.openstreetmap.org/%d/%d/%d.png", zoom, x, y);
Serial.println(url);
if (!https.begin(client, url)) {
Serial.println("Erreur HTTPS.begin()");
return;
}
https.addHeader("User-Agent", "Mozilla/5.0 (ESP32) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/604.1");
int httpCode = https.GET();
if (httpCode != HTTP_CODE_OK) {
Serial.printf("Erreur HTTP: %d\n", httpCode);
Serial.printf("Réponse: %s\n", https.getString().c_str());
https.end();
return;
}
int len = https.getSize();
if (len <= 0 || len >= 50000) {
Serial.println("Taille invalide !");
https.end();
return;
}
uint8_t *buf = (uint8_t*)malloc(len);
if (!buf) {
Serial.println("Erreur malloc !");
https.end();
return;
}
WiFiClient *stream = https.getStreamPtr();
int index = 0;
while (https.connected() && index < len) {
int bytes = stream->read(buf + index, len - index);
if (bytes <= 0) break;
index += bytes;
}
Serial.printf("Téléchargé %d octets\n", index);
// Calculer un checksum simple pour vérifier l'intégrité
uint32_t checksum = 0;
for (int i = 0; i < index; i++) {
checksum += buf[i];
}
Serial.printf("Checksum du buffer: %u\n", checksum);
// Afficher le "magic number"
Serial.print("Magic number: ");
for (int i = 0; i < 8; i++) {
Serial.printf("%02X ", buf[i]);
}
Serial.println();
// Essayer de décoder le PNG
int rc = png.openRAM(buf, index, pngDraw);
Serial.printf("Résultat openRAM = %d\n", rc);
if (rc == PNG_SUCCESS) {
tft.startWrite();
tft.fillScreen(TFT_BLACK);
png.decode(NULL, 0);
tft.endWrite();
Serial.println("Tuile affichée !");
} else {
Serial.printf("Erreur PNG (%d)\n", rc);
// Afficher le début du buffer comme texte (pour voir s'il y a une erreur cachée)
buf[min(index, len - 1)] = '\0';
Serial.println("Contenu du buffer (début, 100 premiers octets):");
for (int i = 0; i < min(100, index); i++) {
Serial.printf("%02X ", buf[i]);
if ((i + 1) % 20 == 0) Serial.println();
}
Serial.println();
}
free(buf);
https.end();
png.close();
Serial.printf("Free heap après libération: %d\n", ESP.getFreeHeap());
}
void setup() {
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
Serial.printf("Connexion WiFi à %s...", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connecté !");
Serial.println(WiFi.localIP());
// Affichage du message de chargement
tft.fillScreen(TFT_BLUE);
tft.setTextColor(TFT_WHITE, TFT_BLUE);
delay(1000);
tft.fillScreen(TFT_RED);
delay(1000);
tft.fillScreen(TFT_GREEN);
delay(1000);
tft.fillScreen(TFT_WHITE);
delay(1000);
tft.setTextDatum(MC_DATUM);
tft.drawString("Chargement carte...", tft.width()/2, tft.height()/2);
showTile(15, 16614, 11304);
}
void loop() {
}
Et la sortie de la console,
WiFi connecté ! 192.168.1.221 Free heap avant téléchargement: 183400 https://tile.openstreetmap.org/15/16614/11304.png Téléchargé 4113 octets Checksum du buffer: 530546 Magic number: 89 50 4E 47 0D 0A 1A 0A Résultat openRAM = 0 Tuile affichée ! Free heap après libération: 127544