home castoo
chapitre programmation
programmation proc�durale

Librairie Arduino esp8266 et esp32
menu sur �cran oled ssd1306
Version 5 fils

F�vrier 2021

Si vous n'avez pas d�j� utilis� l'une des librairies sai_oled ou menu_oled
il faut directement choisir la librairie lib_1306_rot
qui regroupe
toutes les fonctions des librairies cit�es ainsi que des fonctions additionnelles.

Cette version utilise 5 ports (SCL et SDA pour I2C, CLK, DT et SWD pour le bouton) sur le microprocesseur.

Utiliser des menus sur un mini-�cran.

Quand on d�veloppe sur Arduino o� ESP on a souvent besoin de proposer diff�rent choix � l'utilisateur.
Cette librairie est utilis�e � plusieurs reprises dans ce site voir les exemples dans le chapitre �lectronique.

La librairie : menu_oled

Cette librairie est tr�s souvent associ�e � la librairie sai_oled disponible �galement sur ce site, ces deux librairies fonctionnent exclusivement sur une configuration mat�rielle utilisant i2C dans ce cas les 3 fils de l'encodeur rotatif sont connect�s directement sur des ports du processeur.
(La version de ces librairies utilisant une connexion de l'encodeur rotatif sur un PCF85741 ce qui permet de n'avoir plus que 2 ports du processeur utilis�s est �galement disponible sur ce site.)
Donc en i2c pour initialiser l'objet 3 param�tres vous seront demand�s : La librairie contient trois fichiers regroup�s dans un zip que vous allez pouvoir int�grer dans votre IDE arduino : (Voir ici doc pour integrer dans IDE Arduino une librairie zip)

T�l�charger le zip : menu_oled.zip

Utilisation de la librairie menu :

Inclure la librairie de l'�cran

recuperer lib ecran oled
Attention c'est celle-ci qu'il faut t�l�charger sur le site "github", elle est diff�rente de celle qui est disponible dans l'environnement "Arduino".
On la reconnait au "w" de Wire qui doit dans notre cas �tre une majuscule. (Merci � Guy, pour cette pr�cision qui peut �viter pas mal de gal�re !).
Merci �galement � tous les contributeurs(46) de ce petit package qui contient plusieurs librairies. Vous devez charger le zip complet comme montr� sur l'image ci-contre.

#include "SSD1306Wire.h"
Inclure la librairie menu
#include "menu_oled.h"
Initialiser l'objet �cran
SSD1306Wire display(0x3c, 15, 14); // I2C sur un Wemos D1 mini (esp8266 donc gpio 4 (ou D2) > SDA & gpio 5 (ou D1) > SCL)
Initialiser l'objet menu
menu_oled mes_menus_oled(3, 13, 1, display) // init saisie (Gpio vclk, Gpio vdt, Gpio vsw et nom de l'objet LCD)
Initialiser le contenu des menus
Les diff�rents menus qui vont �tre utilis�s dans le programme peuvent �tre d�finis en variables globales ou locales.
Exemple de menus utilis�s avec l'application "volet" disponible sur ce site ici.
On voit que le maximum de choix possible est de cinq (il est possible d'en mettre 6 mais le dernier ne s'affiche pas mais il reste selectionnable).

// Choix selectionn�s dans menu
int A_menu; 
const int nb_ch_menuA = 5;
const String ch_menuA[] = {"Ouverture / Fermeture", "Param nb tour moteur", "Param date heure", "Param R�seaux", "Param seuil lumiere"};
String _ch_menuA = * ch_menuA;
int B_menu; 
const int nb_ch_menuB = 2;
const String ch_menuB[] = {"V�rif. Date Heure", "Retour"};
String _ch_menuB = * ch_menuB;
int C_menu; 
const int nb_ch_menuC = 5;
const String ch_menuC[] = {"Temps par tour", "Nb tour ouvre", "Test ouvre", "Nb tour ferme", "Test ferme"};
String _ch_menuC = * ch_menuC;
int D_menu; 
const int nb_ch_menuD = 5;
const String ch_menuD[] = {"Login Wifi", "Adresse IP mosquitto", "Login mosquitto", "Passe mosquitto", "Aff. param Wifi"};
String _ch_menuD = * ch_menuD;
	

