- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 44

Thema: Uno R3 mit 128x64 Pixel Display und Dreh-Encoder grafische Anzeigeprobleme

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    28.05.2018
    Beiträge
    45

    Uno R3 mit 128x64 Pixel Display und Dreh-Encoder grafische Anzeigeprobleme

    Werte Community,
    ich bin immer noch autodidaktisch mit Übungen am Uno beschäftigt.
    Nachdem ich nun das 128x64 Pixel Grafikdisplay und den Dreh-Encoder einzeln ansatzweise ergründet habe, sollte die beiden nun zusammen arbeiten.

    Dazu habe ich mir 3 Zeilen mit je dem Text "Wert 1, Wert 2, Wert 3" erstellt, an deren Ende der eingelesene Wert des Dreh-Encoders ausgegeben wird.
    Mit dem Button des Encoders kann ich die Zeilen "im Kreis herum" anspringen und die 3 Werte jeweils durch drehen ändern.
    Das klappt prima.

    Nun dachte ich mir: "Du hast hier ein Grafikdisplay!, Da geht ein bisschen Spielerei!"
    Dazu habe ich um die Zeilen ein Rechteck zeichnen lassen, welches dann, je nach diesem vorhandenen Encoder-Wert (der rechts in jeder Zeile zusätzlich dezimal ausgegeben wird) von links schwarz gefüllt wird. Wie ein Bargraph eben so ist...
    Die Schrift invertiert dabei allein. Das klappt in jeder Zeile allein auch.

    Aber das Problem ist, dass zwar die Zahl rechts immer richtig ist, der Wert der Variablen stimmt also, aber der "Bargraph" mit der selben Variablen nicht richtig läuft.
    Der höchste Wert, der in einer der 3 Zeilen "eingedreht" wird überlagert beim Zeilenwechsel den nächsten Graphen. Auch die Schrifttransparenz ist davon betroffen. Erst über dem "Überlagerungswert" ist sie dann wieder zu sehen.

    Lacht ruhig über meine primitiven Versuche! Der Code ist bestimmt irgendwo zu kompliziert gedacht und umgesetzt.
    Für Verbesserungsvorschläge und Hinweise bin ich echt dankbar.

    Hier der Code:
    Code:
    #include <Arduino.h>
    #include <U8g2lib.h>
    
    #ifdef U8X8_HAVE_HW_SPI
    #include <SPI.h>
    #endif
    #ifdef U8X8_HAVE_HW_I2C
    #include <Wire.h>
    #endif
    
    
    U8G2_ST7565_64128N_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
    
    int volatile Encoderwert = 1;        // Wert vom Drehencoder
    int Bar1=1;                          // Variable von Bargraph 1 und Zahl
    int Bar2=1;                          //                       2
    int Bar3=1;                          //                       3
    
    int taster=4;                       // Alias für Pin4
    int tasterstatus=0;                 // Tasterstatusvariable
    int Cursor=8;                       // Variable für Y Achse des zu steuernden Bargraphs und der Zahl rechts
                                        // 8 = Zeile 1, 28 = Zeile 2, 48 = Zeile 3
    
    void setup(void) {
      u8g2.begin();                     //Displayeinstellungen
      u8g2.setContrast(128);
      u8g2.setFlipMode(0);    
      u8g2.setFontMode(1);              // activate transparent font mode 
    
      pinMode(3, INPUT);                //Pin 2 und 3 für Drehencoder
      pinMode(2, INPUT);
      pinMode(taster, INPUT);           // Pin 4 für Taster
      
      
    attachInterrupt(digitalPinToInterrupt(2),Encoderread,CHANGE);
    
    
    }
    
    void loop(void) {
    
    tasterstatus=digitalRead(taster);                   //Tasterabfrage
    if ((tasterstatus == HIGH)&&(Cursor==8))            //Wenn gedrückt und Cursor steht auf Y Position 8
    {
        Cursor=Cursor+20;                               //Schalte den Cursor weiter auf Y Pos. 28 (Zeile 2)
        Encoderwert=Bar2;                               //Der Encoderwert wird durch den Wert von Bar2 ersetzt
    }                                                   // damit die nicht vom Bar1 Wert überschrieben wird
    else if ((tasterstatus == HIGH)&&(Cursor==28))      //Wenn Taste gedrückt und Y Position steht auf 28 
    {
        Cursor=Cursor+20;                               //Dann Cursor auf Y Position 48 weiterschalten (Zeile3)
        Encoderwert=Bar3;                               //Wie oben
        
    else if ((tasterstatus == HIGH)&&(Cursor==48))      //Taste gedrückt und Y Pos. ist auf 48
    {
        Cursor=8;                                       // wieder zurück auf Y Pos 8 (Zeile1)
        Encoderwert=Bar1;                               // wie oben
    }
    else if (Cursor==8)                                 // Ist der Taster nicht gedrückt und Y Pos ist 8                                 
    {
        Bar1=Encoderwert;                               // geht der Wert aus "Encoderwert" auf die Bargraph 1 Variable "Bar1" 
    }
    else if (Cursor==28)
    {
        Bar2=Encoderwert;                               // Wie bei Bargraph 1
    }
    else if (Cursor==48)
    {
        Bar3=Encoderwert;                               // Wie bei Bargraph 1
    }
    
      u8g2.clearBuffer();					// clear the internal memory
      u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar1,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,20,"Wert 1 = ");  // write something to the internal memory
      u8g2.setCursor(95, 20);
      u8g2.print(Bar1);  // write something to the internal memory
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar2,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,40,"Wert 2 = ");	// write something to the internal memory
      u8g2.setCursor(95, 40);
      u8g2.print(Bar2);  // write something to the internal memory
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar3,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,60,"Wert 3 = ");  // write something to the internal memory
      u8g2.setCursor(95, 60);
      u8g2.print(Bar3);  // write something to the internal memory
      
     
      u8g2.sendBuffer();					// transfer internal memory to the display
      
      delay(250);
    
     
    }
    
    void Encoderread(){
    
      if(digitalRead(2)!= digitalRead(3))
      Encoderwert--;
      else Encoderwert++;
      
    }
    Irgendwie waren alle Umlaute nach der Vorschaufunktion gestört?? Bin mit Windows 7 unterwegs?? Kann oder muss ich hier was einstellen?
    Habe es erstmal korrigiert
    Danke!
    Geändert von Wolle62 (01.01.2019 um 19:48 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    Hallo Wolle,

    ändere mal bitte "int volatile Encoderwert = 1;" in "volatile int Encoderwert = 1;" !
    Hier Referenz dazu: https://www.arduino.cc/reference/en/...iers/volatile/

    Übersetzung:
    volatile ist ein Schlüsselwort, das als Variablenqualifikationsmerkmal bezeichnet wird. Es wird normalerweise vor dem Datentyp einer Variablen verwendet, um die Art und Weise zu ändern, auf die der Compiler und das nachfolgende Programm die Variable behandeln. Das Deklarieren einer variablen Variable ist eine Anweisung an den Compiler. Der Compiler ist eine Software, die Ihren C / C ++ - Code in den Maschinencode übersetzt. Dies sind die echten Anweisungen für den Atmega-Chip im Arduino.
    Ich vermute, Du musst den Encoderwert auf die Breite der Box skalieren. Ich kann nicht sehen, wie breit die Box max. sein darf und wie hoch der Encoderwert maximal ist. Daher liegt die Vermutung nahe, dass der Encoderwert größer wird, als die Max-Boxbreite + dem Offset von 10. Wenn Max-Boxbreite = Max-Encoderwert sein sollte, dann beginnst Du an X-Position 10 und hast dadurch einen Überlauf.

    Versuchsweise könnte man das mal so machen:

    Code:
     
       int Prozent=50;
    
       int Bar1n=Bar1/100*Prozent;
       int Bar2n=Bar2/100*Prozent;
       int Bar3n=Bar3/100*Prozent;
       u8g2.clearBuffer();					// clear the internal memory  u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar1n,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,20,"Wert 1 = ");  // write something to the internal memory
      u8g2.setCursor(95, 20);
      u8g2.print(Bar1);  // write something to the internal memory
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar2n,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,40,"Wert 2 = ");	// write something to the internal memory
      u8g2.setCursor(95, 40);
      u8g2.print(Bar2);  // write something to the internal memory
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,Cursor,Bar3n,15);
     
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,60,"Wert 3 = ");  // write something to the internal memory
      u8g2.setCursor(95, 60);
      u8g2.print(Bar3);  // write something to the internal memory
    Damit wird jeder Bar nur 50% breit. Wenn dann alles klappt, kann man die Prozente erhöhen, bis es dann nicht mehr funktioniert und schauen, wo die Grenze ist. Könnte man dann für die Ausgabe im Display immer auf diesen Wert skalieren und fertig.

    MfG
    Geändert von Moppi (02.01.2019 um 00:45 Uhr)

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    28.05.2018
    Beiträge
    45
    Hallo Moppi,
    Danke für die schnelle Hilfe.
    Zum Verständnis der Darstellung mal ein Bild im Anhang. Der Bargraph geht jeweils über die Schrift. Min und Max habe ich noch nicht festgelegt. Beim Start ist ja "1" definiert...

    Klicke auf die Grafik für eine größere Ansicht

