Grove 16x2 LCD Series

From
Jump to: navigation, search

Grove - 16x2 LCD Series[edit]

16 Characters * 2 Lines
Operating Voltage : 3.3V / 5V

images[edit]

ici on utilise le (White on Blue) V1.0

16x2 LCD White on Blue 01.jpg 16x2 LCD White on Blue 02.jpg

liens externes[edit]

http://wiki.seeedstudio.com/Grove-16x2_LCD_Series LCD wiki Grove-16x2

https://www.seeedstudio.com/Grove-16x2-LCD-White-on-Blue.html Shop Grove-16x2_LCD

Connectique[edit]

interface : I2C-bus
I2C Adresse: 0X3E

https://wiki.myows.top/index.php?title=I2cScanner I2cScanner

on va chercher l'adresse I2C, on regarde sur l'écran série

Scanning... I2C device found at address 0x3E  ! done
c'est la même indiqué par le constructeur.

16x2 LCD White on Blue Connect 01.jpg

Librairie Seed-Studio[edit]

install an Arduino library

https://github.com/Seeed-Studio/Grove_LCD_RGB_Backlight Librairie

https://github.com/Seeed-Studio/Grove_LCD_RGB_Backlight/archive/master.zip Librairie fichier Zip

Add Library Zip.png

HelloWorld Grove LCD.ino

Code 2 @ rgb_lcd.h ✅[edit]

Affichage du texte "hello, world!" et dans la deuxième ligne affichage d'un compteur depuis zéro, +1 chaque seconde, 0,1,2, 3, ...51...

https://github.com/Seeed-Studio/Grove_LCD_RGB_Backlight Librairie

Seeeduino-nano-connect.png Pinout Grove Shield Arduino Nano.JPG 16x2 LCD White on Blue 01.jpg

Seeeduino-nano / (port i2c) ✅
16x2 LCD White on Blue

Grove Base for XIAO 1.PNG XIAO-ESP32S3 1.PNG 16x2 LCD White on Blue 01.jpg

Grove Base for XIAO (Port i2c) ✅
XIAO-ESP32S3
16x2 LCD White on Blue

#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

/*
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
*/

void setup() 
{
    // set up the LCD's number of columns and rows:
    lcd.begin(16, 2);
    
    //lcd.setRGB(colorR, colorG, colorB);
    
    // Print a message to the LCD.
    lcd.print("hello, world!");

    delay(1000);
}

void loop() 
{
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 1);
    // print the number of seconds since reset:
    lcd.print(millis()/1000);

    delay(100);
}

un léger changement : pour "hello, world!"

https://github.come/Seed-Studio/Grove_LCD_RGB_Backlight Librairie

Grove Base for XIAO 1.PNG XIAO-ESP32S3 1.PNG 16x2 LCD White on Blue 01.jpg

Grove Base for XIAO (Port i2c) ✅
XIAO-ESP32S3
16x2 LCD White on Blue

#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;

void setup() {
  lcd.begin(16, 2); // 16 colonnes, 2 lignes
  // lcd.setRGB(0, 128, 64); // Couleur de fond (vert doux)
  lcd.setCursor(0, 0);
  lcd.print("Hello ESP32S3!");
}

void loop() {
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  delay(1000);
}



Code 3 @ LiquidCrystal_I2C.h ❌[edit]

ceci ne fonctionne pas ! ⊗ ❌ ⛔ avec :
Seeeduino-nano +
Port I2c +
16x2 LCD White on Blue

https://github.com/johnrickman/LiquidCrystal_I2C Librairy

https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c


#include <LiquidCrystal_I2C.h>

// I2C address of the LCD (check your specific LCD if it's different)
#define LCD_I2C_ADDRESS 0x01

// Define the LCD as an object
LiquidCrystal_I2C lcd(LCD_I2C_ADDRESS, 16, 2); // 16 columns, 2 rows

void setup() {
  // Initialize the LCD
  lcd.init();
  // Turn on the backlight
  // lcd.backlight();
  // Optional: Set custom characters if needed
  // lcd.createChar(0, custom_char_data);
  // You can use the custom_char_data array from a tool like LCD-Character-Creator (https://maxpromer.github.io/LCD-Character-Creator/)
}
void loop() {
  // Clear the LCD (optional)
  lcd.clear();
  // Set the cursor to the desired position (column, row)
  // 0,0 is the top-left corner
  lcd.setCursor(0, 0); 
  // Print text to the LCD
  lcd.print("Hello, World!");
  // Optionally, delay for a period
  delay(2000);
}



