SDA = A4
SCL = A5
// Inclure les fonctions (librairie) du LCD #include "rgb_lcd.h" /*****************************************/ #define UNE_SECONDE 1000 #define LCD_NB_LIGNE 2 #define LCD_NB_COLONNE 16 #define LCD_LIGNE2 1 #define LCD_PREMIERE_COLONNE 0 /*****************************************/ // Définir une variable globale* pour gérer le LCD - // * Explications en classe rgb_lcd lcd; void setup() { // Définir les specifications du LCD (16 colonnes, 2 lignes) lcd.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); // Aficher sur le LCD lcd.print("Bonjour 420 ;-)"); delay(UNE_SECONDE); // Déplacer le curseur du LCD sur la ligne 1, colonne 0 lcd.setCursor( LCD_PREMIERE_COLONNE , LCD_LIGNE2 ); lcd.print("Objets connectes"); } // setup() void loop() {}
// Inclure les fonctions du LCD
#include "rgb_lcd.h"
// Définir un objet LCD (rgb_lcd).
// Il servira à contrôler l'écran LCD.
rgb_lcd lcd;
const int colorR = 255; // Intensité de rouge
const int colorG = 255; // Intensité de vert
const int colorB = 255; // Intensité de bleu
void setup()
{
// Initialiser le LCD en précisant le nb de lignes (2) de colonnes (16).
lcd.begin(16, 2);
// Renseigner la couleur de fond de l'écran LCD.
lcd.setRGB(colorR, colorG, colorB);
// Afficher un message sur l'écran LCD
lcd.print("Bonjour 420 ;-)");
delay(1000);
}
void loop()
{
// Placer le curseur sur la deuxième ligne, première colonne.
// Ligne 1 = 0, Colonne 1 = 0
lcd.setCursor(0, 1);
// Afficher le nombre de secondes depuis le démarrage de l'application.
// Note: La fn millis() retourne le nombre de ms écoulées depuis le début de l'application.
lcd.print(millis()/1000);
// Arrêter le programme pendant une seconde
delay(1000);
}
3.2 – Analyser et comprendre toutes les lignes du code source.
3.3 – Tester l’application.
Modifier le code précédent pour:
Note: Qu’arrive t’il à la valeur de la variable ‘temps’ lorsque le nombre est supérieur à 32,767?
Écrire un programme qui affiche la valeur d’un potentiomètre, connecté sur la broche de votre choix, sur l’écran LCD, sur fond bleu pale, en respectant le format suivant:
Val. Pot: [0..1023] Volume : [0..10]
La valeur du pot doit être affichée en temps réel. C-a-d, si vous tournez le Pot alors sa valeur change à l’écran.
De plus, il faut afficher un niveau de volume, à partir de la valeur du potentiomètre, entre 0 et 10, Note: Utiliser la fonction map() pour ramener la valeur du Pot entre 0 et 10.
NOTE: Il ne FAUT PAS réafficher les textes « Val. Pot: » et « Volume : » dans la fonction loop(). De plus, il faut effacer l’espace qu’occupaient les valeurs POT et Volume à l’itération précédente.
La solution est ici.
Écrire un programme qui affiche sur l’écran LCD, le temps qui passe et le nombre de fois que le bouton (D2) est appuyé.
Voici un aperçu de l’écran de départ:
Ligne1: Alarme TI-CSTJ Ligne2: Version 1.0b
délai de 3 secondes suivi de :
Ligne1: Temps: 0 sec
Ligne2: Compteur: 9999999
NOTE: Il ne faut pas réafficher tout le texte sur le LCD, seulement le contenu de compteur et temps. Indice: setCursor().
Défi supplémentaire, continuer à afficher le temps qui passe même si le bouton est enfoncé ?.
/* Exemple d'utilisation d'un LCD sur Wokwi Connexion des broches: LCD.SDA -> Uno.A4 LCD.SCL -> Uno.A5 LCD.GND -> Uno.GND LCD.VCC -> Uno.5V **Voir 'Arduino Uno pinout' pour référence. */ #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C ecranLCD(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE); /*****************************************/ #define BOUTON 2 #define BOUTON_DELAI_REBOND 5 #define DELAI_MSG_DEBUT 3000 #define LCD_DELAI 50 #define LCD_NB_LIGNE 2 #define LCD_NB_COLONNE 16 #define LCD_LIGNE2 1 #define LCD_PREMIERE_COLONNE 0 #define LCD_POSITION_COMPTEUR 10 #define LCD_ADRESSE_I2C 0x27 /*****************************************/ void setup() { pinMode(BOUTON, INPUT); ecranLCD.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); ecranLCD.print("Debut du projet"); // Placer le curseur au début de la ligne no 2 // Écrire votre prenom ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE2); ecranLCD.print("Version 1.0beta"); delay(DELAI_MSG_DEBUT); ecranLCD.clear(); // Effacer l'écran ecranLCD.print("Alarme TI-CSTJ"); ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE2); ecranLCD.print("Compteur: "); } // setup() void loop() { static unsigned int compteurBouton = 0; int etatBouton = digitalRead(BOUTON); delay(BOUTON_DELAI_REBOND); // debounce du bouton ecranLCD.setCursor(LCD_POSITION_COMPTEUR, LCD_LIGNE2); ecranLCD.print(compteurBouton); if ( etatBouton == HIGH) { compteurBouton++; while (digitalRead(BOUTON)) ; delay(BOUTON_DELAI_REBOND); } } // loop()
{ "version": 1, "author": "Anonymous maker", "editor": "wokwi", "parts": [ { "type": "wokwi-arduino-uno", "id": "uno", "top": 81.25, "left": -2.09, "attrs": {} }, { "type": "wokwi-pushbutton", "id": "btn1", "top": -4.65, "left": 191.37, "attrs": { "color": "green" } }, { "type": "wokwi-resistor", "id": "r1", "top": 21.93, "left": 100.76, "attrs": { "value": "1000" } }, { "type": "wokwi-lcd1602", "id": "lcd1", "top": -165.75, "left": -26.9, "attrs": { "pins": "i2c" } } ], "connections": [ [ "btn1:2.l", "uno:2", "green", [ "h-0.07", "v18.52", "h55.44" ] ], [ "uno:5V", "btn1:1.l", "red", [ "v24.7", "h-184.65", "v-16.33" ] ], [ "r1:1", "uno:GND.1", "green", [ "v22.14", "h27.61" ] ], [ "r1:2", "btn1:2.l", "green", [ "v0" ] ], [ "lcd1:SCL", "uno:A5.2", "green", [ "h-42", "v98.6", "h137.19" ] ], [ "lcd1:SDA", "uno:A4.2", "green", [ "h-52.33", "v114.74", "h167.43", "v85.56", "h0.74" ] ], [ "lcd1:GND", "r1:1", "black", [ "h-67.08", "v152.92" ] ], [ "lcd1:VCC", "btn1:1.l", "red", [ "h-60.44", "v8.44" ] ] ] }
Pour avoir accès au projet, il faut cliquer sur l’image ?.
NOTE: Pour renseigner l’adresse I2C du deuxième LCD, il faut ajouter l’attribut suivant au schéma json:
"attrs": { "i2c-address": "0x26" }
#define WOKWI /*****************************************/ #define BOUTON 2 #define BOUTON_DELAI_REBOND 5 #define DELAI_MSG_DEBUT 3000 #define LCD_DELAI 50 #define LCD_NB_LIGNE 2 #define LCD_NB_COLONNE 16 #define LCD_LIGNE2 1 #define LCD_PREMIERE_COLONNE 0 #define LCD_POSITION_COMPTEUR 10 #define LCD_ADRESSE_I2C 0x27 /*****************************************/ #ifdef WOKWI #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C ecranLCD(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE); #else #include "rgb_lcd.h" rgb_lcd ecranLCD; #endif void setup() { pinMode(BOUTON, INPUT); ecranLCD.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); ecranLCD.print("Debut du projet"); // Placer le curseur au début de la ligne no 2 // Écrire votre prenom ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE2); ecranLCD.print("Version 1.0beta"); delay(DELAI_MSG_DEBUT); ecranLCD.clear(); // Effacer l'écran ecranLCD.print("Alarme TI-CSTJ"); ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE2); ecranLCD.print("Compteur: "); } // setup() void loop() { static unsigned int compteurBouton = 0; int etatBouton = digitalRead(BOUTON); delay(BOUTON_DELAI_REBOND); // debounce du bouton ecranLCD.setCursor(LCD_POSITION_COMPTEUR, LCD_LIGNE2); ecranLCD.print(compteurBouton); if ( etatBouton == HIGH) { compteurBouton++; while (digitalRead(BOUTON)) ; delay(BOUTON_DELAI_REBOND); } } // loop()
Utilisation de la librairie Streaming.h (Attention, sur Wokwi il faut ajouter la librairie au projet via le panneau Library Manager )
4.3.1 – Installer la librairie (Streaming by Mikal Hart)
4.3.2 – Exemple d’utilisation de la librairie Streaming:
/* Utilisation du lcd_rgb avec un IO-Stream */ // Inclure les fonctions de le LCD #include "rgb_lcd.h" #include <Streaming.h> #define ECRAN_NB_LIGNES 2 #define ECRAN_NB_COLONNES 16 // Définir une chaine de caractères char message[17] = "Bonjour Le Monde"; // Définir un objet de type rgb_lcd rgb_lcd ecran; void setup() { ecran.begin(ECRAN_NB_COLONNES, ECRAN_NB_LIGNES); ecran << message; } void loop() {}
Référence sur Wikipedia
La fonction sprintf() – de la librairie <stdio.h> – permet de construire une chaine de caractères à partir de plusieurs éléments de type différents.
Un peu à la manière de :
‘Volume: ‘ + valeurVolume + ‘, Température: ‘ + valeurTemperature + ‘c’ ,
pour produire le résultat suivant:
Volume: 8, Température: 22c
Pour arriver à ce résultat avec sprintf(), il faut utiliser la syntaxe suivante:
#define NB_MAX_DE_CARACTERES 81 { char uneVariablePourPlacerLeResultat[NB_MAX_DE_CARACTERES; int volume = 8; double temp = 22.2 // %n permet d'insérer une variable dans la chaine sprintf(uneVariablePourPlacerLeResultat, "Volume: %d, Température: %fc", volume, temp); }
Format Sortie Exemple d & i Signed decimal integer 420 u Unsigned decimal integer 47235 o Unsigned octal 610 x Unsigned hexadecimal integer 7fa X Unsigned hexadecimal integer (uppercase) 7FA f Decimal floating point, lowercase 392.65 F Decimal floating point, uppercase 392.65 e Scientific notation (mantissa/exponent), lowercase 3.9265e+2 E Scientific notation (mantissa/exponent), uppercase. 3.9265E+2 g Use the shortest representation: %e or %f. 392.65 G Use the shortest representation: %E or %F 392.65 a Hexadecimal floating point, lowercase -0xc.90fep-2 A Hexadecimal floating point, uppercase -0XC.90FEP-2 c Character a s String of characters 420-1C4 p Pointer address b8000000 n Nothing printed.
Voir ici pour le projet sur Wokwi
// Solution du laboratoire: DOC11.3.5 #include <LiquidCrystal_I2C.h> #define LCD_LIGNE_NO_1 0 #define LCD_LIGNE_NO_2 1 #define LCD_DEBUT_LIGNE 0 #define LCD_NB_LIGNE 4 #define LCD_NB_COLONNE 20 #define DELAI_MSG_OUVERTURE 1000 #define LCD_ADRESSE_I2C 0x27 #define NOM_PROJET "Labo DOC11.4.4.2" #define VERSION_PROJET "sprintf et snprintf" #define LONGUEUR_MSG LCD_NB_COLONNE + 1 LiquidCrystal_I2C ecranLCD(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE); char msg[LONGUEUR_MSG]; void setup() { ecranLCD.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); ecranLCD.print(NOM_PROJET); ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_2); sprintf(msg, "%s", VERSION_PROJET); ecranLCD.print(msg); delay(DELAI_MSG_OUVERTURE); ecranLCD.clear(); } // setup() void loop() { static int compteur = 0; int temperature = 22; String moi = "moi moi"; // char moi[] = "moi moi"; float pi = 3.141592; // Exemple 01 ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_1); sprintf(msg, "c: %d, t: %d", compteur++, temperature); ecranLCD.print(msg); ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_2); sprintf(msg, "Je suis %s", moi.c_str()); ecranLCD.print(msg); // Exemple 02 - Forcer des espaces à gauche /* ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_1); sprintf(msg, "c: %5d, t: %d", compteur++, temperature); ecranLCD.print(msg); */ // Exemple 03 - Forcer des 0 à gauche /* ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_1); sprintf(msg, "c: %05d, t: %d", compteur++, temperature); ecranLCD.print(msg); */ // Exemple 04 - Les nombres réels // La fonction sprintf de Arduino IDE ne supporte pas les nombres réels (float, double) /* ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_1); sprintf(msg, "PI = %f", pi); ecranLCD.print(msg); */ // Voici une solution /* ecranLCD.setCursor(LCD_DEBUT_LIGNE, LCD_LIGNE_NO_1); #define LONGUEUR_CHAINE 8 #define NB_DECIMALES 6 char szF[LONGUEUR_CHAINE + 1]; dtostrf( pi, LONGUEUR_CHAINE, NB_DECIMALES, szF ); sprintf( msg, "PI = %s", szF ); ecranLCD.print(msg); */ } // loop()
— > Référence pour la fonction dtostrf()
#define MACRO
#ifdef MACRO
Inclure ceci seulement si MACRO est définie
#endif /* MACRO */
// -------------------------------------------
#ifdef ABCD
std::cout << "1: yes\n";
#else
std::cout << "1: no\n";
#endif
// -------------------------------------------
#ifndef MACRO
Inclure ceci seulement si MACRO n'est pas définie
#endif /* MACRO */
// -------------------------------------------
#define CLIENT 2
#if (CLIENT == 2)
const byte port_porte = 3;
#else
const byte port_porte = 2;
#endif
Voici un exemple:
#include "Streaming.h" #define CLIENT 1 #if (CLIENT == 2) const byte port_porte = 3; #else const byte port_porte = 2; #endif void setup() { Serial.begin(9600); Serial << "port_porte = " << port_porte << endl; } void loop() {}
/* Utilisation du lcd_rgb avec un IO-Stream */ // Inclure les fonctions i2C #include <Wire.h> // Inclure les fonctions de le LCD #include "rgb_lcd.h" #include <Streaming.h> #define DEBUG #define ECRAN_NB_LIGNES 2 #define ECRAN_NB_COLONNES 16 // Définir une chaine de caractères char message[80]; char ligne_lcd[17]; // Définir un objet de type rgb_lcd rgb_lcd ecran; void setup() { int i = 99; float pi = 3.14; char c = '@'; char texte[] = "Une chaine"; Serial.begin(9600); ecran.begin(ECRAN_NB_COLONNES, ECRAN_NB_LIGNES); #ifdef DEBUG Serial << "Début du programme\n\n"; #endif ecran << "i=" << i; ecran << ", pi=" << pi; // Déplacer le curseur à la ligne 2, colonne 1 ecran.setCursor(0, 1); ecran << "c=" << c; // Attendre 2 sec puis effacer l'écran delay(2000); ecran.clear(); ecran << texte; // Déplacer le curseur à la ligne 2, colonne 1 ecran.setCursor(0, 1); #ifdef DEBUG // Sous Arduino, sprintf n'implémente pas les float. sprintf(message, "i = %d, pi = %f, c = %c, texte = %s", i, pi, c, texte); Serial << message; #endif unsigned int entierNonSigne = 0b10101010101010; sprintf(message, "entierNonSigne : %u, hex : %x, HEX : %X, Octal = %o", entierNonSigne , entierNonSigne, entierNonSigne, entierNonSigne); Serial << endl << endl << message; } void loop() {}
/* Utilisation du lcd_rgb avec un IO-Stream */ // Inclure les fonctions i2C #include <Wire.h> // Inclure les fonctions de le LCD #include "rgb_lcd.h" // #define DEBUG #define ECRAN_NB_LIGNES 2 #define ECRAN_NB_COLONNES 16 #define POSITION_MILLISECONDE 07 // Définir une chaine de caractères char ligneTexte[17]; // Définir un objet de type rgb_lcd rgb_lcd ecran; void setup() { ecran.begin(ECRAN_NB_COLONNES, ECRAN_NB_LIGNES); } void loop() { ecran.setCursor(POSITION_MILLISECONDE, 0); // %9 = 9 car minimun pour l'impression de la valeur // lu = entier long, non signé sprintf(ligneTexte, "%9lu", millis()); ecran.print(ligneTexte); ecran.setCursor(POSITION_MILLISECONDE, 1); // %09 = 9 car minimun pour l'impression de la valeur, complété par des zéros à gauche. sprintf(ligneTexte, "%09lu", millis()); ecran.print(ligneTexte); }
#include <Wire.h> #include "rgb_lcd.h" rgb_lcd lcd; int unCaractere = 'a'; void setup() { // Définir la taille de l'écran lcd.begin(16, 2); // afficher le curseur lcd.cursor(); } void loop() { // changer la direction d'affichage si 'm': if (unCaractere == 'm') { // afficher de roite à gauche lcd.rightToLeft(); } // changer la direction d'affichage si 's': if (unCaractere == 's') { // afficher de gauche à droite lcd.leftToRight(); } // Si 'z' alors reset if (unCaractere > 'z') { // aller à (0,0): lcd.home(); // Recommencer avec 'a' unCaractere = 'a'; } // Afficher le car lcd.write(unCaractere); // Attendre un peu delay(500); // Incrémenter la valeur du caractère unCaractere++; }
#include <Wire.h> #include "rgb_lcd.h" #define TEXTE "Bonjour 420 ;-)" #define LONGUEUR_TEXTE 15 #define LARGEUR_ECRAN 16 #define DELAI_CAR 150 #define DELAI_CYCLE 1000 rgb_lcd lcd; void setup() { lcd.begin(LARGEUR_ECRAN, 2); lcd.print(TEXTE); delay(DELAI_CYCLE * 2); } void loop() { // Déplacer le texte vers la gauche for (int position = 0; position < LONGUEUR_TEXTE; position++) { // Déplacer de un car vers la gauche lcd.scrollDisplayLeft(); delay(DELAI_CAR); } for (int position = 0; position < LONGUEUR_TEXTE + LARGEUR_ECRAN ; position++) { // Déplacer de un car vers la droite lcd.scrollDisplayRight(); delay(DELAI_CAR); } // Replacer le texte au début de l'écran for (int position = 0; position < LARGEUR_ECRAN; position++) { lcd.scrollDisplayLeft(); delay(DELAI_CAR); } delay(DELAI_CYCLE); }
#include <Wire.h> #include "rgb_lcd.h" rgb_lcd lcd; char message[] = "La voix des Misterons"; int longueurMessage = 21; void setup() { lcd.begin(16, 2); } void loop() { lcd.setCursor(0, 0); // Imprimer les car '0' à '9' for (int caractere = 0; caractere < 10; caractere++) { lcd.print(caractere); delay(300); } lcd.setCursor(16,1); // Activer le scroll automatique lcd.autoscroll(); // Parcourir tous les caractères du message for (int caractere = 0; caractere < longueurMessage; caractere++) { // Afficher le caractère courant de la chaine lcd.print(message[caractere]); delay(200); } // désactiver le scroll automatique lcd.noAutoscroll(); // Effacer l'écran lcd.clear(); }
#include <Wire.h> #include "rgb_lcd.h" rgb_lcd lcd; // make some custom characters: byte heart[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000 }; byte smiley[8] = { 0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b10001, 0b01110, 0b00000 }; byte frownie[8] = { 0b00000, 0b00000, 0b01010, 0b00000, 0b00000, 0b00000, 0b01110, 0b10001 }; byte armsDown[8] = { 0b00100, 0b01010, 0b00100, 0b00100, 0b01110, 0b10101, 0b00100, 0b01010 }; byte armsUp[8] = { 0b00100, 0b01010, 0b00100, 0b10101, 0b01110, 0b00100, 0b00100, 0b01010 }; void setup() { lcd.begin(16, 2); // create a new character lcd.createChar(0, heart); // create a new character lcd.createChar(1, smiley); // create a new character lcd.createChar(2, frownie); // create a new character lcd.createChar(3, armsDown); // create a new character lcd.createChar(4, armsUp); // set up the lcd's number of columns and rows: lcd.setCursor(0, 0); // Print a message to the lcd. lcd.print("J'"); lcd.write((unsigned char)0); lcd.print(" Arduino! "); lcd.write(1); } void loop() { // read the potentiometer on A0: int sensorReading = analogRead(A0); // map the result to 200 - 1000: int delayTime = map(sensorReading, 0, 1023, 200, 1000); // set the cursor to the bottom row, 5th position: lcd.setCursor(4, 1); // draw the little man, arms down: lcd.write(3); delay(delayTime); lcd.setCursor(4, 1); // draw him arms up: lcd.write(4); delay(delayTime); }
Écrire un programme qui affiche la valeur du potentiomètre (A1) à droite de la ligne 2. Utiliser la technique du padding pour assurer que la valeur occupe toujours trois espaces à l’écran.
Écrire un programme qui permet de modifier la valeur Bleu de RGB à partir du potentiomètre.
Pour Rouge et Vert, utiliser la valeur 255.
Le reste de la division peut être utilisé pour programmer une séquence dans une série de nombres.
Par exemple, le code suivant permet d’identifier les nombres pairs et les nombres impaires:
#include "Streaming.h" #define INIT_SERIAL Serial.begin(9600); #define DELAI_AFFICHAGE 1000 void setup() { INIT_SERIAL } // setup void loop() { // Une variable de type 'static' n'est initialisée qu'une seule fois durant l'exécution du programme static unsigned long int unNombre = 0; Serial << unNombre++ << " est un nombre"; if (unNombre % 2) { Serial << " pair" << endl; } else Serial << " impair" << endl; delay(DELAI_AFFICHAGE); } // loop
Résultat:
variable = (condition) ? expressionSiVrai : expressionSiFaux;
Par exemple,
#include "Streaming.h" void setup() { Serial.begin(9600); boolean yo = true; Serial << "Start" << endl; Serial << (yo ? "Vrai" : "faux"); } void loop() { }
String etat = yo ? "Vrai" : "faux"; Serial << etat; // String est une classe alors plusieurs méthodes sont disponibles pour traiter la chaine. etat.toUpperCase(); Serial << etat;
NOTE: Une variable de type ‘String‘ occupe plus de place en mémoire qu’un tableau de ‘char’ de même longueur.
Utilisation de la mémoire pour un programme vide:
void setup() {}
void loop() {}
Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
-----------
Utilisation de la mémoire pour un programme avec
char chaine[] = "abc":
Sketch uses 444 bytes (1%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
-----------
Utilisation de la mémoire pour un programme avec
String chaine = "abc";
Sketch uses 1806 bytes (5%) of program storage space. Maximum is 32256 bytes.
Global variables use 29 bytes (1%) of dynamic memory, leaving 2019 bytes for local variables. Maximum is 2048 bytes.
#include "Streaming.h" #define INIT_SERIAL Serial.begin(9600); #define DELAI_AFFICHAGE 1000 void setup() { INIT_SERIAL } // setup void loop() { // Une variable de type 'static' n'est initialisée qu'une seule fois durant l'exécution du programme static unsigned long int unNombre = 0; Serial << unNombre << " est un nombre"; Serial << (unNombre % 2 ? " pair" : " impair"); // Quel est le prob ici? Serial << endl; unNombre++; delay(DELAI_AFFICHAGE); } // loop
#include "Streaming.h" void setup(){ Serial.begin(9600); unsigned char option = 2; Serial << "Option: "; switch (option) { case 0: Serial << "1" ;break; case 1: Serial << "2" ;break; case 2: Serial << "3" ;break; default: Serial << "Choix invalide!"; } // switch() } // setup() void loop(){}
#include "Streaming.h" #include "rgb_lcd.h" rgb_lcd LCD2x16; void setup(){ Serial.begin(9600); LCD2x16.begin(16,2); unsigned char option = 3; Serial << "Option: "; LCD2x16 << "Option: "; switch (option) { case 0: Serial << "1"; LCD2x16 << "1"; break; case 1: Serial << "2"; LCD2x16 << "2"; break; case 2: Serial << "3"; LCD2x16 << "3"; break; default: Serial << "Choix invalide!"; LCD2x16 << "Invalide!"; } // switch() } void loop(){}
Compléter le projet suivant, en utilisant l’instruction ‘switch‘ pour que la DEL clignote le nombre de fois défini par le reste de la division.
Si le macro ‘DEBUG’ est définie, le message suivant doit apparaitre dans le moniteur série:
La DEL clignote n fois.
Note: Si le reste de la division n’est pas entre [0..2] il faut afficher un message d’erreur dans le moniteur série.
/* Fichier: bouton-modulo.ino Auteur: Alain Boudreault Date: 2021.09.28 --------------------------------------------------------------------------- Description: Exemple d'un projet qui tient compte de l'état précédent du bouton momentané pour implémenter une rotation de choix en utilisant le reste d'une division La DEL clignote une, deux ou trois fois selon le reste de la division par trois du nombre de fois que le bouton a été appuyé. Note: Le reste de la division du compteur d'utilisation du bouton retourne, dans l'ordre, les valeurs: 1,2 et 0 --------------------------------------------------------------------------- M-A-J: -------------------------------------------------------------------------- */ // -------------------------- // Inclusion des librairies #include "Streaming.h" #include "rgb_lcd.h" // -------------------------- // Les Macros #define ON HIGH #define OFF LOW #define BROCHE_BOUTON 4 #define BROCHE_DEL 3 #define LCD_MSG_DIVISION "Reste DIV/3 = " #define LCD_POSITION_COL_RESTE_DIVISION 14 #define LCD_POSITION_LIG_RESTE_DIVISION 0 #define MAXIMUM_DELAI_BOUTON_APPUYE 500 #define NB_OPTIONS_MENU 3 // -------------------------- // Les variables globales unsigned long int accumulateur = 0; // NB fois bouton appuyé rgb_lcd ecran; // Objet pour controller le LCD // ---------------------- void setup() { Serial.begin(9600); Serial << "Début du programme\n-----------------------\n\n"; ecran.begin(16,2); ecran << LCD_MSG_DIVISION; pinMode(BROCHE_BOUTON, INPUT); pinMode(BROCHE_DEL, OUTPUT); } // ---------------------- void loop() { if (digitalRead(BROCHE_BOUTON)) // Lire le bouton { accumulateur++; // Augmenter le compteur touche bouton ecran.setCursor(LCD_POSITION_COL_RESTE_DIVISION, // Déplacer le curseur LCD à la position de la valeur modulo LCD_POSITION_LIG_RESTE_DIVISION); ecran << accumulateur % NB_OPTIONS_MENU; // Afficher le reste de la division sur le LCD delay(MAXIMUM_DELAI_BOUTON_APPUYE); // Gérer les rebonts du bouton } // if digitalRead() } // loop()
#include "Streaming.h" enum Menu { option1, // vaut 0 option2, // vaut 1 option3 // vaut 2 }; void setup(){ Serial.begin(9600); Menu unMenu = option2; switch (unMenu) { case option2: Serial << "Option 2"; break; default: Serial << "Choix invalide!"; } // switch } // setup() void loop(){}
#include "Streaming.h" enum Menu { option1 = 1, option2 = 2, option3 = 0 }; void setup(){ Serial.begin(9600); Menu unMenu = 0; switch (unMenu) { case option1: Serial << "Option 1"; break; case option2: Serial << "Option 2"; break; case option3: Serial << "Option 3"; break; default: Serial << "Choix invalide!"; } // switch } // setup() void loop(){}
// Exemple d'utilisation de l'instruction 'enum' #include <Streaming.h> enum desFruits { pomme, cerise, kiwi, banane, fraise = 99 }; void setup() { Serial.begin(115200); desFruits unFruit = kiwi; switch (unFruit) { case kiwi: Serial << "Je suis un kiwi ;-)"; break; default: Serial << "Je suis un fruit non traité"; } // switch Serial << " et j'ai la valeur: " << unFruit << endl; } // setup() void loop() { // put your main code here, to run repeatedly: }
/* Projet: Enum+Menu Auteur: Alain Boudreault Date: 2022.10.23 ------------------------------------ Description: Exemple d'utilisation de l'instruction 'enum' pour la gestion d'un menu affiché sur un LCD. */ #define DEBUG #define WOKWI #include <Streaming.h> #include "projet.h" // Les 'define's du projet sont dans un fichier à part. #ifdef WOKWI #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C ecranLCD(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE); #else #include "rgb_lcd.h" rgb_lcd ecranLCD; #endif void setup() { #ifdef DEBUG Serial.begin(UART_VITESSE); Serial << "Début du projet enum+menu\n"; #endif pinMode(BOUTON, INPUT); ecranLCD.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); ecranLCD.cursor_on(); ecranLCD << "Ex d'un Menu"; ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE2); ecranLCD << "Version 1.00"; delay(DELAI_MSG_DEBUT); ecranLCD.clear(); // Effacer l'écran ecranLCD << "Menu1 Menu2 Menu3"; ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE1); ecranLCD.blink_on(); } // setup() void loop() { static optionMenu choixMenu = menu1; static unsigned long compteurBouton = 0; int etatBouton = digitalRead(BOUTON); if ( etatBouton == HIGH) { delay(BOUTON_DELAI_REBOND); while (digitalRead(BOUTON)) ; delay(BOUTON_DELAI_REBOND); compteurBouton++; // Calculer le choix menu en fonction du reste d'une division par trois (3) // Note: Il y a trois options au Menu. choixMenu = compteurBouton % 3; #ifdef DEBUG Serial << "\nChoix menu = " << choixMenu; #endif // Afficher le choix courant sur le LCD ecranLCD.setCursor(LCD_PREMIERE_COLONNE, LCD_LIGNE3); ecranLCD << MSG_CHOIX_MENU_SELECTIONNE << choixMenu+1; // Déplacer le curseur du LCD en fonction de la sélection menu switch (choixMenu) { case menu1: ecranLCD.setCursor(MENU_POS_OPTION_1, LCD_POS_LIG_MENU); break; case menu2: ecranLCD.setCursor(MENU_POS_OPTION_2, LCD_POS_LIG_MENU); break; case menu3: ecranLCD.setCursor(MENU_POS_OPTION_3, LCD_POS_LIG_MENU); break; default: break; // ERREUR!!! } // switch (choixMenu) } // if } // loop()
Le fichier projet.h:
/*****************************************/ #define UART_VITESSE 115200 #define BOUTON 2 #define BOUTON_DELAI_REBOND 5 #define DELAI_MSG_DEBUT 1000 #define LCD_DELAI 50 #define LCD_NB_LIGNE 2 #define LCD_NB_COLONNE 16 #define LCD_LIGNE1 0 #define LCD_LIGNE2 1 #define LCD_LIGNE3 2 #define LCD_PREMIERE_COLONNE 0 #define LCD_POSITION_COMPTEUR 10 #define LCD_ADRESSE_I2C 0x27 #define LCD_POS_COL_MENU 0 #define LCD_POS_LIG_MENU 0 #define MENU_POS_OPTION_1 LCD_POS_COL_MENU + 0 #define MENU_POS_OPTION_2 LCD_POS_COL_MENU + 6 #define MENU_POS_OPTION_3 LCD_POS_COL_MENU + 12 #define MSG_CHOIX_MENU_SELECTIONNE "Choix --> Menu" /*****************************************/ enum optionMenu { menu1, menu2, menu3 };
Le projet Wokwi est disponible ici