Forum: Mikrocontroller und Digitale Elektronik Effizienteres Programm für LCD-Menü (ISR)


von Jannis K. (jannis_k)


Lesenswert?

Guten Tag,

ich bin neu im Forum und möchte euch um Hilfe bitten. Folgendes: Ich 
habe für mein LCD ein kleines Programm geschrieben. Leider muss ich 
immer einige Male die Tasten drücken, damit ich den richtigen Moment im 
Programm abpasse und es ist etwas träge. Mit der ISR denke ich, dass ich 
schon mal auf dem richtigen Weg bin. Im Internet habe ich mir schon 
einiges zur ISR angeschaut, bekomme es aber nicht bei meinem Programm 
hin. Des weiteren würde ich gerne wissen, welche Teile meines Programms 
in ISR-Funktionen gesteckt werden sollten. Ich verwende einen Arduino 
Mega. Soll ich noch einen Schematikplan erstellen?


Danke!
LG Jannis



#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme;

 int upButton=18;
 int downButton=19;
 int selectButton=2;
 int menu=1;



void setup() {
  // put your setup code here, to run once:


  lcd.createChar(0, customChar_1);
  lcd.home();
  lcd.write(0);


 Serial.begin(9600);
  while (!Serial);
  Serial.println(F("BME680 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check 
wiring!");
    while (1);
  }



  lcd.init(); //Im Setup wird der LCD gestartet
  lcd.backlight(); //Hintergrundbeleuchtung einschalten (0 schaltet die 
Beleuchtung aus).
  lcd.clear();


  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms


  pinMode(upButton,INPUT);
  digitalWrite(upButton,HIGH); // pullup-widerstand hinzuschalten
  pinMode(downButton,INPUT);
  digitalWrite(downButton,HIGH);
  pinMode(selectButton,INPUT);
  digitalWrite(selectButton,HIGH);

  updateMenu();

}

void loop() {
 if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }



if(!digitalRead(downButton)){
  menu++;
  updateMenu();
  delay(100);

}
if(!digitalRead(upButton)){
  menu--;
  updateMenu();
  delay(100);

}
if(!digitalRead(selectButton)){
  executeAction();
  updateMenu();
  delay(100);                                  //Warum delay?

}
}
void updateMenu() {
     switch(menu){
      case 0:
        menu=1 ;
        break;

      case 1:
        lcd.clear();
        lcd.print(">Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 2:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(">Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 3:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(">Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 4:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(">Luftqualitaet");
        break;

      case 5:
        lcd.clear();
        lcd.print(">Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 6:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(">Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 7:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(">Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 8:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(">Datum");
        break;

      case 9:
        lcd.clear();
        lcd.print(">Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 10:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(">Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 11:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(">Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 12:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(">Displayspiel");
        break;

      case 13:
        menu=13;
        break;
     }
}
void executeAction() {
  switch (menu) {
    case 1:
      action1();
      break;
    case 2:
      action2();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;
    case 5:
      action5();
      break;
    case 6:
      action6();
      break;
    case 7:
      action7();
      break;

  }
}

void action1() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatur");
  lcd.setCursor(11,0);
  lcd.print(bme.temperature);
  lcd.setCursor(17,0);
  lcd.print("C");
  delay(6000);
}
void action2() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftdruck");
  lcd.setCursor(10,0);
  lcd.print(bme.pressure / 100.0);
  lcd.setCursor(17,0);
  lcd.print("hPa");
  delay(6000);
}
void action3() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftfeucht.");
  lcd.setCursor(12,0);
  lcd.print(bme.humidity);
  lcd.setCursor(18,0);
  lcd.print("%");
  delay(6000);
}
void action4() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftqu.");
  lcd.setCursor(8,0);
  lcd.print(bme.gas_resistance / 1000.0);
  lcd.setCursor(15,0);
  lcd.print("KOhms");
  delay(6000);
}
void action5() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Hoehe...");
  delay(6000);
}
void action6() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Helligkeit...");
  delay(6000);
}
void action7() {
  lcd.clear();
  lcd.createChar(0, customChar_1);
  delay(6000);
}

: Verschoben durch Moderator
von Jannis K. (jannis_k)


Angehängte Dateien:

Lesenswert?

Hier noch ein Bild.

: Bearbeitet durch User
von Jens N. (midibrain)


Lesenswert?

Hallo,
kein Mensch hat verstehen können was Du willst, den Code für Arduino 
wird sich niemand antun wenn Du nicht sagst was Du willst.

von Michael B. (laberkopp)


Lesenswert?

Jannis K. schrieb:
> Leider muss ich
> immer einige Male die Tasten drücken, damit ich den richtigen Moment im
> Programm abpasse und es ist etwas träge

Na ja, wer Taster als digitalen Eingang abfragt, und nicht entprellt, 
muss halt damit rechnen, daß er prellende Signale einliest. Das wird 
dasnn Glückssache.

Dein Hauptptrogramm ist die

loop()
{
}

Die soll nicht zu schnell laufen, nur alle 10ms ein mal rum

loop()
{
  delay_ms(10);
}

Darin liest man den Taster ein, vergleicht mit dem vorherigen Zustand, 
und macht die Aktion nur wenn gedrückt.

loop()
{
  downButtonpressed=!digitalRead(downButton);
  if(downButtonPressed&&!downButtonPressedOld)
  {
    menu++;
    updateMenu();
  }
  downButtonPressedOld=downButtonPressed;
  :
  delay_ms(10);
}

und darin nun auch die anderen Taster

loop()
{
  downButtonPressed=!digitalRead(downButton);
  if(downButtonPressed&&!downButtonPressedOld)
  {
    menu++;
    updateMenu();
  }
  downButtonPressedOld=downButtonPressed;
  upButtonpressed=!digitalRead(upButton);
  if(upButtonPressed&&!upButtonPressedOld)
  {
    menu--;
    updateMenu();
  }
  upButtonPressedOld=upButtonPressed;
  selectButtonpressed=!digitalRead(selectButton);
  if(selectButtonPressed&&!selectButtonPressedOld)
  {
    executeAction();
    updateMenu();
  }
  selectButtonPressedOld=selectButtonPressed;
  delay_ms(10);
}

Deine serial.prints können das Programm langsam machen.

von Andreas J. (ajbln)


Lesenswert?

Hi Jannis,

Michael hat es im Prinzip schon gesagt.
Eine ISR ist für Taster nur dann benutzbar, wenn Du entweder den Taster 
mit einem Kondensator entprellst (was aber zu spürbaren Verzögerungen 
führen kann). Oder in dem Du in der ISR einen Timer startest (per 
millis()), sobald ein Ereignis eintritt (je nach Schaltung z.B. bei 
steigender Flanke) und Du dann aber(!) alle nachfolgenden ISR-Ereignisse 
bis zu einem Timeout von z.B. 100ms sperrst. Dieser Weg ist aber viel 
aufwendiger als der Weg, den Dir Michael oben beschrieben hat.
Nur gibt es tatsächlich Anwendungen wie z.B. ein Drehencoder, wo Du mit 
einer ISR arbeiten solltest, da zum Zeitpunkt der steigenden Flanke der 
Zustand eines anderen Pins für die Richtung notwendig ist. Ohne ISR 
besteht eine hohe Chance, die korrekte Richtung zu verpassen.
Aber wie gesagt, das ist ein Ausnahmefall. Simple Taster pollt man 
einfach.
Auch hier gilt übrigens, dass man nach dem Ereignis (Taste gedrückt) 
unbedingt solange "Zeit verbrennen" muss, bis mindestens 100ms vergangen 
sind. Wenn Du aber mit LCD irgendwas machst, ist das quasi automatisch 
so.
Sonst kann es Dir eben passieren, dass Du bei nicht entprellten Tastern 
denkst, dass sie mehrmals gedrückt wurden, obwohl das gar nicht der Fall 
war...

: Bearbeitet durch User
von Andreas J. (ajbln)


Lesenswert?

Ach, und was mir gerade auffällt:
Um den Pullup zu aktivieren nimmt man normalerweise pinMode(xxx, 
INPUT_PULLUP).
Guck mal, ob das bei Dir nicht auch funktioniert als Alternative dazu, 
den Ausgang auf HIGH zu schalten. Intern macht Arduino das selbe, aber 
Du hättest dann portableren Code, der auch mit einem ESP32 z.B. 
funktioniert.

Und als Empfehlung noch: guck Dir mal an, was man mit objektorientierter 
Programmierung (C++) erreichen kann. Gibt dazu viele Lernvideos bei 
Youtube und co.. Das macht den Code extrem viel übersichtlicher, 
eleganter und Du vermeidest Redundanz.
Also wenn Du mehrere Taster verwendest, könntest Du Dir eine Klasse 
"Button" oder so schreiben mit der Pinnummer als Argument. Dort 
programmierst Du dann das Verhalten eines Tasters (z.B. in dem Du eine 
Methode is_pressed() oder so einführst).
Das programmierst Du einmal (z.B. in einer Button.h und Button.cpp) und 
dann kannst Du das x-mal in Deinem Projekt aufrufen und später dann in 
anderen Projekten wiederverwenden.
So mache ich das und habe mir damit mittlerweile schon eine riesige 
Bibliothek erstellt, die ich in allen Projekten wiederverwende. Auch mit 
unterschiedlichen Prozessoren...

von MaWin (Gast)


Lesenswert?

