Ja, ich bin schuld.
Bedenke: Ich habe die Hardware nicht gehabt und Du auch nicht.
Und alle Codes sind hier geblieben.
Das ist kein Hexenwerk.
Haben wir an anderer Stelle auch gemacht.
Angefangen von Grundeinstellungen über Datum / Uhrzeit bis hin zu Farbwerten von RGB-Led.s Serielle Datenstring vom Computer im Adruino Mega einlesen und aufteilen - #403 by my_xy_projekt
Ist kein Hexenwerk.
Will mal jemand was probieren?
Er ist momentan auf einem 20x4 Display eingestellt, aber wenn man die Zeilen und Spalten anpasst, wird alles andere im Code automtisch angepasst.
Wer Fehler findet, kann gerne was dazu schreiben.
Ich verwende GitHub - CarlosSiles67/Rotary: Arduino rotary encoder library
Hoffentlich habe ich es genügend kommentiert.
Die RotaryFunktion erkläre ich ggfls. wenn Fragen sind.
Hinweis: Die Pins müssen nicht 2 und 3 sein - das Ding läuft ohne Interrupts
// LCD
#include <LiquidCrystal_I2C.h>
const byte lcdZeilen = 4;
const byte lcdSpalten = 20;
char zeilenBuffer[lcdSpalten] = {' '};
LiquidCrystal_I2C lcd(0x27, lcdSpalten, lcdZeilen);
// RotaryEncoder
#define ENABLE_PULLUPS
#include <rotary.h>
Rotary rotary = Rotary(2, 3, 7); // Rotary(Encoder Pin 1, Encoder Pin 2, Button Pin)
const uint8_t bounce = 10;
void setup()
{
delay(500);
Serial.begin(115200);
Serial.println(F("Start..."));
lcd.begin();
lcd.backlight();
hauptmenu(true);
}
void loop()
{
hauptmenu();
}
void hauptmenu()
{hauptmenu(false);}
void hauptmenu(bool neu)
{
const char texte[][6] = {"Menu1", "Menu2", "Menu3", "Menu4", "Menu5", "Menu6", "Menu7", "Menu8"};
const byte menuepunkte = sizeof(texte) / sizeof(texte[0]); // Rechenwert Anzahl der Einträge
const char isauswahl[] = {'>', '#'}; // Positionsanzeige für LCD
static uint8_t myRotate = 0; // Aktuelle RotaryPosition
static uint8_t lcdID = 0; // Jeder Bildschirm wird errechnet
static uint8_t lastRotate = 0; // letzte RotaryFunktion zum Vergleichen
static bool displayNew = false; // Merker für neu
if (neu) {lcdID = -1; lastRotate = -1;}
myRotate = getRotary (myRotate, 0, menuepunkte - 1, true); // Gibt den Counter zurück
/*
Serial.print(myRotate % lcdZeilen); Serial.print(' ');
Serial.print(lastMenu); Serial.print(' ');
Serial.println();
*/
if (lcdID != myRotate / lcdZeilen) // Ist der Inhalt der Anzeige passend zum Counter?
{
lcdID = myRotate / lcdZeilen; // Ermittelt die lcdID an der Anzahl der MenuEinträge
for (byte b = 0; b < lcdZeilen; b++) // schreibt Menueinträge
{
char buf[lcdSpalten] = {'\0'}; // Zwischenpuffer für Leerzeichen
if (b + lcdZeilen * lcdID < menuepunkte) // um zu vermeiden, das über Ende von texte[] gelesen wird
{
lcd.setCursor(0, b);
for (byte c = 0; c < lcdSpalten - sizeof(texte[b]) - 2; c++) // baut einen buffer bis ende der Zeile
{buf[c] = ' ';}
lcd.print(" ");
lcd.print(texte[b + lcdZeilen * lcdID]);
lcd.print(buf);
}
}
}
if (lastRotate != myRotate) // Für die Auswahlanzeige
{
for (byte b = 0; b < lcdZeilen; b++) // durchlaufe alle LCD-Zeilen
{
if (b + lcdZeilen * lcdID < menuepunkte) // solange sich da ein Menupunkt findet
{
lcd.setCursor(0, b); // spalte 0 - Zeile b
byte c = myRotate; // Ab hier Festlegung in welcher Zeile
if (myRotate >= lcdZeilen) // und was ausgegeben wird
c = (myRotate % lcdZeilen);
if (c == b)
lcd.print(isauswahl[0]);
else
lcd.print(isauswahl[1]);
}
}
lastRotate = myRotate;
}
if (rotary.buttonPressedReleased(bounce))
{
Serial.println(myRotate);
}
}
// Diese Funktionen sind für den RotaryCounter!
uint8_t getRotary(int16_t rotaryWert, const uint8_t rotaryMin, const uint8_t rotaryMax)
{return getRotary(rotaryWert, rotaryMin, rotaryMax, false);}
uint8_t getRotary(int16_t rotaryWert, const uint8_t rotaryMin, const uint8_t rotaryMax, const bool atEnd)
{
// *INDENT-OFF*
uint8_t val = rotary.process();
//Serial.println(val);
if (val == rotary.clockwise())
{
rotaryWert ++;
Serial.println('+');
}
else if (val == rotary.counterClockwise())
{
rotaryWert --;
Serial.println('-');
}
// Ab hier wird festgelegt, wie sich verhalten wird, wenn Ende erreicht
if (rotaryWert > rotaryMax) { if (atEnd) rotaryWert = rotaryMin; else rotaryWert = rotaryMax;}
else if (rotaryWert < rotaryMin) {if (atEnd) rotaryWert = rotaryMax; else rotaryWert = rotaryMin;}
return (rotaryWert);
// *INDENT-ON*
}