Elektronik-Labor
Projekte
Mikrocontroller
Raspberry
/ Ansteuerung eines 16x2 LCD-Displays über I2C auf dem RPi-Pico und Steuerung mit einem Taster
// beispielhaft werden 3 Seiten alternativ angezeigt, ein langes Drücken schaltet das Display dunkel
//
// Dieses Beispiel verwendet die Pico-Arduino Boarderweiterung von Earle Philhower (Version 2.6.3)
// nach Anregung des Buches "RPi Pico Schaltungen und Projekte" von Burkhard Kainka, Seite 5
// Einbindung über die Boardverwalter-URL https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
// unter "Datei | Voreinstellungen" in der Arduino-IDE
//
// Die Library LiquidCrystal_I2C habe ich mit dem RPi-Pico nicht zum laufen bekommen. Mit dieser klappt es:
//
// Die Library LiquidCrystal_PCF8574 wird mit beliebigen I2C-PIN verwendet. Die Funktionen dazu sind beschrieben in:
// /home/username/.arduino15/packages/rp2040/hardware/rp2040/2.6.3/libraries/Wire/src/Wire.h
// /home/username/Arduino/libraries/LiquidCrystal_PCF8574/src/LiquidCrystal_PCF8574.h
// Die Library OneButton ist beschrieben in
// /home/username/Arduino/libraries/OneButton/src/OneButton.h
#include <Arduino.h>
#include <Wire.h> // Die Wire-Bibliotek stellt zwei Objekte zur Verfügung: Wire nutzt i2c0, Wire1 nutzt i2c1
#define WIRE Wire // Wire nutzt i2c0
//#define WIRE Wire1 // Wire1 nutzt i2c1
#define PIN_SDA 4 // mit i2c0 bzw. Wire geht: 0, 4, 8, 12, 16, 20, 24, 28
// i2c1 bzw. Wire1 geht: 2, 6, 10, 14, 18, 22, 26
#define PIN_SCL 5 // SCL-pin immer eine Nummer höher als SDA, also 1, 3, 5,...
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27); // Adresse der PCF8574-Chips ist 0x27
#define LCD_LINES 2 // Anzahl Zeilen
#define LCD_CHARS 16 // Anzahl Spalten
#define BACKLIGHT 255 // Wert für Hintergrundbeleuchtung an (jeder Wert ungleich null möglich)
#include "OneButton.h"
#define PIN_INPUT 14
OneButton button(PIN_INPUT, true, true); // 2.Parameter: activeLow = true, weil von Taster gegen GND geschalten
// 3.Parameter: pullupActive = true, weil wir einen Pullup wollen
bool show = true; // show = true - Hintergrundlicht an, Anzeige sichtbar
int seite = 1, alt_seite = 2; // Erst Seite 1 anzeigen
const int seite_max = 3; // Im Beispiel gibt es 3 Seiten
void setup() {
Serial.begin(115200);
setupDisplay();
button.attachClick(myClickFunction); // Einfacher Klick --> blättert durch die Seiten oder schaltet hell
button.attachLongPressStart(myLongClickFunction); // Langer Klick --> nur zum Dunkel schalten
button.setClickTicks(50); // Default erkennt einzelnen Klick erst nach 400ms, jetzt schon nach 50ms
} // setup()
void loop() {
if (show)
lcd.setBacklight(BACKLIGHT); // Hintergrundlicht anschalten
else
lcd.setBacklight(0); // Hintergrundlicht ausschalten
if (seite != alt_seite) {
lcd.home();
lcd.clear();
if (seite ==1) {
Serial.println("in loop - Seite 1 wird angezeigt");
lcd.print("Seite 1");
}
else if (seite == 2) {
Serial.println("in loop - Seite 2 wird angezeigt");
lcd.print("Seite 2");
} else {
Serial.println("in loop - Seite 3 wird angezeigt");
lcd.print("Seite 3");
} // if
alt_seite = seite;
}
button.tick(); // Überwacht den Button
} // loop()
// this function will be called when the button was pressed 1 time and them some time has passed.
void myClickFunction() {
if (!show) {
show = true;
Serial.println("in myClickFunction. Hintergrundlicht war aus, jetzt an");
} else {
seite+=1;
if (seite > seite_max) seite=1;
Serial.print("in myClickFunction. Hintergrundlicht war an, Seite jetzt = ");
Serial.println(seite);
}
} // myClickFunction
void myLongClickFunction() {
Serial.println("in myLongClickFunction. Show jetzt false ");
show = false;
} // myLongClickFunction
void setupDisplay () {
int error;
bool WireSucess = true;
Serial.println("I2C...");
sleep_ms(5000); // 5 Sekunden warten auf Serielles Display
WireSucess = WIRE.setSDA(PIN_SDA); // Das muss vor Wire.beginn() aufgerufen werden
if (!WireSucess) Serial.println("Fehler bei SDA"); // Dies wird nie aufgerufen, bei Fehler hängt sich Prozess auf (wohl wegen panic())
WIRE.setSCL(PIN_SCL); // Das muss vor Wire.beginn() aufgerufen werden
WIRE.begin();
Serial.print("initialisiert auf PIN SDA=");
Serial.print(PIN_SDA);
Serial.print(" und PIN SCL=");
Serial.println(PIN_SCL);
Serial.print("Probing for PCF8574 on address 0x27...");
WIRE.beginTransmission(0x27);
error = WIRE.endTransmission();
if (error == 0) {
Serial.println(": LCD found.");
show = true;
lcd.begin(LCD_CHARS, LCD_LINES, WIRE); // WIRE wird definiert als Wire oder Wire1, für i2c0 bzw. i2c1
} else {
Serial.println(": LCD not found.");
} // if
} // setupDisplay
---------------