Voilà une petite vidéo qui présente un petit écran OLED de 1,3". Les deux programmes sont juste après.
.
.
Le câblage est très simple :
La borne VCC de l'écran vas sur 3v3 ou 5V selon le modèle
La borne GND de l'écran vas sur GND
La borne SCL de l'écran vas sur D1 (GPIO5)
La borne SDA de l'écran vas sur D2 (GPIO4)
C'est le câblage I2C standard sur Wemos D1 Mini (D1 = SCL, D2 = SDA par défaut)
Bibliothèque à utiliser
Comme votre écran utilise le chip SH1106 (et non SSD1306, attention à ne pas confondre), il faut une bibliothèque compatible. La plus simple est U8g2 (par olikraus), qui gère très bien le SH1106.
Dans l'IDE Arduino : Outils > Gérer les bibliothèques → rechercher "U8g2" → installer.
Programme 1
Code : Tout sélectionner
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
// Configuration pour écran SH1106 128x64 I2C (Adresse 0x3C par défaut)
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
void setup() {
u8g2.begin();
}
void loop() {
u8g2.clearBuffer();
u8g2.sendBuffer(); // Efface l'écran
delay(2000);
u8g2.setFont(u8g2_font_6x10_tf); // Choix d'une police adaptée
u8g2.drawStr(10, 25, "Bonjour,"); // Ligne 1 (X=10, Y=25)
u8g2.sendBuffer();
delay (2000);
u8g2.drawStr(10, 45, "bienvenue a vous."); // Ligne 2 (X=10, Y=45)
u8g2.sendBuffer(); // Envoie le rendu à l'écran
delay(2000);
}
Programme 2
Code : Tout sélectionner
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <U8g2lib.h>
#include <Wire.h>
// --- Point d'accès Wi-Fi ---
const char* ap_ssid = "WemosOLED";
const char* ap_password = "12345678"; // minimum 8 caractères
// --- Écran OLED ---
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
// --- Serveur web ---
ESP8266WebServer server(80);
String texteActuel = "En attente...";
// --- Textes préformatés (à personnaliser) ---
const char* textesPredefinis[10] = {
"Hello les terriens !",
"Texte numero 2",
"Texte numero 3",
"Texte numero 4",
"Ne pas me deranger, je fait ma sieste.",
"Texte numero 6",
"Au telephone avec ma femme, cela vas durer longtemps. Allez vous balader.",
"Texte numero 8",
"Vive Passionnement",
"Texte numero 10"
};
// --- Gestion du défilement (marquee) ---
const int ecranLargeur = 128;
const int ecranHauteur = 64;
int scrollX = ecranLargeur;
int texteWidthPx = 0;
unsigned long dernierScroll = 0;
const unsigned long delaiScroll = 50; // ms entre chaque décalage (plus petit = plus rapide)
const int vitesseScroll = 2; // pixels par pas
bool defilementActif = true;
// --- Gestion de l'inactivité / économiseur d'écran ---
unsigned long derniereActivite = 0;
const unsigned long delaiInactivite = 30000; // 30 secondes
bool modeEconomiseur = false;
// --- Point rebondissant ---
float pointX = 10, pointY = 10;
float pointDX = 1.2, pointDY = 0.9;
const int pointRayon = 2;
unsigned long dernierPoint = 0;
const unsigned long delaiPoint = 20; // ms entre chaque déplacement
void signalerActivite() {
derniereActivite = millis();
if (modeEconomiseur) {
modeEconomiseur = false;
// Réaffiche l'état courant en sortant de l'économiseur
if (defilementActif) {
scrollX = ecranLargeur;
} else {
afficherFixeDeclare(); // déclaration anticipée ci-dessous
}
}
}
// Découpe le texte en lignes qui tiennent dans la largeur de l'écran (respecte les mots)
int decouperEnLignes(String texte, String lignes[], int maxLignes) {
int nbLignes = 0;
String ligne = "";
int start = 0;
while (start < (int)texte.length() && nbLignes < maxLignes) {
int espace = texte.indexOf(' ', start);
if (espace == -1) espace = texte.length();
String mot = texte.substring(start, espace);
String essai = ligne.length() > 0 ? ligne + " " + mot : mot;
if (u8g2.getUTF8Width(essai.c_str()) > ecranLargeur && ligne.length() > 0) {
lignes[nbLignes++] = ligne;
ligne = mot;
} else {
ligne = essai;
}
start = espace + 1;
}
if (ligne.length() > 0 && nbLignes < maxLignes) {
lignes[nbLignes++] = ligne;
}
return nbLignes;
}
void afficherFixe(String texte) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
const int maxLignes = 4;
const int hauteurLigne = 15;
String lignes[maxLignes];
int nbLignes = decouperEnLignes(texte, lignes, maxLignes);
int hauteurTotale = nbLignes * hauteurLigne;
int yDepart = (ecranHauteur - hauteurTotale) / 2 + 11;
if (yDepart < 11) yDepart = 11;
for (int i = 0; i < nbLignes; i++) {
int largeur = u8g2.getUTF8Width(lignes[i].c_str());
int x = (ecranLargeur - largeur) / 2;
if (x < 0) x = 0;
u8g2.setCursor(x, yDepart + i * hauteurLigne);
u8g2.print(lignes[i]);
}
u8g2.sendBuffer();
}
void afficherFixeDeclare() {
afficherFixe(texteActuel);
}
void preparerTexte(String texte) {
texteActuel = texte;
u8g2.setFont(u8g2_font_ncenB08_tr);
texteWidthPx = u8g2.getUTF8Width(texte.c_str());
scrollX = ecranLargeur; // repart depuis la droite
if (!modeEconomiseur) {
if (!defilementActif) {
afficherFixe(texteActuel);
}
}
}
void mettreAJourScroll() {
if (!defilementActif) return;
if (texteActuel.length() == 0) return;
unsigned long maintenant = millis();
if (maintenant - dernierScroll < delaiScroll) return;
dernierScroll = maintenant;
scrollX -= vitesseScroll;
if (scrollX < -texteWidthPx) {
scrollX = ecranLargeur; // recommence à droite
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
int yCentre = (ecranHauteur / 2) + 4;
u8g2.setCursor(scrollX, yCentre);
u8g2.print(texteActuel);
u8g2.sendBuffer();
}
void mettreAJourEconomiseur() {
unsigned long maintenant = millis();
if (maintenant - dernierPoint < delaiPoint) return;
dernierPoint = maintenant;
pointX += pointDX;
pointY += pointDY;
if (pointX <= pointRayon || pointX >= ecranLargeur - pointRayon) {
pointDX = -pointDX;
pointX = constrain(pointX, pointRayon, ecranLargeur - pointRayon);
}
if (pointY <= pointRayon || pointY >= ecranHauteur - pointRayon) {
pointDY = -pointDY;
pointY = constrain(pointY, pointRayon, ecranHauteur - pointRayon);
}
u8g2.clearBuffer();
u8g2.drawDisc((int)pointX, (int)pointY, pointRayon);
u8g2.sendBuffer();
}
void gererAffichage() {
unsigned long maintenant = millis();
if (!modeEconomiseur && (maintenant - derniereActivite > delaiInactivite)) {
modeEconomiseur = true;
u8g2.clearBuffer();
u8g2.sendBuffer();
}
if (modeEconomiseur) {
mettreAJourEconomiseur();
} else {
mettreAJourScroll();
}
}
void handleRoot() {
signalerActivite();
String html = "<!DOCTYPE html><html><head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<title>Afficheur OLED</title>";
html += "<style>body{font-family:sans-serif;text-align:center;margin-top:30px;}";
html += "input{padding:10px;font-size:16px;width:80%;max-width:300px;}";
html += "button{padding:10px 20px;font-size:16px;margin-top:10px;margin-left:5px;}";
html += ".effacer{background-color:#e74c3c;color:white;border:none;border-radius:5px;}";
html += ".toggle{background-color:" + String(defilementActif ? "#27ae60" : "#95a5a6") + ";color:white;border:none;border-radius:5px;}";
html += ".predefini{display:block;width:80%;max-width:300px;margin:6px auto;padding:10px;";
html += "font-size:15px;background-color:#3498db;color:white;border:none;border-radius:5px;}";
html += ".predefini:active{background-color:#2980b9;}";
html += "hr{width:80%;max-width:300px;margin:25px auto;}</style>";
html += "</head><body>";
html += "<h2>Afficher un texte sur l'ecran OLED</h2>";
html += "<form action='/set' method='GET'>";
html += "<input type='text' name='texte' placeholder='Votre texte ici' maxlength='60'>";
html += "<br><button type='submit'>Envoyer</button>";
html += "</form>";
html += "<form action='/toggleScroll' method='GET'>";
html += "<button type='submit' class='toggle'>Defilement : " + String(defilementActif ? "ON" : "OFF") + "</button>";
html += "</form>";
html += "<form action='/clear' method='GET'>";
html += "<button type='submit' class='effacer'>Effacer l'ecran</button>";
html += "</form>";
html += "<hr><h3>Textes predefinis</h3>";
for (int i = 0; i < 10; i++) {
html += "<form action='/set' method='GET'>";
html += "<input type='hidden' name='texte' value='" + String(textesPredefinis[i]) + "'>";
html += "<button type='submit' class='predefini'>" + String(textesPredefinis[i]) + "</button>";
html += "</form>";
}
html += "<p>Texte actuel : " + texteActuel + "</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleSet() {
signalerActivite();
if (server.hasArg("texte")) {
preparerTexte(server.arg("texte"));
}
server.sendHeader("Location", "/");
server.send(303);
}
void handleToggleScroll() {
signalerActivite();
defilementActif = !defilementActif;
if (!defilementActif) {
afficherFixe(texteActuel);
}
server.sendHeader("Location", "/");
server.send(303);
}
void handleClear() {
signalerActivite();
texteActuel = "";
u8g2.clearBuffer();
u8g2.sendBuffer();
server.sendHeader("Location", "/");
server.send(303);
}
void setup() {
Serial.begin(115200);
u8g2.begin();
derniereActivite = millis();
preparerTexte("Demarrage...");
WiFi.mode(WIFI_AP);
WiFi.softAP(ap_ssid, ap_password);
IPAddress ip = WiFi.softAPIP();
Serial.print("Point d'acces demarre, IP : ");
Serial.println(ip);
server.on("/", handleRoot);
server.on("/set", handleSet);
server.on("/toggleScroll", handleToggleScroll);
server.on("/clear", handleClear);
server.begin();
preparerTexte("WiFi: " + String(ap_ssid) + " IP: " + ip.toString());
derniereActivite = millis();
}
void loop() {
server.handleClient();
gererAffichage();
}