Gestion d'un volet menu g�n�ral Dans le setup() rien � d�clarer !
Dans le code pour chaque menu
Initialisation de la valeur de retour du menu
A_menu = 0;
Lancement du menu
A_menu = mes_menus_oled.init(nb_ch_menuA, _ch_menuA);
Petit d�lai
delay(300);
Lancement du traitement en fonction du choix de l'utilisateur

	switch (A_menu){ // Menu g�n�ral
	case 0 : // Saisie du nom
		// Traitement choix 1
		break;
	case 1 : // Saisie du pr�nom
		// Traitement choix 2
		break;
	case 2 : // Affichage du nom et du pr�nom
		// Traitement choix 3
		break;
	}
	

La connexion de l'encodeur rotatif.

Encodeur rotatif en plaquette L'encodeur rotatif est disponible en brut ou sur plaquette qui doit inclure 3 r�sistances de rappel au + (positif).
Diff�rents Encodeurs rotatifs sont support�s mais l'objet a �t� cr��e avec un KY-040 30 pas.
Cette librairie a �t� d�velopp�e avec un encodeur qui comporte bien une r�sistance de rappel au positif sur les trois signaux. Il existe cependant sur le march� des encodeurs sur plaquette ou la r�sistance sur le signal "SW" n'a pas �t� install�e, pour fonctionner avec cette librairie cette r�sistance doit �tre ajout�e. Voir ici en bas de page.
Si vous utilisez un encodeur brut (sans pr� c�blage sur une plaquette) vous devez r�aliser le c�blage des r�sistance comme sur le sch�ma ci-contre.

Ecran OLED SD1306 et Encodeur rotatif sur I2C
Dans cette version le LCD et l'encodeur sont directement connect�s au microprocesseur. Sur ce sch�ma j'ai repris les num�ros de port de l'exemple si vous utilisez un autre processeur, vous devez adapter les num�ros de port et utiliser dans votre code les num�ros correspondants.

Je vous livre ici le code complet en "Open Source".
Si vous utilisez ce code, merci de mettre un lien vers ce site : https://castoo.fr

Tous ces fichiers sont dans le zip d'installation.
Bonne utilisation...


// menu_oled.h
// Affiche un menu sur LCD Oled 1306
// Affichage/Saisie depuis le menu et retourne le choix de l'utilisateur
// Castoo
// D�cembre 2019

/*
menu_oled.h
- Objet destin� � �tre utilis� avec Arduino ou ESPxxx.
Possibilit� de supporter diff�rents LCD mais l'objet a �t� cr��e avec un OLED SD1306
Possibilit� de supporter diff�rents Encodeurs rotatifs mais l'objet a �t� cr��e avec un KY-040 30 pas
Cr�ation Jean Michel Castille d�cembre 2019 / castoo.fr
Cette biblioth�que est un logiciel libre;
Vous pouvez la redistribuer et ou la modifier.
Cette biblioth�que est distribu�e dans l'espoir qu'elle sera utile,
mais SANS AUCUNE GARANTIE, sans m�me la garantie implicite de
QUALIT� MARCHANDE ou AD�QUATION � UN USAGE PARTICULIER. 
*/

#ifndef menu_oled_h
#define menu_oled_h

#include 
#include "SSD1306Wire.h"


class menu_oled{
  private:
  	SSD1306Wire *_ecran; // Ecran OLED
	uint8_t PinCLK; // Gpio x sur sortie Clk du selecteur rotatif
	uint8_t PinDT;  // Gpio x sur sortie DT du selecteur rotatif
	uint8_t PinSW;  // Gpio x sur sortie SW du selecteur rotatif
	int max_ch; // Nb max de chaine du menu
	String * _ch_menu; // Pointeur sur tableau des chaines

  public:
	// Constructeur permet de passer les cnx du bouton de commande et le nom du LCD
	menu_oled(uint8_t vclk, uint8_t vdt, uint8_t vsw, SSD1306Wire &ecran);
	
	// Initialisation du menu permet de passer le nb de choix et un tableau des chaines de choix
	uint8_t init(int nb_ch_menu, String &ch_menu);

   private:
	// Affichage du menu A
	void aff_menu(int pos);

	// Selection dans le menu A � l'aide selecteur rotatif
	uint8_t sel_menu(int max);
};

#endif
	

// menu_oled.cpp
// Affiche un menu sur LCD Oled 1306
// Affichage/Saisie depuis le menu et retourne le choix de l'utilisateur
// Castoo
// D�cembre 2019