Andreas J. schrieb:
> Das macht den Code extrem viel übersichtlicher, eleganter und Du
> vermeidest Redundanz

Das ist jetzt aber schon grobes Fanboy-Geschwätz.

Anders gesagt: meistens trifft in der Praxis das behauptete nicht zu, 
auch wenn es seltene Ausnahmebeispiele in Lehrbüchern gibt.

von Andreas J. (ajbln)


Lesenswert?

MaWin schrieb:
> Das ist jetzt aber schon grobes Fanboy-Geschwätz.
Es war ja auch nur eine Empfehlung. "Übersichtlich" und "Elegant" ist 
natürlich subjektiv. Aber dass man Redundanz vermeidet ist definitiv 
wahr.

Also hier mal konkret ein Beispiel (auf C Level) aus Jannis' Code:

Wenn Du zwei Methoden einführst:

void showHeader(bool selected, int line, const char* text)
{
 lcd.setCursor(0, line);
 lcd.print(selected ? '<' : ' ');
 lcd.print(text);
}

void showMenu(int x)
{
 lcd.clear();
 showHeader(x == 0, 0, "Temperatur");
 showHeader(x == 1, 1, "Luftdruck");
 showHeader(x == 2, 2, "Luftfeuchtigkeit");
 showHeader(x == 3, 3, "Luftqualitaet");
}

Kannst Du später folgendes machen:

showMenu(0) => Temperatur ist ausgewählt...

Dann hast Du den Text an einer Stelle, die Logik an einer Stelle und 
musst später nur eine Stelle warten bzw. verändern. Du hast in meinen 
Augen - also ganz subjektiv - übersichtlichen, eleganten und leicht 
wartbaren Code. Und Dein Code würde sich um gefühlt die Hälfte 
reduzieren (und auch weniger Flash verbrauchen).

Das hier ist auch schon einfachstes OO. Mit C++ kann man noch einen 
Schritt weiter gehen (mit C auch), dann würde man ein Header-Objekt 
einführen und ein Menu-Objekt. Aber jeder eben wie kann und mag. ;-)

: Bearbeitet durch User
von Jannis K. (jannis_k)


Lesenswert?

Danke für eure Rückmeldungen und Hinweise.

Michael B. schrieb:
> Na ja, wer Taster als digitalen Eingang abfragt, und nicht entprellt,
> muss halt damit rechnen, daß er prellende Signale einliest. Das wird
> dasnn Glückssache.

Der Entprellcode ist nun eingefügt.

__________
Andreas J. schrieb:
> Um den Pullup zu aktivieren nimmt man normalerweise pinMode(xxx,
> INPUT_PULLUP).

Den Befehl zur Aktivierung des Pullup Widerstand habe ich abgeändert.
____________
Andreas J. schrieb:
> Dann hast Du den Text an einer Stelle, die Logik an einer Stelle und
> musst später nur eine Stelle warten bzw. verändern. Du hast in meinen
> Augen - also ganz subjektiv - übersichtlichen, eleganten und leicht
> wartbaren Code. Und Dein Code würde sich um gefühlt die Hälfte
> reduzieren (und auch weniger Flash verbrauchen).

Deinen Vorschlag werde ich mir demnächst vornehmen.
___________
Probehalber habe ich den Seriellen-Teil für die Sensor-Kommunikation 
entfernt und der uC reagierte sofort auf meine Tasten-Befehle.
Gäbe es eine weitere Möglichkeit das Programm so zu ändern, dass der uC 
sofort im Menü umspringt, wenn ich die Taster betätige?
Mir ist aufgefallen, dass das Springen in einen Unterpunkt sehr schnell 
geht, nur das Wechseln der Einträge im Hauptmenü ist manchmal ein wenig 
verzögert.













#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme;

 int upButton=18;
 int downButton=19;
 int selectButton=2;
 int menu=1;

 int downButtonPressed=19;
 int downButtonPressedOld=19;
 int upButtonPressed=18;
 int upButtonPressedOld=18;
 int selectButtonPressed=2;
 int selectButtonPressedOld=2;



void setup() {
  // put your setup code here, to run once:


  lcd.createChar(0, customChar_1);
  lcd.home();
  lcd.write(0);


 Serial.begin(9600);
  while (!Serial);
  Serial.println(F("BME680 test"));

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check 
wiring!");
    while (1);
  }



  lcd.init(); //Im Setup wird der LCD gestartet
  lcd.backlight(); //Hintergrundbeleuchtung einschalten (0 schaltet die 
Beleuchtung aus).
  lcd.clear();


  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms


  pinMode(18,INPUT_PULLUP);
  pinMode(19,INPUT_PULLUP);
  pinMode(2,INPUT_PULLUP);


  updateMenu();

}

