- LiFePO4 Speicher Test         
Ergebnis 1 bis 4 von 4

Thema: Vorstellung: Arduino C++ Menu Lib (ARM oder ESP, ggf auch AVR)

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast

    Vorstellung: Arduino C++ Menu Lib (ARM oder ESP, ggf auch AVR)

    so,
    nach den vielen Problemen bei der Programmierung der Objekte und Arrays, die wir hier schon besprochen haben, und dank der zahlreichen gegebenen Tipps und Hinweise (vielen Dank nochmals dafür!), hier nun als mein eigenes 2. C++ OOP Projekt eine weitere Vorstellung:
    eine Arduino C++ Menu Lib (ARM oder ESP, vlt auch AVR)

    Einbindung:
    #include <MenuClass.h>

    Es ist nicht auf Speicherplatzoptimierung hin programmiert, sondern für eher mittelgroße MCUs, die eh Speicher satt haben.
    Es bietet Multilayer-Menüs, die einfach zu instanziieren, zu initialisieren, und zu bedienen und auszuwerten sind.

    Die Lib bietet eine Class tMenu, die beliebig häufig instanziiert werden kann.
    Sie ist im Beispielprogramm ausgelegt auf OLEDs 128x64 an ESP8266, auch andere OLEDs/TFTs an anderen Arduinos mit Adafruit-TFT Drivern sind bereits vorgesehen oder können angepasst werden.

    Außerdem erfolgt die Menü-Darstellung zusätzlich noch per Serial.print(), es ist daher auch ohne TFT zu benutzen.


    Steuerung:

    Es werden 3 Buttons zu Steuerung benötigt für Cursor auf, ab, und Enter (Auswahl).

    Nicht notwendig (aber empfehlenswert) ist die bereits in einem anderen Topic erwähnte ButtonClass.
    https://www.roboternetz.de/community...gf-auch-AVR%29

    Mit Enter Long-Press kann markiert werden (tag/untag),
    wenn markiert (tagged), dann per Enter Doppelclick Übernahme/Rückgabe der Liniennummer ans Hauptprogramm.

    Die Auswertungsfunktion bekommt den Click-Status der 3 Buttons übermittelt
    tMenu::checkbtn(btnUp, btnDown, btnEnter)
    und gibt dann, falls eine Auswahl per Enter-Button erfolgt ist, die ausgewählte Linien-Nummer zurück.

    Einträge können im Namen per '>' oder '<' als letzter "Buchstabe" als Verzweigung zu Untermenü/Vorgängermenü konfiguriert werden, dann wird per Longpress oder Doppelclick sofort die Liniennummer zurückgegeben ohne extra vorherige Markierung (tag)
    (nicht notwendigerweise erforderlich, aber es macht das Springen zu anderen Menüs einfacher).

    Alles andere im readme.txt in der Lib.

    Jetzt auf Github: https://github.com/dsyleixa/Arduino/...ster/MenuClass

    Share and enjoy!
    Geändert von HaWe (26.01.2019 um 22:58 Uhr)

  2. #2
    HaWe
    Gast
    neues, ganz einfaches Beispiel, nur 1 Menü-Ebene, z.B. auch zum LED ein- und ausschalten:


    Code:
    // TFT Menu 
    // (C) 2018 by HaWe
    
    // This example code is in the public domain for private use.
    // Use for professional or business purpose: only 
    // by personal written permission by the author.
    
    // default TFT: OLED 128x64, compatible to Adafruit (R) Libs
    // in this example: using an ESP8266 NodeMCU 1.0 board
    // using ButtonClass for button action (up, down, enter, single/double/long press) 
    
    // history:
    // 0.0.1  tMenu new list
    
    // simple menu example 
    // ver 0.0.1
    
    
    // I2C
    #include <Wire.h>         // Incl I2C comm, but needed for not getting compile error
    
    
    //-----------------------------------------------------------------------
    // display driver
    //-----------------------------------------------------------------------
    #include <Adafruit_GFX.h>   // https://github.com/adafruit/Adafruit-GFX-Library 
    // Adafruit Arduino OLED driver
    #include <Adafruit_SSD1306.h> // https://github.com/esp8266/arduino 
    
    #include <Fonts/FreeSans9pt7b.h>             // optional
    #include <Fonts/FreeMono12pt7b.h>            // optional  
    #include <Fonts/FreeMono9pt7b.h>    // used here
    
    // Pin definitions
    
    #define OLED_RESET 10  // GPIO10=D12 Pin RESET signal (virtual)
    
    //Adafruit_SSD1306 display(OLED_RESET);  // old Adafruit lib (tested OK)
     Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET); // new Adafruit lib
    
     
    //-----------------------------------------------------------------------
    // OLED menu
    //-----------------------------------------------------------------------
    #include <MenuClass.h>
     
    char * mlist1[7] = {"Menu1 L0","L1","L2","LED ON","LED OFF", "L5", "L6"}; 
    tMenu menu1(7,11, (char**)mlist1, &menu1, 1);  
    //      numEntries, lineLength,  menu_list,  preMenu, menu-ID
    
    tMenu * actMenu = &menu1;
    
    //-----------------------------------------------------------------------
    // ButtonClass buttons
    //-----------------------------------------------------------------------
    
    #include <ButtonClass.h>
    // 3 buttons for menu control
    tButton btnUp;
    tButton btnDown;
    tButton btnEnter;
    
    
    
    
    //-----------------------------------------------------------------------
    // setup
    //-----------------------------------------------------------------------
    
    void setup(void)
    {
      // Start Serial
    
      Serial.begin(115200);
      delay(3000); // wait for Serial()
      Serial.println("Serial started");
    
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, !LOW);  // inverted LED_BUILTIN signal logic
      
      btnUp.init(D6, INPUT_PULLUP);
      btnDown.init(D3, INPUT_PULLUP);
      btnEnter.init(D4, INPUT_PULLUP);    
      
      // Start Wire (SDA, SCL)
      //Wire.begin(ESPSDA,ESPSCL);  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      Wire.begin();
    
      // SSD1306 Init  
      //display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // old Adafruit lib
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C, true, false); // new Adafruit lib
      
      display.setRotation(2);  
      display.clearDisplay();  // Clear the buffer.
    
      // text display tests
      display.setTextSize(1);
      display.setFont();
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println("Hello, world!");  
      display.display();
      delay(500);
    
      //--------------------------------------
      // test +  debug
    
      display.setFont(&FreeMono9pt7b);  
      
      display.clearDisplay(); 
      display.display(); 
    
      Serial.println("menu init:");
    
      actMenu = &menu1;  //   
      actMenu->mdisplay();   
    
      Serial.println("\n\n");
    }
    
    //-----------------------------------------------------------------------
    // loop
    //-----------------------------------------------------------------------
    
    void loop() {
        int32_t ID;
        int16_t ln;   
        char buf[20];
    
        ln = actMenu->checkbtn(btnUp.click(), btnDown.click(), btnEnter.click() ); 
    
        if(ln!=-1) {      // double click btnEnter: do if selected
           sprintf(buf, "select: line=%d ID=%d  contents=%s", ln, ID, actMenu->list[ln]); 
           Serial.println(buf);
    
           if(ln==0) {  // menu ID 1, line 0
             // do something
           }
           else
           if(ln==1) {  // menu ID 1, line 1
             // do something
           }
           else
           if(ln==2) {  // menu ID 1, line 2: > next menu
             // do something
           }
           else
           if(ln==3) {  // menu ID 1, line 3
             digitalWrite(LED_BUILTIN, !HIGH);  // inverted LED_BUILTIN signal logic
           }
           else
           if(ln==4) {  // menu ID 1, line 4
             digitalWrite(LED_BUILTIN, !LOW);   // inverted LED_BUILTIN signal logic
           }
           // etc.
        }       
    }
    
    // end of file

    https://github.com/dsyleixa/Arduino/...ster/MenuClass
    Geändert von HaWe (26.01.2019 um 22:59 Uhr)

  3. #3
    HaWe
    Gast
    Bisher nutzt die MenuLib Class Lib eine (public) Methode zur zeilenweisen Ausgabe der menü-Einträge:

    Code:
    // Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
    //
    display.setColor(BLACK);
    display.setCursor(FONTWI, line);            
    display.print(list[i]);
    Nicht alle Display Libs (für LCD1602, ILI9341,...)unterstützen aber diese Syntax.
    Es wäre nun eine schöne Erweiterung, wenn die MenuLib Class auch verschiedene Displays nutzen könnte, indem man eine interne, "allgemein gehaltene" ("virtuelle" ?) Schreibmethode verwendet, die erst bei der Instanziierung mit einer bestimmten TFT Lib mit der jeweiligen speziellen Syntax "assoziiert" wird.
    Diese könnte dann gezwungen sein, z.B.
    statt
    display.setColor(BLACK);
    display.setCursor(x,y);
    display.print(cstring);
    display.display();

    etwas in dieser Form aufrufen:
    TextOut(x,y, cstring, TFT_BLACK);
    // schreibt uU sofort, ohne ein zusätzliches display.display(); zu benötigen

    Sieht jemand eine Möglichkeit, so etwas umzusetzen?

    Code:
    class tMenu {  
      
    //...      
      
      public:      
         
         tMenu (...) :   {            
         //...
     
      
         void mdisplay() {          
            if(actln>VISLNUM-1) firstvln=_min(actln-1, MENULEN-VISLNUM);
            else firstvln=0;       
            lastvln=min(firstvln+VISLNUM-1, firstvln+MENULEN-1) ; 
    
            display.clearDisplay();
            
            for(int i=firstvln; i<=lastvln; i++) {   
                displn=(FONTHI-3) + (i-firstvln)*FONTHI;   
                display.setCursor(0, displn);
                
                if(i!=actln && i==tagged) {   
                  display.print('*');   
                }              
                else
                if(i==actln && i==tagged) {   
                  display.print('#');   
                }              
                else                       
                if(i==actln && i!=tagged) {                
                  display.print('>');              
                }
                else {            
                  display.print(' ');              
                }
                display.setCursor(FONTWI, displn);            
                display.print(list[i]);   
            }       
            display.display();
             
         }
          
    
    
         //...
    
    };
    Geändert von HaWe (09.02.2019 um 18:50 Uhr)

  4. #4
    HaWe
    Gast
    das Problem mit stark unterschiedlicher TFTLib-Syntax ist noch nicht gelöst, aber die Zuordnung von Menü-Zeilen und den zugehörigen Exec-Commandos ist deutlich vereinfacht:

    Passend zur Liste mit den einzelnen Zeilen des Menüs
    wird eine entsprechende Exec-Funktion mit den jew. Zeilen der zugehörigen Befehle geschrieben.

    Dadurch ist das Handling der Menü-Funktionen in der loop() deutlich vereinfacht (es können auch optional Strings als Rückgabewerte empfangen werden für spezielle Anforderungen).


    --------------------------
    Update!

    Neu:
    Es können nun auch Variablenwerte in Menüzeilen angezeigt, geupdated und nach Markieren (tag) per Buttons verändert werden, und das sogar für mehrere verschiedene Variablen im selben Menü.

    Beispielcodes hier:

    https://github.com/dsyleixa/Arduino/...ster/MenuClass
    Geändert von HaWe (09.02.2019 um 16:00 Uhr)

Ähnliche Themen

  1. Antworten: 0
    Letzter Beitrag: 15.12.2018, 23:02
  2. esp8266+Arduino IDE + email lib auch für gmx.de?
    Von HaWe im Forum Arduino -Plattform
    Antworten: 10
    Letzter Beitrag: 11.08.2018, 09:53
  3. Raspberry Pi auch über 9V Batterie wie den Arduino?
    Von RoboTrader im Forum Raspberry Pi
    Antworten: 25
    Letzter Beitrag: 14.01.2018, 18:49
  4. Arduino 101: Intel stellt auch das letzte Bastler-Board ein
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 21.07.2017, 07:21
  5. LCD - Menu-Navigation
    Von testone im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 12.11.2008, 23:32

Berechtigungen

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

Labornetzteil AliExpress