Affichage "Hello" @ LiquidCrystal_I2C_ESP32[edit]

https://github.com/iakop/LiquidCrystal_I2C_ESP32 Librairie

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3E, 16, 2); // Adresse I2C 0x3E pour Grove LCD

void setup() {
  Wire.begin(); // Initialise I2C
  lcd.init();   // Initialise l'écran
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Hello ESP32!");
}

void loop() {
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  delay(1000);
}



Affichage "Hello" @ Wire.h ✅[edit]

Grove Base for XIAO 1.PNG XIAO-ESP32S3 1.PNG 16x2 LCD White on Blue 01.jpg

Grove Base for XIAO (Port i2c) ✅
XIAO-ESP32S3
16x2 LCD White on Blue

LCD I2C Adresse 0X3E
RGB I2C Adresse 0X62
#include <Wire.h>

#define LCD_ADDR 0x3E  // Adresse I2C du Grove LCD
#define COMMAND 0x00   // Mode commande
#define DATA    0x40   // Mode données

void sendCommand(uint8_t cmd) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(COMMAND);
  Wire.write(cmd);
  Wire.endTransmission();
  delay(2);
}

void sendData(uint8_t data) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(DATA);
  Wire.write(data);
  Wire.endTransmission();
  delay(2);
}

void initLCD() {
  delay(50); // Attente après alimentation
  sendCommand(0x38); // Fonction : 2 lignes, 8 bits
  sendCommand(0x39); // Fonction étendue
  sendCommand(0x14); // Oscillateur
  sendCommand(0x70); // Contraste (ajuster si nécessaire)
  sendCommand(0x56); // Puissance + icône + contraste
  sendCommand(0x6C); // Activation du booster
  delay(200);
  sendCommand(0x38); // Retour mode normal
  sendCommand(0x0C); // Affichage ON, curseur OFF
  sendCommand(0x01); // Clear
  delay(2);
}

void printText(const char* text) {
  while (*text) {
    sendData(*text++);
  }
}

void setup() {
  Wire.begin();
  delay(100);
  initLCD();
  printText("Hello ESP32!Wire");
}

void loop() {
  // Rien ici pour l'instant
}



"Compteur dynamique avec curseur" @ Wire.h ✅[edit]

Grove Base for XIAO 1.PNG XIAO-ESP32S3 1.PNG 16x2 LCD White on Blue 01.jpg

Grove Base for XIAO (Port i2c) ✅
XIAO-ESP32S3
16x2 LCD White on Blue

LCD I2C Adresse 0X3E
RGB I2C Adresse 0X62


#include <Wire.h>

#define LCD_ADDR 0x3E
#define COMMAND 0x00
#define DATA    0x40

void sendCommand(uint8_t cmd) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(COMMAND);
  Wire.write(cmd);
  Wire.endTransmission();
  delay(2);
}

void sendData(uint8_t data) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(DATA);
  Wire.write(data);
  Wire.endTransmission();
  delay(2);
}

void setCursor(uint8_t col, uint8_t row) {
  uint8_t pos = (row == 0) ? 0x80 + col : 0xC0 + col;
  sendCommand(pos);
}

void clearLCD() {
  sendCommand(0x01); // Clear display
  delay(2);
}

void initLCD() {
  delay(50);
  sendCommand(0x38);
  sendCommand(0x39);
  sendCommand(0x14);
  sendCommand(0x70); // contraste
  sendCommand(0x56);
  sendCommand(0x6C);
  delay(200);
  sendCommand(0x38);
  sendCommand(0x0C); // affichage ON
  clearLCD();
}

void printText(const char* text) {
  while (*text) {
    sendData(*text++);
  }
}

void setup() {
  Wire.begin();
  initLCD();
  setCursor(0, 0);
  printText("Compteur:");
}

void loop() {
  static int count = 0;
  setCursor(0, 1); // ligne 2
  char buffer[16];
  snprintf(buffer, sizeof(buffer), "Valeur: %4d", count++);
  printText(buffer);
  delay(1000);
}



Internet Clock 1 LCD "16x2 I2C" @ Wire.h ❌[edit]

Bibliothèques à installer :

https://github.com/me-no-dev/ESPAsyncWebServer 'ESPAsyncWebServer'
https://github.com/me-no-dev/AsyncTCP 'AsyncTCP'
La Bibliothèque 'Preferences' est ✅ déjà incluse dans le core ESP32