void loop() {

 if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }

  downButtonPressed=!digitalRead(downButton);
  if(downButtonPressed&&!downButtonPressedOld)
  {
    menu++;
    updateMenu();
  }
  downButtonPressedOld=downButtonPressed;
  upButtonPressed=!digitalRead(upButton);
  if(upButtonPressed&&!upButtonPressedOld)
  {
    menu--;
    updateMenu();
  }
  upButtonPressedOld=upButtonPressed;
  selectButtonPressed=!digitalRead(selectButton);
  if(selectButtonPressed&&!selectButtonPressedOld)
  {
    executeAction();
    updateMenu();
  }
  selectButtonPressedOld=selectButtonPressed;
  delay(10);
}


void updateMenu() {
     switch(menu){
      case 0:
        menu=1 ;
        break;

      case 1:
        lcd.clear();
        lcd.print(">Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 2:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(">Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 3:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(">Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(" Luftqualitaet");
        break;

      case 4:
        lcd.clear();
        lcd.print(" Temperatur");
        lcd.setCursor(0,1);
        lcd.print(" Luftdruck");
        lcd.setCursor(0,2);
        lcd.print(" Luftfeuchtigkeit");
        lcd.setCursor(0,3);
        lcd.print(">Luftqualitaet");
        break;

      case 5:
        lcd.clear();
        lcd.print(">Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 6:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(">Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 7:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(">Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(" Datum");
        break;

      case 8:
        lcd.clear();
        lcd.print(" Hoehe");
        lcd.setCursor(0,1);
        lcd.print(" Helligkeit");
        lcd.setCursor(0,2);
        lcd.print(" Uhrzeit");
        lcd.setCursor(0,3);
        lcd.print(">Datum");
        break;

      case 9:
        lcd.clear();
        lcd.print(">Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 10:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(">Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 11:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(">Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(" Displayspiel");
        break;

      case 12:
        lcd.clear();
        lcd.print(" Ultraschall");
        lcd.setCursor(0,1);
        lcd.print(" Sonderzeichen");
        lcd.setCursor(0,2);
        lcd.print(" Zaehler->unendlich");
        lcd.setCursor(0,3);
        lcd.print(">Displayspiel");
        break;

      case 13:
        menu=13;
        break;
     }
}
void executeAction() {
  switch (menu) {
    case 1:
      action1();
      break;
    case 2:
      action2();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;
    case 5:
      action5();
      break;
    case 6:
      action6();
      break;
    case 7:
      action7();
      break;

  }
}

void action1() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatur");
  lcd.setCursor(11,0);
  lcd.print(bme.temperature);
  lcd.setCursor(17,0);
  lcd.print("C");
  delay(6000);
}
void action2() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftdruck");
  lcd.setCursor(10,0);
  lcd.print(bme.pressure / 100.0);
  lcd.setCursor(17,0);
  lcd.print("hPa");
  delay(6000);
}
void action3() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftfeucht.");
  lcd.setCursor(12,0);
  lcd.print(bme.humidity);
  lcd.setCursor(18,0);
  lcd.print("%");
  delay(6000);
}
void action4() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Luftqu.");
  lcd.setCursor(8,0);
  lcd.print(bme.gas_resistance / 1000.0);
  lcd.setCursor(15,0);
  lcd.print("KOhms");
  delay(6000);
}
void action5() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Hoehe...");
  delay(6000);
}
void action6() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Helligkeit...");
  delay(6000);
}
void action7() {
  lcd.clear();
  lcd.createChar(0, customChar_1);
  delay(6000);
}

von Andreas J. (ajbln)


Lesenswert?

LCD-Befehle sind generell sehr langsam.
Was Du optimieren kannst, ist z.B. nicht immer das ganze Menü neu zu 
zeichnen (was ja auch zum Blinken führt), sondern nur das '>' Zeichen.
Du malst also erst das Menü ohne '>'. Und wenn Du ein Menüeintrag 
änderst, dann überschreibst Du das alte selektierte Menü an dieser 
Stelle mit einem Leerzeichen und das neu selektierte mit eben dem '>'.

Also sowas hier:

int old_selected_line = -1;

void selectMenu(int line)
{
  if (old_selected_line != -1)
  {
    lcd.setCursor(0,old_selected_line);
    lcd.print(' ');
  }
  lcd.setCursor(0,line);
  lcd.print('>');
  old_selected_line = line;
}

: Bearbeitet durch User
von Andreas J. (ajbln)


Lesenswert?

Außerdem sehe ich gerade, dass Du da bei den actions() ein delay(6000) 
drin hast. Generell sollte man delays() vermeiden, es sei denn sie 
dienen der Kommunikation mit Geräten.
Ich würde wohl per Tastendruck (selectButton) zurückgehen.
Aber auch hier: alles Geschmackssache...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.