/*
menu_oled.cpp
- Objet destin� � �tre utilis� avec Arduino ou ESPxxx.
Possibilit� de supporter diff�rents LCD mais l'objet a �t� cr��e avec un OLED SD1306
Possibilit� de supporter diff�rents Encodeurs rotatifs mais l'objet a �t� cr��e avec un KY-040 30 pas
Cr�ation Jean Michel Castille d�cembre 2019 / castoo.fr
Cette biblioth�que est un logiciel libre;
Vous pouvez la redistribuer et ou la modifier.
Cette biblioth�que est distribu�e dans l'espoir qu'elle sera utile,
mais SANS AUCUNE GARANTIE, sans m�me la garantie implicite de
QUALIT� MARCHANDE ou AD�QUATION � UN USAGE PARTICULIER. 
*/

#include "menu_oled.h"

// Constructeur permet de passer les cnx du bouton de commande et le nom du LCD
menu_oled::menu_oled(uint8_t vclk, uint8_t vdt, uint8_t vsw, SSD1306Wire &ecran){
	this->PinCLK = vclk; pinMode (this->PinCLK, INPUT); // Clk du selecteur rotatif
	this->PinDT = vdt; pinMode (this->PinDT, INPUT); // DT du selecteur rotatif
	this->PinSW = vsw; pinMode (this->PinSW, INPUT);  // SW du selecteur rotatif
	this->_ecran = &ecran; // Ecran OLED
}

// Initialisation du menu permet de passer le nb de choix et un tableau des chaines de choix
uint8_t menu_oled::init(int nb_ch_menu, String &ch_menu){
	this->_ecran->flipScreenVertically();
	this->_ecran->setFont(ArialMT_Plain_10);
	this->_ecran->setTextAlignment(TEXT_ALIGN_LEFT);
	this->max_ch = nb_ch_menu;
	this->_ch_menu = &ch_menu;
	return this->sel_menu(this->max_ch);
}

// Affichage du menu et encadrement de la valeur en cours de selection
void menu_oled::aff_menu(int pos){
	this->_ecran->clear();
	for (uint8_t i = 0; i < this->max_ch; i++) this->_ecran->drawString(0, (12*i), this->_ch_menu[i+1]);
    this->_ecran->drawRect(0, (12*pos), (this->_ch_menu[pos+1].length()*5)+2, 13);
	this->_ecran->display();
}

// Selection dans le menu � l'aide du selecteur rotatif
uint8_t menu_oled::sel_menu(int max){
	max--;
	bool B_val = false, val_clk = true, memo_clk = true;
	int B_choix = 0;
	this->aff_menu(B_choix);
	while (! B_val){
		val_clk = digitalRead(PinCLK);
		if (val_clk != memo_clk){
			if (digitalRead(PinDT) != val_clk) { B_choix++; if (B_choix > max) B_choix = max;}
				else { B_choix--; if (B_choix < 0) B_choix = 0;}
			this->aff_menu(B_choix); delay(10);
		}
		if (!(digitalRead(PinSW))) { B_val = true; } // Bouton validation
		memo_clk = val_clk;	delay(5);
	}
	this->aff_menu(B_choix);
	return B_choix;
}
	

Le fichier d'exemple d'utilisation des deux objets (mais chacun peut bien s�r �tre utilis� seul dans vos montage).
Ne pas oublier de personnaliser les PIN GPio en fonction du circuit sur lequel vous d�sirez tester l'exemple !


// test_obj_saioled.ino 
// Test des objets sai_oled et menu_oled
// Castoo https://castoo.fr
// D�cembre 2019

#include "SSD1306Wire.h"
#include "sai_oled.h"
#include "menu_oled.h"

// l'adresse I2C (ici 0x3C) peut �tre diff�rente en fonction du module utilis�
//SSD1306Wire  display(0x3c, 4, 5); // I2C sur un esp8266 donc gpio 4 > SDA & gpio 5 > SCL
SSD1306Wire  display(0x3c, 15, 14); // I2C sur un esp8266 donc gpio 4 > SDA & gpio 5 > SCL
// Pour initialiser les objets sai_oled et menu_oled il faut passer les sorties Gpio utilis�es pour le bouton rotatif
// Il est �galement necessaire de preciser le nom de l'objet �cran utilis� (celui-ci peut facilement �tre modifi�)
//sai_oled mon_sai_oled(16, 13, 0, display); // init saisie (Gpio vclk, Gpio vdt, Gpio vsw et nom de l'objet LCD)
sai_oled mon_sai_oled(3, 13, 1, display); // init saisie (Gpio vclk, Gpio vdt, Gpio vsw et nom de l'objet LCD)
//menu_oled mes_menus_oled(16, 13, 0, display); // init saisie (Gpio vclk, Gpio vdt, Gpio vsw et nom de l'objet LCD)
menu_oled mes_menus_oled(3, 13, 1, display); // init saisie (Gpio vclk, Gpio vdt, Gpio vsw et nom de l'objet LCD)
//uint8_t PinSW = 0;  // Gpio x sur sortie SW du selecteur rotatif sera utilis�e pour valider les delais d'attente
uint8_t PinSW = 1;  // Gpio x sur sortie SW du selecteur rotatif sera utilis�e pour valider les delais d'attente

int B_menu; // Choix selectionn� dans menu
const int nb_ch_menuA = 3; // choix du menu Principal
const String ch_menuA[] = {"Saisir votre nom", "Saisir votre pr�nom", "Afficher Nom Pr�nom"};
String _ch_menuA = * ch_menuA;
String nom = "";
String prenom = "";
String ch_result = "";

// Initialisation
void setup() { 
	pinMode(PinSW, INPUT); // Sortie SW du selecteur rotatif
	// Init OLED
	display.init();
	display.flipScreenVertically();
	display.setFont(ArialMT_Plain_24);
	display.setTextAlignment(TEXT_ALIGN_CENTER);
	display.clear();
	// Init des objets sai_oled
	mon_sai_oled.init(); // Initialisation ecran pour saisie OLED
	mon_sai_oled.sortie_deb(false); // Invalide sortie balayage apr�s chaque saisie (+ rapide mais perso, j'aime pas !) � tester � true...
} 

// Boucle principale
void loop(){
	delay(200);
	B_menu = 0;
	B_menu = mes_menus_oled.init(nb_ch_menuA, _ch_menuA);
	delay(300);
	if (B_menu == 0) {
		// Saisie du nom
		mon_sai_oled.init(); // Initialisation ecran OLED pour saisie
		nom = mon_sai_oled.aff_menu_Alpha(); // On lance la saisie
	}
	else if (B_menu == 1) {
		// Saisie du pr�nom
		mon_sai_oled.init(); // Initialisation ecran OLED pour saisie
		prenom = mon_sai_oled.aff_menu_Alpha(); // On lance la saisie
	}
	else if (B_menu == 2) {
		// Affichage du nom et du pr�nom
		delay(200); // Anti rebond bouton
		ch_result = nom + " " + prenom;
		if(ch_result == " ") ch_result = "Vous devez faire une saisie !";
		display.setFont(ArialMT_Plain_10);
		display.setTextAlignment(TEXT_ALIGN_CENTER);
		display.clear();
		display.drawString(64, 25, ch_result);
		display.display();
		while(digitalRead(PinSW)){delay(10);} // On attend que le bouton soit press� pour sortir de l'affichage
		delay(400);
	}
}
	

Retour accueil programmation

Bricolage Robotique Informatique Peinture Voyage
T�l�c. portail Le robot "m�cano" Astuces informatique Henri Bertrou Auvergne
Bat. Iphone 6S Le robot "solaire" R�seau couche app. Jean-Michel Castille Floride
Robot piscine Servo et IR" R�seau Les couches New York
Xiaomi M365 Le robot "thymio" R�seaux Outils L'Ouest am�ricain
Mac Mini Le robot "Rovio" Unit�s grandeur inf. L'Ile Maurice
Putty SSH Windows L'Italie / Venise
Bases Raspberry Tunisie
Termius IPhone/IPad Grece
Le vieux ZX 81
...
Navigation La Rochelle CNC / Imp3D Electronique Programmation
Rencontre dauphins Les Minimes Construction CNC Alim. TPL 5110 Doc. programme
Analyse NMEA 0183 Le Vieux port CNC du commerce Carte ESP8266 Indent programme
graph. NMEA 0183 L'Ile de R� Martyr CNC ESP8266 1 relai Prog. objet
Analyse trames AIS A visiter R�a. imp. 3D ESP8266 Alarme Prog. proc�durale
Analyse AIS TCP-IP Cura impression 3D ESP8266 MQTT
Sortie en ketch Plateau CR10 ESP8266 Temp.
Echange GPS C80 An�mom�tre.
HP Sun-Odyssey CNC / 3D en vrac MCP9808 Librairie
LCD yanmar Saisie Oled
Testeur nmea esp1 i2c