CONTENUTO ►
Vediamo come realizzare un menu con un encoder Arduino sul display LCD 1602 i2c. Presenteremo due esempi: un menu per l’accensione dei LED e un menu con sottomenu sul display con un controllo fluido della luminosità dei LED da parte dell’encoder. Si consiglia di familiarizzare con il collegamento del display LCD 1602 Arduino e del modulo encoder ky-040 ad Arduino. Se avete già collegato questi moduli, potete iniziare questo mini progetto.
Per questa attività sono necessari:
- Arduino Uno / Arduino Nano / Arduino Mega
- display LCD 1602 i2c
- modulo encoder KY-040
- LED e resistenza
- breadboard
- cavi di collegamento
- libreria LiquidCrystal_I2C.h, RotaryEncoder.h
Come creare un menu LCD 1602 i2c con Arduino
Gli esempi di creazione di menu con modulo encoder rotativo e display LCD riportati in questa pagina possono essere adattati alle vostre esigenze. Molti progetti Arduino richiedono all’utente di creare un modo per configurare o controllare un dispositivo sul microcontrollore. L’encoder consente di creare un menu semplice e nativo sul display LCD per controllare i LED o il servo Arduino, ma è anche possibile utilizzare i pulsanti per il controllo.
Schema per la costruzione di menu Arduino con LCD 1602
LCD 1602 i2c | Arduino Uno | Arduino Nano | Arduino Mega |
GND | GND | GND | GND |
VCC | 5V | 5V | 5V |
SDA | A4 | A4 | 20 |
SCL | A5 | A5 | 21 |
Nel primo esempio, più semplice, ci sono tre voci nel menu del display che possono essere modificate ruotando la manopola dell’encoder. Premendo il tasto orologio dell’encoder, si accende il colore del LED RGB selezionato. In base alla posizione del cursore sul display, il colore desiderato viene attivato mediante l’istruzione if. Assemblare il circuito come mostrato nella figura precedente e caricare il seguente programma nel microcontrollore.
Programma Arduino per menu semplice con LCD 16×2 i2c
#include "Wire.h" #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C LCD(0x27, 16, 2); #include "RotaryEncoder.h" RotaryEncoder encoder(4, 5); // DT, CLK #define STEPS 6 #define POSMIN 0 #define POSMAX 12 int lastPos, newPos; boolean buttonWasUp = true; void setup() { LCD.init(); LCD.backlight(); pinMode(9, OUTPUT); // LED blu pinMode(10, OUTPUT); // LED verde pinMode(11, OUTPUT); // LED rosso pinMode(2, INPUT_PULLUP); // SW Serial.begin(9600); encoder.setPosition(10 / STEPS); } void loop() { LCD.setCursor(0, 0); LCD.print("LED1 LED2 LED3"); encoder.tick(); newPos = encoder.getPosition() * STEPS; if (newPos < POSMIN) { encoder.setPosition(POSMIN / STEPS); newPos = POSMIN; } else if (newPos > POSMAX) { encoder.setPosition(POSMAX / STEPS); newPos = POSMAX; } if (lastPos != newPos) { Serial.println(newPos); LCD.setCursor(lastPos, 1); LCD.print(" "); LCD.setCursor(newPos, 1); LCD.print("===="); lastPos = newPos; } boolean buttonIsUp = digitalRead(2); if (buttonWasUp and !buttonIsUp) { delay(10); buttonIsUp = digitalRead(2); if (!buttonIsUp and newPos == 0) { digitalWrite(9, HIGH); digitalWrite(10, LOW); digitalWrite(11, LOW); } if (!buttonIsUp and newPos == 6) { digitalWrite(9, LOW); digitalWrite(10, HIGH); digitalWrite(11, LOW); } if (!buttonIsUp and newPos == 12) { digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, HIGH); } } }
Spiegazione del codice per menu semplice con LCD 16×2 Arduino:
- la posizione del cursore sul display può assumere tre valori – 0, 6 o 12;
- il pulsante dell’encoder rotativo è collegato alla porta digitale configurando il pin con il parametro INPUT PULLUP, che consente di leggere la pressione del pulsante.
Nell’esempio seguente, il menu ha un secondo livello per regolare la luminosità di ciascun LED separatamente. Il passaggio da un menu all’altro avviene premendo il pulsante dell’encoder, che modifica il valore della variabile globale w nello sketch. Lo schema di collegamento dei LED e dei moduli al microcontrollore rimane lo stesso dell’immagine precedente, basta caricare il seguente codice di programma nella scheda Arduino Uno.
Programma Arduino per menu con sottomenu LCD 16×2
#include "Wire.h" #include "LiquidCrystal_I2C.h" LiquidCrystal_I2C LCD(0x27, 16, 2); #include "RotaryEncoder.h" RotaryEncoder encoder(4, 5); // DT, CLK #define STEPS 6 #define POSMIN 0 #define POSMAX 12 #define STEPS_2 10 #define POSMIN_2 0 #define POSMAX_2 250 int lastPos, newPos; boolean buttonWasUp = true; byte w = 2; void setup() { LCD.init(); LCD.backlight(); pinMode(9, OUTPUT); // LED blu pinMode(10, OUTPUT); // LED verde pinMode(11, OUTPUT); // LED rosso pinMode(2, INPUT_PULLUP); // SW Serial.begin(9600); encoder.setPosition(10 / STEPS); } void loop() { // CICLO CON MENU PRINCIPALE while (w == 0) { LCD.setCursor(0, 0); LCD.print("LED1 LED2 LED3"); encoder.tick(); newPos = encoder.getPosition() * STEPS; if (newPos < POSMIN) { encoder.setPosition(POSMIN / STEPS); newPos = POSMIN; } else if (newPos > POSMAX) { encoder.setPosition(POSMAX / STEPS); newPos = POSMAX; } if (lastPos != newPos) { Serial.println(newPos); LCD.setCursor(lastPos, 1); LCD.print(" "); LCD.setCursor(newPos, 1); LCD.print("===="); lastPos = newPos; } boolean buttonIsUp = digitalRead(2); if (buttonWasUp && !buttonIsUp) { delay(10); buttonIsUp = digitalRead(2); if (!buttonIsUp && newPos == 0) { LCD.clear(); delay(500); w = 1; } if (!buttonIsUp && newPos == 6) { LCD.clear(); delay(500); w = 2; } if (!buttonIsUp && newPos == 12) { LCD.clear(); delay(500); w = 3; } } } // MENU ANNIDATO CON UN PRIMO LED while (w == 1) { LCD.setCursor(0, 0); LCD.print("LED1 - "); encoder.tick(); newPos = encoder.getPosition() * STEPS_2; if (newPos < POSMIN_2) { encoder.setPosition(POSMIN_2 / STEPS_2); newPos = POSMIN_2; } else if (newPos > POSMAX_2) { encoder.setPosition(POSMAX_2 / STEPS_2); newPos = POSMAX_2; } if (lastPos != newPos) { LCD.setCursor(7, 0); LCD.print(newPos); analogWrite(9, newPos); } boolean buttonIsUp = digitalRead(2); if (buttonWasUp && !buttonIsUp) { delay(10); buttonIsUp = digitalRead(2); if (!buttonIsUp) { LCD.clear(); digitalWrite(9, LOW); delay(500); w = 0; } } } // MENU ANNIDATO CON UN SECONDO LED while (w == 2) { LCD.setCursor(0, 0); LCD.print("LED2 - "); encoder.tick(); newPos = encoder.getPosition() * STEPS_2; if (newPos < POSMIN_2) { encoder.setPosition(POSMIN_2 / STEPS_2); newPos = POSMIN_2; } else if (newPos > POSMAX_2) { encoder.setPosition(POSMAX_2 / STEPS_2); newPos = POSMAX_2; } if (lastPos != newPos) { LCD.setCursor(7, 0); LCD.print(newPos); analogWrite(10, newPos); } boolean buttonIsUp = digitalRead(2); if (buttonWasUp && !buttonIsUp) { delay(10); buttonIsUp = digitalRead(2); if (!buttonIsUp) { LCD.clear(); digitalWrite(10, LOW); delay(500); w = 0; } } } // MENU ANNIDATO CON UN TERZO LED while (w == 3) { LCD.setCursor(0, 0); LCD.print("LED3 - "); encoder.tick(); newPos = encoder.getPosition() * STEPS_2; if (newPos < POSMIN_2) { encoder.setPosition(POSMIN_2 / STEPS_2); newPos = POSMIN_2; } else if (newPos > POSMAX_2) { encoder.setPosition(POSMAX_2 / STEPS_2); newPos = POSMAX_2; } if (lastPos != newPos) { LCD.setCursor(7, 0); LCD.print(newPos); analogWrite(11, newPos); } boolean buttonIsUp = digitalRead(2); if (buttonWasUp && !buttonIsUp) { delay(10); buttonIsUp = digitalRead(2); if (!buttonIsUp) { LCD.clear(); digitalWrite(11, LOW); delay(500); w = 0; } } } }
Spiegazione del codice per Arduino menu con sottomenu LCD 16×2:
- per ogni sezione del menu viene utilizzato un ciclo while, poiché la variabile globale w = 0; il ciclo while (w == 0) viene eseguito;
- se non si desidera che i LED si spengano quando si esce dal menu principale, eliminare il comando digitalWrite in tutti i loop dei sottomenu.
Conclusione. Abbiamo visto due esempi di creazione di un menu con un encoder sul display Arduino 1602 IIC. Se avete compreso l’essenza del controllo dei menu con un encoder (encoder rotativo), potete facilmente utilizzare questi esempi nei vostri progetti con un display Arduino. Se avete ancora domande su questo argomento, potete lasciarle nei commenti a questo post. Vi auguriamo di riuscire a padroneggiare la programmazione Arduino!
Lascia un commento