Nasz mikrokontroler kiedy pracuje niezależnie od komputera niekiedy potrzebuje przekazać informacje użytkownikowi albo jakieś informacje zebrać. W wielu przypadkach wystarczy skromny wyświetlacz i enkoder do komunikacji z użytkownikiem.
W tym przypadku użyty zostanie wyświetlacz LCD 2x16 znaków z interfejsem I2C oraz pospolity enkoder z przyciskiem.
Większość tanich wyświetlaczy LCD 2x16 znaków jest oparta na sterowniku HD44780. Podłączenie go bezpośrednio do Arduino zanjmuje sporo pinów, stąd warto skorzystać z wersji, która ma konwerter I2C (np.: LCM1602). Dzięki temu do Arduino idą tylko 2 przewody do złącz SCL i SDA (jeżeli mamy więcej urządzeń na magistrali I2C to wpinamy wyświetlacz w magistralę pamiętając o tym by nie doszło do konfliktu adresów). Takie wyświetlacze mają zwykle rezystory podciągające stąd nie ma potrzeby osobnego podciągania linii do zasilania podczas budowy układu. Prócz podłączenia do magistrali trzeba jeszcze przyłączyć zasilanie.
Korzystamy z biblioteki LiquidCrystalIO - jest dostępna w repozytorium Arduino. Przykładowy szkic pozwalający wyświetlić napis "Hello world!".
#include <Arduino.h>
#include <LiquidCrystalIO.h>
// When using the I2C version, these two extra includes are always needed. Doing this reduces the memory slightly for
// users that are not using I2C.
#include <IoAbstractionWire.h>
#include <Wire.h>
// For most standard I2C backpacks one of the two helper functions below will create you a liquid crystal instance
// that's ready configured for I2C. Important Note: this method assumes a PCF8574 running at 100Khz. If otherwise
// use a custom configuration as you see in many other examples.
// If your backpack is wired RS,RW,EN then use this version
LiquidCrystalI2C_RS_EN(lcd, 0x27, false)
// If your backpack is wired EN,RW,RS then use this version instead of the above.
//LiquidCrystalI2C_EN_RS(lcd, 0x27, false)
void setup() {
// for i2c variants, this must be called first.
Wire.begin();
// set up the LCD's number of columns and rows, must be called.
lcd.begin(16, 2);
// most backpacks have the backlight on pin 3.
lcd.configureBacklightPin(3);
lcd.backlight();szynie
lcd.clear();
}
void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hello world!");
}
Współrzędne kursora podawane są w postaci (kolumna, wiersz) przy czym kolumna przyjmuje wartości od 0 do 15 a wiersz od 0 do 1.
Tanie enkodery zwykle przy jednym skoku podają dwa razy sygnał, stąd liczenie impulsów zwykle będzie pokazwyło wartości parzyste skoków mimo pojedynczych skoków - trzeba to mieć na uwadze i sprawdzić czy enkoder, którego używamy daje jeden czy dwa impulsy co skok by uwzględnić to w programie mikrokontrolera.
Enkoder podpinamy do zasilania i trzech wybranych pinów Arduino, zaznaczyć trzeba, że pin pod który podpięty jest przycisk, musi być w trybie PULL_UP.
Poniższy kod pobiera dane z enkodera i wyświetla wyniki na opisywanym wcześniej ekranie.
#include <Arduino.h>
#include <LiquidCrystalIO.h>
#include <IoAbstractionWire.h>
#include <Wire.h>
#define encoder_switch 8
#define outputA 9
#define outputB 10
int encoder_counter = 0;
int encoder_state;
int encoder_last_state;
int lastButtonPress;
LiquidCrystalI2C_RS_EN(lcd, 0x27, false)
void setup() {
Wire.begin();
lcd.begin(16, 2);
lcd.configureBacklightPin(3);
lcd.backlight();szynie
lcd.clear();
// Encoder
pinMode(encoder_switch, INPUT_PULLUP);
pinMode(outputA, INPUT);
pinMode(outputB, INPUT);
encoder_last_state = digitalRead(outputA);
}
void loop() {
encoder_state = digitalRead(outputA);
if(encoder_state != encoder_last_state) {
if(digitalRead(outputB) != encoder_state) {
encoder_counter++;
}
else {
encoder_counter--;
}
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(encoder_counter);
}
encoder_last_state = encoder_state;
int btnState = digitalRead(encoder_switch);
if (btnState == LOW)
{
if (millis() - lastButtonPress > 50)
{
lcd.setCursor(0,1);
lcd.print("Button pressed!");
}
lastButtonPress = millis();
}
delay(1);
}