Name:	Display1.jpg
Hits:	14
Größe:	35,2 KB
ID:	33902

    Man sieht oben, dass der Bargraph die Schrift überdeckt. Die wäre normaler Weise jetzt auf die Länge invertiert zu sehen.
    Der Balken hat jetzt die Länge des Wertes 43 aus Zeile 2! Das ist auch das Problem..

    Also:
    Der in irgendeiner Zeile maximale Wert von allen drei Zeilen wird beim durchschalten durch die Zeilen mit dem Button leider immer auf die anderen Zeilen verschleppt. Hinten, wo die gleiche Variable als Zahl angezeigt wird, stimmt die immer.
    Drehe ich nun weiter, wird der Rest der Schrift ab dem Wert (Länge) 43 wieder invertiert sichtbar.
    Ich hatte erwartet, dass der Bargraph beim Durchschalten automatisch immer die Länge der Zahl hinten bekommt, da es ja die selbe Variable ist??

    Mit Deiner Änderung passiert nun folgendes:
    Ich muss immer mit dem Encoder über den Wert 100 kommen, dann erscheint der Bargraph mit der Länge 50 auf einen Schlag und geht dann normal weiter jeden 2. Step.
    Vor 100 ist keiner zu sehen.

    Ich habe testweise mal alle Bargraphs im Sketch "parallel geschaltet" um ein Ansteuerproblem beim Display auszuschliessen. Dann laufen die sauber alle 3 gleichzeitig mit dem Encoder mit. Und die Schrift bleibt auch lesbar. Das Umschalten macht das Problem.

    Gibt es bei der U8G2 Lib einen Unterschied zwischen "DrawBox" und "Print(Text)"?
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken Display.JPG  

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    Der in irgendeiner Zeile maximale Wert von allen drei Zeilen wird beim durchschalten durch die Zeilen mit dem Button leider immer auf die anderen Zeilen verschleppt.
    Das hatte ich heute Nacht noch nicht so gesehen, als ich mir den Code ansah. Wenn die Zahl stimmt, muss auch der Balken stimmen, denn Du führst die Zahl ja nicht extra in einer Variablen.

    Also mal zum Vertändnis:

    1. Du drehst am Rad

    2. Du veränderst damit einen Wert

    3. den Wert zeigst Du in einer Zeile am Ende an

    4. dieser Wert ist richtig und nicht falsch

    5. Du verwendest denselben Wert zur Darstellung des Balkens

    6. der Balken wird falsch dargestellt


    Vielleicht liegt es an: u8g2.drawBox()
    Eventuell brauchst Du für jede Zeile ein extra Objekt oder was in der Richtung.

    1) Wenn Du am Rad drehst und weiter und weiter und immer weiter in dieselbe Richtung, dass der Wert immer größer wird, gibt es dann mal irgendwo einen Endwert? Oder wird der Wert immer größer und größer?
    2) Was ist der maximale Wert für die Breite des Balkens in drawBox() für eine Zeile?

    Ich habe noch mal geschaut, wenn ich das richtig sehe, dann verwendet U8G2 einen Pixelpuffer in welchem man sich "bewegen" kann, indem man eine Draw-Methode aufruft und mit X- und Y-Position in Pixel die Startposition oben Links angibt. Ist das korrekt?

    Ich habe noch was gefunden in:

    Code:
    u8g2.drawBox(10,Cursor,Bar1,15);  u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,20,"Wert 1 = ");  // write something to the internal memory
    Du verwendest einmal absolute Angabe und einmal aus Variable Cursor.

    ändere das entweder in:
    Code:
    u8g2.drawBox(10,Cursor,Bar1,15);  u8g2.setDrawColor(2); /* color 1 for the box */
       u8g2.drawStr(25,Cursor,"Wert 1 = ");  // write something to the internal memory
    oder in absolute Angabe, wie hier als Beispiel:

    Code:
    u8g2.drawBox(10,20,Bar1,15);  u8g2.setDrawColor(2); /* color 1 for the box */
       u8g2.drawStr(25,20,"Wert 1 = "); // write something to the internal memory

    Das ist glaub ich das Problem, dass Du in der ersten Zeile den Balken mit der Länge vom Wert aus der zweiten Zeile erzeugst und so ist das dann mit den anderen auch.

    So müsste es besser sein:

    Code:
      u8g2.setDrawColor(1); /* color 1 for the box */  
      u8g2.drawBox(10,20,Bar1,15);
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,20,"Wert 1 = ");  // write something to the internal memory
      u8g2.setCursor(95, 20);
      u8g2.print(Bar1);  // write something to the internal memory
    
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,40,Bar2,15);
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,40,"Wert 2 = ");    // write something to the internal memory
      u8g2.setCursor(95, 40);
      u8g2.print(Bar2);  // write something to the internal memory
    
    
      u8g2.setDrawColor(1); /* color 1 for the box */
      u8g2.drawBox(10,60,Bar3,15);
      u8g2.setDrawColor(2); /* color 1 for the box */
      u8g2.drawStr(25,60,"Wert 3 = ");  // write something to the internal memory
      u8g2.setCursor(95, 60);
      u8g2.print(Bar3);  // write something to the internal memory

    MfG
    Geändert von Moppi (02.01.2019 um 13:17 Uhr)

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    28.05.2018
    Beiträge
    45
    Ein JA auf alle 6 Fragen.

    Darstellungsende und maximale Balkenbreite bei dem Display ist logischer Weise 128. Da bleibt der stehen
    bis 256 512 ... ,
    dann fängt der Bargraph von vorn neu an.
    Das Gleiche gilt linksrum für negative Werte. Das grenze ich später dann ein, auf Werte, die ich benutzen kann.


    EDIT:
    Hat sich überschnitten, ich setze Deinen Ansatz mit den Werten mal in die Tat um...

    EDIT2:
    Du hast Recht!! Es läuft. Ich habe nun absolute Angeben genommen.
    Nun sind alle 3 Bargraphen immer gleichzeitig sichtbar und alle haben die richtige Länge
    und behalten die auch! Schrift ist immer zu sehen! DANKEEE !!!!!
    Der Tastendruck wechselt nun nur noch die Zuordnung des Encoders zur Zeile.
    Sieht sogar noch besser aus als vorher. Allerdings fehlt nun ein Symbol oder Cursor vorn,
    damit ich weiss in welcher Zeile ich bin.

    Hast Du da einen Ansatz auf der Hand? Ohne das ich das Problem erneut einbaue?
    Achso, wenn ich diese eingestellten Werte permanent behalten will, dann muss ich mich nun mit EEPROMs beschäftigen ?
    Geändert von Wolle62 (02.01.2019 um 13:45 Uhr)

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    Ich habe oben Sachen nachgetragen.

    In Deinem Ursprungs-Code hast Du immer die Variable Cursor zur Ausgabe der Box verwendet, aber Du hast Cursor nie geändert, um die die Box für die nächste Zeile zu zeichnen.

    MfG
    Geändert von Moppi (02.01.2019 um 13:28 Uhr)

Ähnliche Themen

  1. Dreh-Encoder gibt "Rückschlag-Impuls" ab - wieso nur?
    Von t0bias im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 03.03.2014, 17:08
  2. Dreh-Encoder und Tasten gleichzeitig abfragen
    Von DerSchatten im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 13.05.2011, 21:16
  3. LCD-Display 128x64 mit dem Controler T6963c
    Von heri im Forum PIC Controller
    Antworten: 8
    Letzter Beitrag: 05.06.2007, 23:04
  4. Funktioniert der Pollin-Dreh-Encoder mit BASCOM?
    Von felack im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 27.06.2006, 18:52
  5. Hyundai 128x64 LC-Display
    Von ShadowPhoenix im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 14
    Letzter Beitrag: 01.12.2005, 22:16

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests