Module StepDown LM2596 (exemple d'application)
Un boîtier imprimé pour le module StepDown avec connecteurs XT60 adapté à l'imprimante 3D (TEVO-Black Widow), afin de réduire la tension disponible de 24V à 12V pour, par exemple, alimenter un éclairage LED 12V.
Un boîtier imprimé pour le module StepDown avec des connecteurs XT60, adapté à l'imprimante 3D (TEVO-Black Widow), permettant de « réduire » la tension existante de 24 V à 12 V afin, par exemple, faire fonctionner un éclairage LED en 12 V. D'autres conversions de tension, telles que 12 V/24 V vers 9 V, 9 V vers 5 V, etc., sont bien sûr également possibles.
Composant nécessaire
- 4x vis M3 x 20 mm
- env. 10 cm - 15 cm de câble
- Boîtier StepDown – XT60
- 1x module StepDown
- 2x connecteur XT60
- Gaine thermorétractable
- Troisième main (pour la soudure)
- Station de soudage / fer à souder
- Étain à souder
Instructions
Tout d'abord, téléchargez le boîtier imprimé depuis Thingiverse.com et imprimez-le à l'aide d'une imprimante 3D. Des écarts peuvent survenir selon le filament utilisé, l'imprimante, etc. Une imprimante 3D précise est ici très importante.
cliquez sur les images pour agrandir
Conclusion
Nous sommes arrivés à la fin de ce projet !
Avec ce cadre photo IoT numérique basé sur ESP32, vous avez non seulement appris à contrôler des écrans et à décoder des images, mais aussi à configurer un serveur web local pour une gestion pratique des fichiers.
Ces connaissances constituent une excellente base pour de futurs projets d'automatisation et d'IoT. Nous espérons que le montage vous a plu et que vous continuerez à explorer les nombreuses possibilités offertes par l'ESP32 !
(Cours de l'action) afficher / masquer
{
"meta": {
"symbol": "AAPL",
"interval": "15min"
},
"values": [
{
"datetime": "2026-07-24 09:30:00",
"open": "212.41",
"high": "213.02",
"low": "212.20",
"close": "212.88",
"volume": "1840233"
}
],
"status": "ok"
}
Seul close nous intéresse dans chaque entrée – 26 valeurs à un rythme de 15 minutes donnent exactement une journée de trading américaine de 6,5 heures. order=ASC garantit que la valeur la plus ancienne vient en premier, puis nous pouvons tracer la courbe directement de gauche à droite.
Étape 2 | Préparer l'IDE Arduino
Installer le package de carte ESP32 (guide détaillé)
- Fichier → Préférences ouvrir.
- Saisir dans le champ URL de gestionnaire de cartes supplémentaires : https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
- Outils → Carte → Gestionnaire de cartes ouvrir, rechercher esp32, installer esp32 by Espressif Systems.
- Sélectionner la carte : ESP32 Dev Module.
Vérifier les pilotes
Notre carte utilise un CP2102 comme convertisseur USB-série. Windows 11, macOS et la plupart des distributions Linux le reconnaissent automatiquement. Si aucune entrée n'apparaît sous Outils → Port, installez le pilote CP2102 de Silicon Labs.
Installer les bibliothèques
Outils → Gérer les bibliothèques, puis rechercher et installer :
Lors de l'installation de la bibliothèque Adafruit-ILI9341, l'IDE demande si les dépendances doivent être installées – sélectionnez ici « Install all ». WiFi, HTTPClient, SPI et WiFiClientSecure sont déjà inclus dans le package de carte ESP32.
Étape 3 | Câbler l'écran
Les deux composants fonctionnent en 3,3 V – un convertisseur de niveau n'est pas nécessaire. Retirez toujours le câble USB avant le câblage. L'écran possède en haut une rangée de broches avec neuf pins. Les quatre broches en bas appartiennent au slot microSD et restent libres dans ce projet.
| Broche de l'affichage | Broche ESP32 | Fonction |
|---|---|---|
| VCC | 3V3 | Alimentation |
| GND | GND | Masse |
| CS | GPIO 15 | Sélection de puce |
| RESET | GPIO 4 | Réinitialisation |
| DC (aussi RS) | GPIO 2 | Données / Commande |
| SDI (MOSI) | GPIO 23 | Données vers l'affichage |
| SCK | GPIO 18 | Horloge |
| LED | 3V3 | Rétroéclairage |
| SDO (MISO) | GPIO 19 | Données de l'affichage |
Les broches GPIO 23, 18 et 19 sont les broches SPI matérielles de l'ESP32 (VSPI). La bibliothèque Adafruit les utilise automatiquement – dans le croquis, nous indiquons uniquement CS, DC et RESET.
Deux broches, une seule source
VCC et LED ont tous deux besoin de 3,3 V, mais l'ESP32 n'a qu'une seule broche 3V3. C'est là que les rails d'alimentation de la plaque d'essai entrent en jeu : un câble de la broche 3V3 vers le rail rouge, puis deux câbles vers l'affichage. Les deux broches sont simplement des consommateurs parallèles sur la même source. La masse (GND) est disponible deux fois sur l'ESP32, mais peut également transiter par le rail bleu. Si vous câblez directement, il faut fabriquer un câble en Y. Vous pouvez également utiliser un connecteur de câble.
Vérification avant la mise sous tension
- VCC est-il bien positionné sur 3V3 et non sur VIN/5V ?
- Le GND est-il connecté ?
- Tous les connecteurs sont-ils bien enfichés ? Les mauvais contacts sur le bus SPI génèrent les erreurs les plus étranges.
Étape 4 | Test rapide - L'écran fonctionne-t-il ?
Avant d'ajouter le WLAN et les API, vérifions isolément l'affichage :
Afficher / masquer le code
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
void setup() {
tft.begin();
tft.setRotation(3); // Format paysage 320 x 240 ; avec 1, l'image est à l'envers
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(3);
tft.setCursor(20, 100);
tft.print("Display laeuft!");
}
void loop() {}
Le texte vert s'affiche-t-il en mode paysage à l'écran ? Alors le matériel est en bon état.
Sinon, passez brièvement à la résolution des problèmes à la fin.
Étape 5 | Le croquis Ticker
Copiez le programme en entier dans un nouveau croquis et adaptez les lignes marquées en haut : nom du WLAN, mot de passe WLAN, les deux clés API et votre liste de surveillance.
Afficher / masquer le code
/* ============================================================
ESP32 Ticker boursier avec historique des cours
Display : 2,4" TFT ILI9341 (Adafruit_GFX / Adafruit_ILI9341)
Cours : finnhub.io – Cours en direct, 60 requêtes/minute
Historique : twelvedata.com – Bougies intraday pour le graphique
============================================================ */
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSansBold24pt7b.h>
// ---------- Broches de l'écran ----------
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
// MOSI 23, SCK 18, MISO 19 = SPI matériel, utilisé automatiquement
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// ============ À ADAPTER ICI =================================
const char* WIFI_SSID = "MEIN_WLAN";
const char* WIFI_PASS = "MEIN_PASSWORT";
const char* FINNHUB_KEY = "MEIN_FINNHUB_KEY";
const char* TWELVE_KEY = "MEIN_TWELVEDATA_KEY";
struct Symbol { const char* ticker; const char* name; };
// Votre watchlist – ajoutez ou supprimez des lignes, le reste s'adapte
const Symbol watchlist[] = {
{ "AAPL", "Apple" },
{ "MSFT", "Microsoft" },
{ "NVDA", "NVIDIA" },
{ "AMZN", "Amazon" },
{ "TSLA", "Tesla" }
};
// ============================================================
const uint8_t ANZAHL = sizeof(watchlist) / sizeof(watchlist[0]);
// Fuseau horaire Allemagne avec passage automatique à l'heure d'été
const char* TZ_INFO = "CET-1CEST,M3.5.0/02,M10.5.0/03";
const char* NTP_SERVER = "pool.ntp.org";
const uint32_t KURS_INTERVALL = 60000; // 1 min – Cours en direct (Finnhub)
const uint32_t CHART_INTERVALL = 240000; // 4 min – un graphique (Twelve Data)
const uint32_t WECHSEL_INTERVALL = 8000; // 8 s – valeur suivante de la liste
#define MAX_PUNKTE 26 // Points de données dans le graphique (26 x 15 min = 1 journée de trading)
// Données d'exécution, remplies par le programme
struct Daten {
float kurs;
float diff;
float proz;
bool gueltig;
float verlauf[MAX_PUNKTE];
uint8_t punkte;
};
Daten daten[ANZAHL]; // global -> démarre automatiquement avec des zéros
// ---------- Couleurs (RGB565) ----------
#define FARBE_BG 0x0862 // presque noir
#define FARBE_BAR 0x1105 // barre d'en-tête
#define FARBE_TEXT 0xFFFF // blanc
#define FARBE_GRAU 0x7C52 // texte secondaire
#define FARBE_LINIE 0x39C7 // ligne auxiliaire dans le graphique
#define FARBE_GRUEN 0x2610 // en hausse
#define FARBE_ROT 0xE267 // en baisse
#define FARBE_GRUEN_BG 0x09C5 // surface de remplissage sous la courbe
#define FARBE_ROT_BG 0x38A2
// ---------- Mise en page ----------
#define BREITE 320
#define HOEHE 240
#define KOPF_H 28
#define CHART_X 12
#define CHART_Y 152
#define CHART_W 296
#define CHART_H 60
uint32_t tKurse = 0;
uint32_t tChart = 0;
uint32_t tWechsel = 0;
uint8_t anzeigeIndex = 0; // valeur actuellement affichée
uint8_t chartIndex = 0; // prochain graphique à mettre à jour
int letzteSekunde = -1;
// ===========================================================
void setup() {
Serial.begin(115200);
delay(200);
tft.begin();
tft.setSPISpeed(40000000); // 40 MHz ; en cas de perturbations d'image, réduire à 24000000
tft.setRotation(3); // Format paysage 320 x 240 (1 = tourné de 180 degrés)
statusText("Connexion au Wi-Fi ...");
wifiVerbinden();
configTzTime(TZ_INFO, NTP_SERVER);
statusText("Récupération des cours ...");
kurseAktualisieren();
statusText("Chargement des graphiques ...");
for (uint8_t i = 0; i < ANZAHL; i++) {
chartAktualisieren(i);
delay(1000); // Twelve Data autorise 8 requêtes par minute
}
tft.fillScreen(FARBE_BG);
kopfzeileZeichnen();
wertZeichnen(anzeigeIndex);
tKurse = tChart = tWechsel = millis();
}
// ===========================================================
void loop() {
uint32_t jetzt = millis();
// Cours en direct de tous les symboles
if (jetzt - tKurse >= KURS_INTERVALL) {
tKurse = jetzt;
kurseAktualisieren();
wertZeichnen(anzeigeIndex);
}
// Charger un graphique à tour de rôle
if (jetzt - tChart >= CHART_INTERVALL) {
tChart = jetzt;
chartAktualisieren(chartIndex);
if (chartIndex == anzeigeIndex) wertZeichnen(anzeigeIndex);
chartIndex = (chartIndex + 1) % ANZAHL;
}
// Passer à la valeur suivante
if (jetzt - tWechsel >= WECHSEL_INTERVALL) {
tWechsel = jetzt;
anzeigeIndex = (anzeigeIndex + 1) % ANZAHL;
wertZeichnen(anzeigeIndex);
}
uhrzeitZeichnen();
delay(50);
}
// ===========================================================
// Wi-Fi
// ===========================================================
void wifiVerbinden() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
uint8_t versuche = 0;
while (WiFi.status() != WL_CONNECTED && versuche < 40) {
delay(500);
Serial.print(".");
versuche++;
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Connecté. IP : ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Échec de la connexion Wi-Fi.");
statusText("Pas de Wi-Fi !");
}
}
// ===========================================================
// Cours en direct de Finnhub
// ===========================================================
void kurseAktualisieren() {
if (WiFi.status() != WL_CONNECTED) {
wifiVerbinden();
if (WiFi.status() != WL_CONNECTED) return;
}
for (uint8_t i = 0; i < ANZAHL; i++) {
String url = String("https://finnhub.io/api/v1/quote?symbol=")
+ watchlist[i].ticker + "&token=" + FINNHUB_KEY;
WiFiClientSecure client;
client.setInsecure(); // sans vérification de certificat – suffisant ici
HTTPClient https;
https.setTimeout(8000);
if (https.begin(client, url)) {
int code = https.GET();
if (code == HTTP_CODE_OK) {
JsonDocument doc;
DeserializationError fehler = deserializeJson(doc, https.getString());
if (!fehler) {
daten[i].kurs = doc["c"] | 0.0f;
daten[i].diff = doc["d"] | 0.0f;
daten[i].proz = doc["dp"] | 0.0f;
daten[i].gueltig = (daten[i].kurs > 0);
Serial.printf("%-6s %8.2f (%+.2f%%)\n", watchlist[i].ticker, daten[i].kurs, daten[i].proz);
} else {
Serial.printf("Erreur JSON pour %s : %s\n", watchlist[i].ticker, fehler.c_str());
}
} else {
Serial.printf("Finnhub HTTP %d pour %s\n", code, watchlist[i].ticker);
}
https.end();
}
delay(250);
}
}
// ===========================================================
// Historique des cours de Twelve Data
// ===========================================================
void chartAktualisieren(uint8_t i) {
if (WiFi.status() != WL_CONNECTED) return;
String url = String("https://api.twelvedata.com/time_series?symbol=")
+ watchlist[i].ticker
+ "&interval=15min&outputsize=" + String(MAX_PUNKTE)
+ "&order=ASC&apikey=" + TWELVE_KEY;
WiFiClientSecure client;
client.setInsecure();
HTTPClient https;
https.setTimeout(10000);
if (!https.begin(client, url)) {
Serial.println("TwelveData : échec de la connexion");
return;
}
int code = https.GET();
if (code != HTTP_CODE_OK) {
Serial.printf("TwelveData HTTP %d pour %s\n", code, watchlist[i].ticker);
https.end();
return;
}
// Lire complètement au lieu d'analyser directement depuis le flux : Twelve Data
// répond selon la taille avec "chunked transfer encoding", ce qui ferait échouer
// un analyseur lisant directement.
String antwort = https.getString();
https.end();
// Filtre : ne conserver que "close" par entrée ainsi que le statut et le message d'erreur
JsonDocument filter;
filter["values"][0]["close"] = true;
filter["status"] = true;
filter["message"] = true;
JsonDocument doc;
DeserializationError fehler = deserializeJson(doc, antwort, DeserializationOption::Filter(filter));
if (fehler) {
Serial.printf("Erreur JSON du graphique pour %s : %s\n", watchlist[i].ticker, fehler.c_str());
return;
}
// Important : Twelve Data signale souvent les erreurs avec HTTP 200 dans le corps JSON
const char* status = doc["status"] | "";
if (strcmp(status, "ok") != 0) {
Serial.printf("TwelveData signale une erreur pour %s : %s\n", watchlist[i].ticker, doc["message"] | "inconnu");
return;
}
uint8_t k = 0;
for (JsonObject eintrag : doc["values"].as<JsonArray>()) {
if (k >= MAX_PUNKTE) break;
daten[i].verlauf[k++] = eintrag["close"].as<float>();
}
daten[i].punkte = k;
Serial.printf("Graphique %s : %d points\n", watchlist[i].ticker, k);
}
// ===========================================================
// Affichage
// ===========================================================
void kopfzeileZeichnen() {
tft.fillRect(0, 0, BREITE, KOPF_H, FARBE_BAR);
textAn(12, 19, "TICKER BOURSIER", &FreeSans9pt7b, FARBE_TEXT);
}
void wertZeichnen(uint8_t i) {
char puffer[32];
tft.fillRect(0, KOPF_H, BREITE, HOEHE - KOPF_H, FARBE_BG);
// Nom de l'entreprise et symbole boursier
textAn(12, 52, watchlist[i].name, &FreeSans12pt7b, FARBE_TEXT);
textAn(12, 74, watchlist[i].ticker, &FreeSans9pt7b, FARBE_GRAU);
if (!daten[i].gueltig) {
textAn(12, 118, "pas de données", &FreeSans12pt7b, FARBE_GRAU);
punkteZeichnen(i);
return;
}
uint16_t farbe = (daten[i].diff >= 0) ? FARBE_GRUEN : FARBE_ROT;
// Cours, grand
snprintf(puffer, sizeof(puffer), "%.2f", daten[i].kurs);
textAn(12, 122, puffer, &FreeSansBold24pt7b, FARBE_TEXT);
// Variation, en couleur
snprintf(puffer, sizeof(puffer), "%+.2f (%+.2f%%)", daten[i].diff, daten[i].proz);
textAn(12, 146, puffer, &FreeSans12pt7b, farbe);
// Triangle comme flèche directionnelle
if (daten[i].diff >= 0)
tft.fillTriangle(292, 92, 278, 116, 306, 116, farbe);
else
tft.fillTriangle(292, 116, 278, 92, 306, 92, farbe);
chartZeichnen(i);
punkteZeichnen(i);
}
// ---------- Historique des cours ----------
void chartZeichnen(uint8_t i) {
tft.fillRect(CHART_X, CHART_Y, CHART_W, CHART_H, FARBE_BG);
uint8_t n = daten[i].punkte;
if (n < 2) {
textAn(CHART_X, CHART_Y + 34, "Historique non disponible", &FreeSans9pt7b, FARBE_GRAU);
return;
}
// Déterminer la plage de valeurs – la clôture de la veille doit toujours être visible,
// afin que la ligne zéro ne sorte pas de l'image
float vortag = daten[i].kurs - daten[i].diff;
float minWert = daten[i].verlauf[0];
float maxWert = daten[i].verlauf[0];
for (uint8_t k = 1; k < n; k++) {
if (daten[i].verlauf[k] < minWert) minWert = daten[i].verlauf[k];
if (daten[i].verlauf[k] > maxWert) maxWert = daten[i].verlauf[k];
}
if (vortag < minWert) minWert = vortag;
if (vortag > maxWert) maxWert = vortag;
float spanne = maxWert - minWert;
if (spanne < 0.0001f) spanne = 1.0f; // Éviter la division par zéro
// Ligne en pointillés à la hauteur de la clôture de la veille
int yVortag = CHART_Y + CHART_H - 1 - (int)((vortag - minWert) / spanne * (CHART_H - 1));
for (int x = CHART_X; x < CHART_X + CHART_W; x += 6) {
tft.drawFastHLine(x, yVortag, 3, FARBE_LINIE);
}
// Calculer les coordonnées écran de tous les points
int px[MAX_PUNKTE], py[MAX_PUNKTE];
for (uint8_t k = 0; k < n; k++) {
px[k] = CHART_X + (int)((float)k * (CHART_W - 1) / (n - 1));
py[k] = CHART_Y + CHART_H - 1 - (int)((daten[i].verlauf[k] - minWert) / spanne * (CHART_H - 1));
}
uint16_t linie = (daten[i].diff >= 0) ? FARBE_GRUEN : FARBE_ROT;
uint16_t flaeche = (daten[i].diff >= 0) ? FARBE_GRUEN_BG : FARBE_ROT_BG;
// Passage 1 : Remplir la surface sous la courbe
for (uint8_t k = 1; k < n; k++) {
for (int x = px[k - 1]; x <= px[k]; x++) {
int y = py[k - 1];
if (px[k] != px[k - 1]) {
y += (py[k] - py[k - 1]) * (x - px[k - 1]) / (px[k] - px[k - 1]);
}
tft.drawFastVLine(x, y, CHART_Y + CHART_H - y, flaeche);
}
}
// Passage 2 : Dessiner la courbe par-dessus
for (uint8_t k = 1; k < n; k++) {
tft.drawLine(px[k - 1], py[k - 1], px[k], py[k], linie);
}
}
void punkteZeichnen(uint8_t aktiv) {
int x = BREITE / 2 - ((ANZAHL - 1) * 14) / 2;
for (uint8_t k = 0; k < ANZAHL; k++) {
tft.fillCircle(x + k * 14, 228, 3, (k == aktiv) ? FARBE_TEXT : FARBE_GRAU);
}
}
void uhrzeitZeichnen() {
struct tm zeit;
if (!getLocalTime(&zeit, 0)) return;
if (zeit.tm_sec == letzteSekunde) return; // une seule fois par seconde
letzteSekunde = zeit.tm_sec;
char puffer[12];
strftime(puffer, sizeof(puffer), "%H:%M:%S", &zeit);
// Police intégrée : peut remplir l'arrière-plan en même temps -> pas de scintillement
tft.setFont();
tft.setTextSize(2);
tft.setTextColor(FARBE_TEXT, FARBE_BAR);
tft.setCursor(BREITE - 88 - 12, 6);
tft.print(puffer);
tft.setTextSize(1);
}
// ---------- Petites fonctions utilitaires ----------
void textAn(int x, int grundlinie, const char* txt, const GFXfont* font, uint16_t farbe) {
tft.setFont(font);
tft.setTextSize(1);
tft.setTextColor(farbe);
tft.setCursor(x, grundlinie); // avec les polices GFX, y est la ligne de base
tft.print(txt);
}
void statusText(const char* txt) {
tft.fillScreen(FARBE_BG);
textAn(20, 125, txt, &FreeSans12pt7b, FARBE_TEXT);
}
Étape 6 : Télécharger et démarrer
- Outils → Carte : ESP32 Dev Module
- Outils → Port : sélectionner le port de votre carte
- Vitesse de téléchargement : 921600 (réduire à 115200 en cas de problème)
- Cliquer sur Télécharger.
Si le téléchargement reste bloqué sur Connecting........___ : maintenir enfoncée la touche BOOT sur l'ESP32 jusqu'à ce que le téléchargement commence. Certaines cartes nécessitent cette impulsion.
- Connexion au WLAN…"
- Récupération des cours…"
- Chargement des graphiques…" (prend environ cinq secondes en raison du temps d'attente entre les requêtes)
- et enfin la première valeur avec la courbe
Ouvrir en parallèle le moniteur série à 115200 bauds. Celui-ci affiche les cours récupérés et le nombre de points de graphique consultés – idéal pour le dépannage.
Optionnel | Boîtier imprimé en 3D
Le boîtier se compose de 3 parties et nécessite 4 aimants 5x2 mm. Le téléchargement est disponible ici.
Résolution des problèmes
| Symptôme | Cause & Solution |
|---|---|
| L'écran reste noir | Vérifier le rétroéclairage : la broche LED est-elle connectée à 3V3 ? Ensuite, contrôler CS, DC et RESET. |
| L'écran reste blanc | Souvent, DC ou RESET sont inversés. Vérifiez si les valeurs #define en haut du sketch correspondent au câblage. |
| Image déformée, striée ou avec des artefacts | Réduire tft.setSPISpeed() à 24000000. Les câbles jumper longs ou de mauvaise qualité ne supportent souvent pas 40 MHz. |
| Couleurs inversées (Rouge / Bleu) | Certains modules utilisent BGR au lieu de RGB. Solution : après tft.begin(), ajouter la ligne tft.sendCommand(ILI9341_MADCTL, (uint8_t[]) {0x28}, 1); et faire varier la valeur. |
| L'image est à l'envers | tft.setRotation() dans setup() : alternez entre 1 et 3 – les deux sont en mode paysage, les deux valeurs diffèrent de 180°. Celle qui convient dépend de si la barrette de broches de l'écran est à gauche ou à droite. (0 et 2 donnent un mode portrait, ce qui nécessiterait d'adapter la mise en page.) |
FreeSans12pt7b introuvable |
La bibliothèque Adafruit-GFX n'est pas (complètement) installée. Installez-la via le gestionnaire de bibliothèques. |
redeclared as different kind of entity |
Une variable personnelle porte le même nom qu'une fonction de la bibliothèque standard. Candidats notoires : index, time, link, div, remove, y0/y1. Renommez la variable, par exemple indexAffichage au lieu de index. |
| Wi-Fi ne se connecte pas | L'ESP32 ne prend pas en charge le 5 GHz. Vérifiez si votre routeur propose un réseau 2,4 GHz et que le mot de passe est exactement correct. |
| Finnhub HTTP 401 | Clé API incorrecte ou non encore activée. Testez dans le navigateur (voir étape 1). |
| Finnhub HTTP 429 | Trop de requêtes. Augmentez KURS_INTERVALL ou réduisez la liste de surveillance. |
| Finnhub HTTP 403 | Le symbole appartient à une bourse en dehors de l'offre gratuite. Restez sur les actions américaines. |
| TwelveData HTTP 429 / « API credits » | La limite quotidienne de 800 est atteinte. Augmentez CHART_INTERVALL – avec 6 minutes, il n'y a plus que 240 appels par jour. |
| Le graphique affiche « Historique non disponible » | La récupération a échoué – ce n'est pas un état de chargement, tous les graphiques sont récupérés au démarrage. Le moniteur série révèle la cause. Fréquemment : clé Twelve Data incorrecte ou crédits épuisés. Attention, Twelve Data signale les deux avec HTTP 200 et "status":"error" dans le corps. Appelez l'URL de test de l'étape 1 dans le navigateur, la raison y est indiquée en clair. |
| Le graphique est une ligne plate | Normal en dehors des heures de trading – il n'y a alors pas de nouveaux cours. |
| Le cours est à 0,00 | Vérifiez l'orthographe du symbole. Les deux API attendent exactement le code boursier, par exemple BRK.B au lieu de BRK-B. |
| Le téléversement échoue | Maintenez le bouton BOOT enfoncé lors de l'établissement de la connexion. Aucun port visible ? Installez le pilote CP2102 et utilisez un câble de données authentique. |
| L'ESP32 redémarre en continu | C'est généralement un problème d'alimentation : les ports USB des moniteurs ou des hubs fournissent souvent trop peu de courant. Utilisez une alimentation avec au moins 1 A. |