Ich versuche aktuell nach einer Möglichkeit zwischen zwei Anzeigen wechseln zu können, per Knopfdruck.
Um mir verschiedene Messwerte anzeigen zu lassen.
Meine Idee ist/war das ganze über "switch case" zu realisieren. Es kommt jedoch zu folgendem Problem, dass sich die Werte bei der Anzeige nicht mehr ändern, wenn man am Poti dreht. Ist ja auch logisch da gilt:
display.clearDisplay(); --> display.display();
Ich stecke noch nicht so tief in der Materie drin, da ich mich erst seit kurzem mit dem Thema beschäftige.
Kann mir jemand eine Möglichkeit nennen, wie ich es schaffe das sich die Anzeige immer Aktualisiert bzw.
gibt es eine andere Möglichkeit mit nur einem Knopf zwischen zwei Anzeigen zu wechseln?
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(-1);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
int Analogwert1;
int Analogwert2;
int upButton = 2;
int downButton = 3;
int menu = 1;
void setup() {
Serial.begin(9600);
pinMode( A0 , INPUT);
pinMode( A1 , INPUT);
pinMode(upButton, INPUT_PULLUP);
pinMode( downButton , INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC,0x3c);
display.display();
display.clearDisplay();
updateMenu();
}
void loop() {
Analogwert1 = analogRead(A0);
Analogwert2 = analogRead(A1);
Serial.print("Der erfasste Wert lautet : ");
Serial.println(Analogwert1, DEC);
Serial.println();
delay(1000);
if (!digitalRead(downButton)){
menu++;
updateMenu();
delay(100);
while (!digitalRead(downButton));
}
if (!digitalRead(upButton)){
menu--;
updateMenu();
delay(100);
while(!digitalRead(upButton));
}
}
void updateMenu(){
switch (menu){
case 0:
menu = 1;
break;
case 1:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert1);
display.display();
break;
case 2:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert2);
display.display();
break;
case 3:
menu = 2;
break;
}
}
Wenn du uns deinen Sketch "richtig" zeigst, können wir evtl. am Sketch Fehler erkennen.
Den Sketch richtig zeigen heißt, diesen in Code-Tags posten, damit jeder diesen lesen kann.
Dazu die Schaltfläche </> oben links im Editorfenster verwenden.
Du musst das Display ständig aktualisieren. Und mit den Knöpfen nur auswählen welcher Wert angezeigt wird
Das Display immer komplett zu löschen ist bei sowas auch schlecht. Das ist langsam und flackert. Besser ist es man formatiert seine Werte auf eine konstante Breite, z.B. mit führenden Leerzeichen oder Nullen
HotSystems:
Wenn du uns deinen Sketch "richtig" zeigst, können wir evtl. am Sketch Fehler erkennen.
Den Sketch richtig zeigen heißt, diesen in Code-Tags posten, damit jeder diesen lesen kann.
Dazu die Schaltfläche </> oben links im Editorfenster verwenden.
Grüß,
vielen Dank für den Tipp, hab das ganze dementsprechend nochmal geändert.
Ok, einen UP-Button für menu-- und einen DN-Button für menu++ zu benutzen, entspricht nicht ganz der Benennung der Taster-Pins, aber sei's drum.Bei zwei Menü-Punkten wohl auch nicht sooo wichtig.
switch (menu){
case 0:
menu = 1;
//break; Hier KEIN break, damit der 'case 1' ebenfalls abgearbeitet wird
case 1:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert1);
display.display();
break;
case 3: //ist hoch gewandert
menu = 2;
//break; //auch hier wollen wir ja, daß der 'case 2' ausgeführt wird
case 2:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert2);
display.display();
break;
}
Habe mir gestattet, Deine switch-Abfrage etwas anzupassen.
Auch, wenn hier im obersten Menü bei menu-- oder im untersten Menü bei menu++ genau das Gleiche erneut angezeigt wird, was bereits auf dem Display zu sehen ist.
Wenn Du damit leben kannst, daß das Menü erst aktualisiert wird, wenn Du den Taster los gelassen hast, würde ich updateMenu() unterhalb der Taster-Abfrage aufrufen - alle halbe Sekunde (ginge mit INTERVAL.h oder oldscool mit millis()).
So wird das Display IMMER aktualisiert (also jede halbe Sekunde) und Du kannst per Taster die Menü's hoch/runter schalten.
So dürftest Du nur bei Tastendruck einen aktuellen Wert auf's Display bekommen, da ohne Tastendruck keine Display-Ausgabe erfolgt.
Ok, einen UP-Button für menu-- und einen DN-Button für menu++ zu benutzen, entspricht nicht ganz der Benennung der Taster-Pins, aber sei's drum.Bei zwei Menü-Punkten wohl auch nicht sooo wichtig.
switch (menu){
case 0:
menu = 1;
//break; Hier KEIN break, damit der 'case 1' ebenfalls abgearbeitet wird
case 1:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert1);
display.display();
break;
case 3: //ist hoch gewandert
menu = 2;
//break; //auch hier wollen wir ja, daß der 'case 2' ausgeführt wird
case 2:
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(27,20);
display.print(Analogwert2);
display.display();
break;
}
Habe mir gestattet, Deine switch-Abfrage etwas anzupassen.
Auch, wenn hier im obersten Menü bei menu-- oder im untersten Menü bei menu++ genau das Gleiche erneut angezeigt wird, was bereits auf dem Display zu sehen ist.
Wenn Du damit leben kannst, daß das Menü erst aktualisiert wird, wenn Du den Taster los gelassen hast, würde ich updateMenu() unterhalb der Taster-Abfrage aufrufen - alle halbe Sekunde (ginge mit INTERVAL.h oder oldscool mit millis()).
So wird das Display IMMER aktualisiert (also jede halbe Sekunde) und Du kannst per Taster die Menü's hoch/runter schalten.
So dürftest Du nur bei Tastendruck einen aktuellen Wert auf's Display bekommen, da ohne Tastendruck keine Display-Ausgabe erfolgt.
MfG
Vielen Dank für deine Antwort.
Etwas schlauer bin ich daraus geworden, aber noch nicht hundert prozentig. Die Idee hab ich verstanden aber wo genau muss der Befehl millis() hin, damit es mein Display aktualisiert?
uint32_t waittime=500; //Wartezeit zwischen Display-Aktualisierungen in ms
...
setup(){
...
}
loop(){
... Abfrage Taster DN ...
... Abfrage Taster UP ...
static uint32_t lastmillis=millis(); //lastmillis wird auch nach Ende von loop den zugewiesenen Wert behalten
if (millis()-lastmillis>=waittime){ //alle x ms die Update-Funktion aufrufen
updateMenu();
lastmillis=millis(); //und die neue 'letzte Zeit' merken
}
}
... oder die INTERVAL.h includieren (findest Du im Bibliotheks-Verwalter) und
@postmaster-ino, danke für deine Bemühungen, leider hat das ganze nicht funktioniert, ich habe das ganze jetzt nochmal für einen Sketch mit OneButton ausprobiert, es kommt jedoch der selbe Fehler.
C:\Users\--\Documents\Arduino\sketch_nov20d\sketch_nov20d.ino: In function 'void setup()':
sketch_nov20d:39:25: error: 'ein_Klick' was not declared in this scope
button1.attachClick(ein_Klick);
^
sketch_nov20d:40:31: error: 'dopple_Klick' was not declared in this scope
button1.attachDoubleClick(dopple_Klick);
^
In file included from C:\Users\--\Documents\Arduino\sketch_nov20d\sketch_nov20d.ino:5:0:
C:\Users\--\Documents\Arduino\sketch_nov20d\sketch_nov20d.ino: At global scope:
C:\Users\--\Documents\Arduino\libraries\INTERVAL/INTERVAL.h:11:1: error: expected unqualified-id before '{' token
{ \
^
C:\Users\--\Documents\Arduino\sketch_nov20d\sketch_nov20d.ino:49:2: note: in expansion of macro 'INTERVAL'
}INTERVAL(500){
^
C:\Users\--\Documents\Arduino\libraries\INTERVAL/INTERVAL.h:16:1: error: expected unqualified-id before 'if'
if(DoINTERVAL)
^
C:\Users\--\Documents\Arduino\sketch_nov20d\sketch_nov20d.ino:49:2: note: in expansion of macro 'INTERVAL'
}INTERVAL(500){
^
exit status 1
'ein_Klick' was not declared in this scope
Um mein Ziel mal zu nennen, ich möchte aus einem Co2 Sensor, und einem Luftdruck-/Feuchte-/Temp.- Sensor ein paar Messungen machen. Die einzelnen Analogwerte sollen dann einzeln auf meinem Display erscheinen. Per Knopfdruck soll man dann zwischen den Anzeigen Wechseln können. Es soll auch so sein, dass sich der Wert auf dem Display ändert, falls sich was an den Messwerten ändert.
Mit der OneButton library funktioniert das ganze bis jetzt ganz gut, nur eben das Problem, das sich der Analogwert nicht ändert, sondern dieser nur einmal abgefragt wird.
Gib uns doch erst mal einen Link auf Deine OneButton-Lib. Es gibt mehrere mit dem gleichen Namen.
Dein Code muss zu den Beispielen Deiner Lib passen.
Du musst in Deinem Sketch immer von Den Beispielen Deiner Lib ausgehen.
Deine Lib kennt "ein_Klick" nicht.
Wahrscheinlich passt Dein Sketch nicht zur Lib.
Habe ein/zwei Zeilen kommentiert.
Drücke Mal STRG+T in der IDE - dann siehst Du, wie der Arduino Deinen Sketch 'sieht' - Klammer-Fehler kommen dadurch gut zum Vorschein!
Hi.
Nur zum Verständnis, der void loop läuft doch immer wieder von vorn ab und stellt meine Hauptfunktion dar?
Und ja der Void stellt eine Funktion dar wie meinst du das jetzt mit "wir brauchen hier den AUFRUF"? Wie muss man die Klammern setzten das das ganze Funktioniert, ich dachte immer das diese einen bestimmten bereich begrenzen ?
Das Problem an der ganzen Geschichte ist, das ich aktuell noch nicht die 100% Ahnung habe von dem was ich mache, im Grunde genommen besteht mein Sketch aus diesem Video: Arduino Tutorial: Kapitel 3.2.2: "Die OneButton Library" - YouTube
Danach habe ich mir alle nötigen Sachen für das Display reinkopiert und am Ende noch zwei Eingänge definiert, damit ich durch 2 Potentiometer am Ende auf meinem Display die Analogwerte angezeigt bekomme.
Ich hab nur noch nicht richtig verstanden wo man jetzt nun die Klammern richtig setzt ?
Es muss ja immer ein Anfang und ein Ende geben, und ein Befehl der dazwischen ausgeführt wird ?
Muss ich alles in dir void loob Datei schreiben ? Oder schließ ich die mit den Klammern ab und fang dann mit dem nächsten void an ?
Morgen.
Ich habe meinen Sketch nochmal überarbeitet, alles nutzlose raus geschmissen und alles hoffentlich etwas übersichtlicher Gestaltet.
One Button funktioniert, das Display auch, jetzt ist die frage wie man die Analogwerte dynamisch anzeigen lassen kann.
//---------------------------------------------------------------------------------------------------------------
// LIBRARIES
//---------------------------------------------------------------------------------------------------------------
#include <OneButton.h>
#include <Wire.h> //I2C für OLed
#include <Adafruit_SSD1306.h> //grafik Libary für Oled
#include <Adafruit_GFX.h> //Oled Treiber
#include <INTERVAL.h>
//---------------------------------------------------------------------------------------------------------------
// DEFINES
//---------------------------------------------------------------------------------------------------------------
#define OLED_RESET 4 //OLED reset on lin 4
//---------------------------------------------------------------------------------------------------------------
// DISPLAY / LIBARY CAll
//---------------------------------------------------------------------------------------------------------------
Adafruit_SSD1306 display(OLED_RESET); //create instance of OLED called display
//---------------------------------------------------------------------------------------------------------------
// VARIABLEN
int buttonPin1 = 2; //Knopf
int Analogwert1; //Potentiometer1 zur Simulation
int Analogwert2; //Potentiometer2 zur Simulation
//---------------------------------------------------------------------------------------------------------------
OneButton button1 = OneButton(buttonPin1, false); // Kopf wird mit externem Wiederstand verwendet
//---------------------------------------------------------------------------------------------------------------
// SETUP
//---------------------------------------------------------------------------------------------------------------
void setup() {
// Display
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //begin display @ hex addy 0x3C
display.clearDisplay();
display.display();
// Pins
pinMode( A0 , INPUT); // Analoger-Eingang
pinMode( A1 , INPUT); // Analoger-Eingang
}
//---------------------------------------------------------------------------------------------------------------
// MAIN LOOP
//---------------------------------------------------------------------------------------------------------------
void loop()
{
button1.attachClick(ein_Klick); //ObeButton Befehl für einaml Klicken
button1.attachDoubleClick(dopple_Klick); //ObeButton Befehl für doppel Klicken
button1.attachPress(halten); //ObeButton Befehl für halten
button1.setPressTicks(2000); //ObeButton Drückzeit für Halten
button1.tick(); //ObeButton Abfragezeit ob Knopf betätigt wird
delay(100); //ObeButton ? empfehleswerter Delay ?
}
//---------------------------------------------------------------------------------------------------------------
// ein Klick
//---------------------------------------------------------------------------------------------------------------
void ein_Klick()
{
Analogwert1 = analogRead(A0); //nach Klicken soll der Analogwert1 gelesen werden
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print(Analogwert1); //-->diese Anzeige soll immer dem Aktuellen Analogwert entsprechen ??
display.display();
}
//---------------------------------------------------------------------------------------------------------------
// doppel Klick
//---------------------------------------------------------------------------------------------------------------
void dopple_Klick()
{
Analogwert2 = analogRead(A1); //nach doppel Klicken soll der Analogwert2 gelesen werden
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print(Analogwert2); //-->diese Anzeige soll immer dem Aktuellen Analogwert entsprechen ??
display.display();
}
//---------------------------------------------------------------------------------------------------------------
// halten
//---------------------------------------------------------------------------------------------------------------
void halten()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(27,30);
display.print("halten");
display.display();
}
//---------------------------------------------------------------------------------------------------------------
Genau wenn ich meine Analogwerte im Loop auslese und sie mir dort auch anzeigen lasse funktioniert das. Soweit war ich schon mal.
Wenn ich dann die Verknüpfung vom Loop dann in mein "void ein_Klick" ziehe, dann passiert folgendes. Der Analogwert wird einmal vom Loop abgefragt, dann wird er dar gestellt und ist fest da, bis ich den Knopf erneut drücke.
Ich möchte aber das ich den Knopf einmal drücke und sich der Analogwert dann auch in der Anzeige ändert wenn ich am Poti drehe.
Deswegen sollst Du die Werte ja auch im Loop lesen und darstellen und nicht in den Klick-Funktionen.
Wenn Du die Anzeige erst bei Klick beginnen willst, dann verwende Statusvariablen.
Noch ein Tipp: Die Anzeige nur ändern, wenn sich der Wert geändert hat. Also alten Wert merken.
Alten Wert auf dem Display mit der Hintergrundfarbe schreiben und dann den neuen Wert mit der Vordergrundfarbe. Das reduziert das Flackern.