ceci ne fonctionne pas ❎ à cause de 'Preferences' ❌

SQUARED OK 🆗 & #x1F197;
ANTENNA BARS 📶 & #x1F4F6;
WIFI 🛜 & #128732;
BRIGHTNESS SYMBOL 🔆 & #x1F506;
CROSS MARK ❌ & #x274C;
CROSS MARK ❎ & #x274E;
WHITE HEAVY ✅ & #x2705;
NO ENTRY ⛔ & #x26D4;
CLOCK 🕒 & #x1F552;
ROUND PUSHPIN 📍 & #x1F4CD;

https://www.quackit.com/character_sets/emoji/emoji_v3.0/unicode_emoji_v3.0_characters_all.cfm

#include <WiFi.h>
#include <Preferences.h>
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <time.h>

// LCD I2C
#define LCD_ADDR 0x3E
#define COMMAND 0x00
#define DATA	0x40

Preferences prefs;
AsyncWebServer server(80);

// Variables config
String wifiSSID;
String wifiPASS;
String timezone;

const char* htmlPage = R"rawliteral(
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>ESP32 Config</title></head>
<body>
<h1>Configuration ESP32</h1>
<form action="/save" method="GET">
<label>WiFi SSID:</label><br>
<input type="text" name="ssid" value="%SSID%"><br>
<label>WiFi Password:</label><br>
<input type="password" name="pass" value="%PASS%"><br><br>
<label>Fuseau horaire:</label><br>
<select name="tz">
	<option value="CET-1CEST,M3.5.0/2,M10.5.0/3" %TZ1%>Europe/Zurich</option>
	<option value="UTC0" %TZ2%>UTC</option>
</select><br><br>
<input type="submit" value="Enregistrer">
</form>
</body>
</html>
)rawliteral";

String processor(const String& var) {
	if (var == "SSID") return wifiSSID;
	if (var == "PASS") return wifiPASS;
	if (var == "TZ1") return (timezone == "CET-1CEST,M3.5.0/2,M10.5.0/3") ? "selected" : "";
	if (var == "TZ2") return (timezone == "UTC0") ? "selected" : "";
	return String();
}

// LCD functions
void sendCommand(uint8_t cmd) {
	Wire.beginTransmission(LCD_ADDR);
	Wire.write(COMMAND);
	Wire.write(cmd);
	Wire.endTransmission();
	delay(2);
}

void sendData(uint8_t data) {
	Wire.beginTransmission(LCD_ADDR);
	Wire.write(DATA);
	Wire.write(data);
	Wire.endTransmission();
	delay(2);
}

void setCursor(uint8_t col, uint8_t row) {
	uint8_t pos = (row == 0) ? 0x80 + col : 0xC0 + col;
	sendCommand(pos);
}

void clearLCD() {
	sendCommand(0x01);
	delay(2);
}

void initLCD() {
	delay(50);
	sendCommand(0x38);
	sendCommand(0x39);
	sendCommand(0x14);
	sendCommand(0x70);
	sendCommand(0x56);
	sendCommand(0x6C);
	delay(200);
	sendCommand(0x38);
	sendCommand(0x0C);
	clearLCD();
}

void printText(const char* text) {
	while (*text) {
	 sendData(*text++);
	}
}

void setup() {
	Serial.begin(115200);
	Wire.begin();
	initLCD();

	// Charger paramètres
	prefs.begin("config", false);
	wifiSSID = prefs.getString("ssid", "Your_wifi_SSID");
	wifiPASS = prefs.getString("pass", "Wifi_password");
	timezone = prefs.getString("tz", "CET-1CEST,M3.5.0/2,M10.5.0/3");

	// Connexion Wi-Fi
	WiFi.begin(wifiSSID.c_str(), wifiPASS.c_str());
	if (WiFi.waitForConnectResult() != WL_CONNECTED) {
			Serial.println("WiFi non trouvé, démarrage en AP...");
			WiFi.softAP("ESP32_Config", "12345678");
	} else {
			Serial.println("Connecté au WiFi");
	}

	// Serveur Web
	server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
			request->send_P(200, "text/html", htmlPage, processor);
	});

	server.on("/save", HTTP_GET, [](AsyncWebServerRequest *request){
			if (request->hasParam("ssid")) wifiSSID = request->getParam("ssid")->value();
			if (request->hasParam("pass")) wifiPASS = request->getParam("pass")->value();
			if (request->hasParam("tz")) timezone = request->getParam("tz")->value();

			prefs.putString("ssid", wifiSSID);
			prefs.putString("pass", wifiPASS);
			prefs.putString("tz", timezone);

			request->send(200, "text/html", "<h1>Paramètres enregistrés. Redémarrage...</h1>");
			delay(2000);
			ESP.restart();
	});

	server.begin();

	// Fuseau horaire
	configTime(0, 0, "pool.ntp.org", "time.nist.gov");
	setenv("TZ", timezone.c_str(), 1);
	tzset();
}

void loop() {
	struct tm timeinfo;
	if (!getLocalTime(&timeinfo)) {
			Serial.println("Impossible d'obtenir l'heure");
			return;
	}

	char timeStr[17];
	snprintf(timeStr, sizeof(timeStr), "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);

	char dateStr[17];
	snprintf(dateStr, sizeof(dateStr), "%02d/%02d/%04d", timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900);

	setCursor(0, 0);
	printText(timeStr);
	setCursor(0, 1);
	printText(dateStr);

	delay(1000);
}



Internet Clock 2 LCD "16x2 I2C" @ Wire.h 🛜 ✅[edit]

Grove Base for XIAO 1.PNG XIAO-ESP32S3 1.PNG 16x2 LCD White on Blue 01.jpg

Grove Base for XIAO (Port i2c) ✅
XIAO-ESP32S3 📶
16x2 LCD White on Blue

LCD I2C Adresse 0X3E
RGB I2C Adresse 0X62
#include <Wire.h>
#include <WiFi.h>
#include <time.h>

#define LCD_ADDR 0x3E
#define COMMAND 0x00
#define DATA    0x40

const char* ssid = "Mon_SSID";
const char* password = "Mon_pass";

// Fuseau horaire suisse avec heure d’été automatique
const char* timeZone = "CET-1CEST,M3.5.0,M10.5.0/3";
const char* ntpServer = "pool.ntp.org";

void sendCommand(uint8_t cmd) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(COMMAND);
  Wire.write(cmd);
  Wire.endTransmission();
  delay(2);
}

void sendData(uint8_t data) {
  Wire.beginTransmission(LCD_ADDR);
  Wire.write(DATA);
  Wire.write(data);
  Wire.endTransmission();
  delay(2);
}

void setCursor(uint8_t col, uint8_t row) {
  uint8_t pos = (row == 0) ? 0x80 + col : 0xC0 + col;
  sendCommand(pos);
}

void clearLCD() {
  sendCommand(0x01);
  delay(2);
}

void initLCD() {
  delay(50);
  sendCommand(0x38);
  sendCommand(0x39);
  sendCommand(0x14);
  sendCommand(0x70);
  sendCommand(0x56);
  sendCommand(0x6C);
  delay(200);
  sendCommand(0x38);
  sendCommand(0x0C);
  clearLCD();
}

void printText(const char* text) {
  while (*text) {
    sendData(*text++);
  }
}

void clearLine(uint8_t row) {
  setCursor(0, row);
  for (int i = 0; i < 16; i++) {
    sendData(' ');
  }
  setCursor(0, row);
}

void setup() {
  Wire.begin();
  initLCD();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }

  configTzTime(timeZone, ntpServer);
}

void loop() {
  struct tm timeInfo;
  if (!getLocalTime(&timeInfo)) {
    clearLine(0);
    printText("Erreur NTP");
    delay(1000);
    return;
  }

  // Ligne 1 : heure au format 24h
  char line1[17];
  snprintf(line1, sizeof(line1), "%02d:%02d:%02d", timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);

  // Ligne 2 : date au format JJ/MM/AAAA
  char line2[17];
  snprintf(line2, sizeof(line2), "%02d/%02d/%04d", timeInfo.tm_mday, timeInfo.tm_mon + 1, timeInfo.tm_year + 1900);

  // Centrage : calculer le décalage pour centrer chaque ligne
  int len1 = strlen(line1);
  int len2 = strlen(line2);
  int pad1 = (16 - len1) / 2;
  int pad2 = (16 - len2) / 2;

  // Nettoyer et afficher ligne 1
  clearLine(0);
  setCursor(pad1, 0);
  printText(line1);

  // Nettoyer et afficher ligne 2
  clearLine(1);
  setCursor(pad2, 1);
  printText(line2);

  delay(1000);
}