Waarom werkt de lcd nog niet goed in wokwiki ?

Ja. Dit is het geheugen gebruik

protected:
	char *buffer;	        // the actual char array
	unsigned int capacity;  // the array length minus one (for the '\0')
	unsigned int len;       // the String length (not counting the '\0')

Een pointer naar een buffer, dat is twee bytes. En beide ints zijn ook twee bytes en dus 6 bytes geheugen voor één String object; het maakt niet uit of er iets in zit of niets. De tekst zelf zit ergens anders en wordt daarom niet geteld in dit voorbeeld; maar gebruikt uiteraard wel geheugen.

Ja. Ik heb je al eerder NUMELEMENTS laten zien.

klopt,
toen je me op wees, dacht is daar direct aan.

Nu eens goed nadenken hoe ik het zien of een button is ingedrukt of niet.

ik dacht aan dit maar het lijkt me dat ik het veel te complex maak.

Code :

void loop() {
 int buttonValue = digitalRead(buttonPin);

 if (buttonValue != lastButtonState) {
   lastDebounceTime = millis();
 }

if ((millis() - lastDebounceTime) > debounceDelay) {
   if (buttonValue != currentButtonState) {
     currentButtonState = buttonValue;

     if (currentButtonState == LOW) {
       buttonPressed = true;
       Serial.println("Button is pressed!");
     } else {
       buttonPressed = false;
     }
   }
 }

als ik dit voor 3 buttons moet doen.

Je kunt een struct gebruiken om een paar gegevens van een knop op te slaan. Bv lastDebounceTime en currentButtonState. Vervolgens creëer je een array van deze structs en een functie (met als parameter de index van een element in het array) die je aanroept voor ieder element in het array.

oke

Eens even nazoeken waar we deze "truuk" meer hebben gebruikt.

Heb het al gevonden bij de rekenmachine.

Even een opmerking ter overweging.
Het lijkt er op dat je een menu hebt met op, neer en select/enter knoppen.
Das aardig, maar je hebt ook een display met maar 2 regels.
Is het dan niet een beter idee om een knop te hebben met een scroll functie en 1 met een select functie ?
Dan heb je geen (bewegende) cursor meer nodig en scroll je door je menu totdat het gewenste item op de bovenste regel staat.
De bovenste regel, omdat je dan nog wel kunt zien wat de volgende optie gaat worden terwijl je net de vorige optie hebt verlaten.
Dat is wellicht iets minder intuïtief dan op en neer, maar het scheelt je wel wat werk.
Want het scrollen komt er toch altijd bij kijken.

In post 54 stel je dat wanneer de cursor op de 2e lijn staat, je scrollt en de pijl dan weer naar de 1e lijn zet.
Is dat ook je bedoeling of bedoel je dat wanneer de cursor op de 2e lijn staat terwijl er verder naar beneden gedrukt wordt terwijl je al op de onderste lijn was ?

ik bedoel het tweede. wanneer de cursor op de 2e lijn staat, je op de button voor naar beneden scrollt en moet de cursor daarna op de 1e lijn staan omdat dan daar het item staat wat je kunt kiezen.

Jouw idee kan ook. IK dacht aan een cursor omdat dan de gebruiker kan zien welke keus hij/zij gaat maken.

@MAS3 dus jij bedoelt :

keuze1
keuze2

persoon drukt op de knop en dan wordt het

keuze2
keuze3

IK had in mijn hoofd

-> keuze1 
   keuze2 

   keuze1 
-> keuze2 

-> keuze2 
   keuze3

Je kunt nog steeds een cursor gebruiken, maar dan 1 die altijd op 0,0 staat.
Ik zou dan niet -> doen, maar alleen > want dat scheelt kostbare LCD ruimte.

> Keuze 1
  Keuze 2

> Keuze 2
  Keuze 3

> Keuze 15
  Exit

> Exit
  Keuze 1

Wanneer zou je in wat je tot nog toe had bedacht, het scrollen laten gebeuren ?

ik dacht op het moment dat ik de knop indruk maar kom er al achter dat dit niet zo handig is.

Menu zoals jij denkt, is denk ik handiger alleen moet ik er dan bedenken hoe je weer naar het begin gaat.

Denk dat ik daar dezelfde "truuk" kan gebruiken als bij de leds.

Stel je eens voor dat je 20 effecten hebt. Je bent aan het scrollen en scrolt één te ver. Dan moet verder scrollen (19 x drukken) voordat je bij de juiste bent. Voorwaarts / achterwaarts is vele malen gebruikersvriendelijker naar mijn mening.

Ik denk dat ik daar met je eens bent.

Misschien het idee van Mas hoe het menu eruit ziet en waar de cursor geplaatst wordt en jouw idee over het scrollen.

En dan toch mijn idee hoe de cursor eruit moet zien.

Kan dit een goed onderdeel van het plan zijn.

@sterretje ik heb je hulp weer even nodig

Ik heb dit:

#include <LiquidCrystal.h>

#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
int maxButtons = 3; 

struct Button {
  int lastDebounceTime; 
  int currentButtonState; 
};

struct LIST
{
  // number of nodes currently in list
  uint8_t size;
  // array of nodes
   Button buttons[maxButtons];

  bool add(Button button)
  {
    // check
    if (size == NUMELEMENTS(buttons))
    {
      Serial.println(F("Lijst van buttons is vol"));
      return false;
    }

    // copy the specified node to the end of the list
    memcpy(&buttons[size], &button, sizeof(Button));
    size++;

    return true;
  }
}

Button buttonUp; 
Button buttonDown; 
Button buttonSelect

List list; 
list.add(buttonUp); 
list.add(buttonDown);
list.add(buttonSelect); 

Waarom krijg ik deze compile errors :

C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:16:29: error: array bound is not an integer constant before ']' token
    Button buttons[maxButtons];
                             ^
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino: In member function 'bool LIST::add(Button)':
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:21:29: error: 'buttons' was not declared in this scope
     if (size == NUMELEMENTS(buttons))
                             ^
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:3:32: note: in definition of macro 'NUMELEMENTS'
 #define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
                                ^
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:21:29: note: suggested alternative: 'button'
     if (size == NUMELEMENTS(buttons))
                             ^
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:3:32: note: in definition of macro 'NUMELEMENTS'
 #define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
                                ^
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:28:13: error: 'buttons' was not declared in this scope
     memcpy(&buttons[size], &button, sizeof(Button));
             ^~~~~~~
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:28:13: note: suggested alternative: 'button'
     memcpy(&buttons[size], &button, sizeof(Button));
             ^~~~~~~
             button
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino: At global scope:
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:35:8: error: expected initializer before 'buttonUp'
 Button buttonUp;
        ^~~~~~~~
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:39:1: error: expected initializer before 'List'
 List list;
 ^~~~
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:40:1: error: 'list' does not name a type; did you mean 'lrint'?
 list.add(buttonUp);
 ^~~~
 lrint
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:41:1: error: 'list' does not name a type; did you mean 'lrint'?
 list.add(buttonDown);
 ^~~~
 lrint
C:\Users\rwobb\Documents\Arduino\menu_v0.2\menu_v0.2.ino:42:1: error: 'list' does not name a type; did you mean 'lrint'?
 list.add(buttonSelect);
 ^~~~
 lrint
exit status 1

Compilation error: array bound is not an integer constant before ']' token

Niet een antwoord op de vraag.

Waarom gebruik je LIST? Je kunt dit eenvoudig af met een array met vaste grootte, er is geen reden om een (pseudo) dynamische lijst te gebruiken.

Dit idee beter ?

#include <LiquidCrystal.h>

struct Button {
  int lastDebounceTime; 
  int currentButtonState; 
};

Button buttonList[3] = {
  {0, 0},  // buttonUp
  {0, 0},  // buttonDown
  {0, 0}   // buttonSelect
};

String menuItems[3] = {"Sweep", "staart", "Twee keer"}; 

int buttonPin =  A1;
int buttonState = 1; 
int choice = 0; 

LiquidCrystal LCD(12, 11, 10, 9, 8, 7);  //Create Liquid Crystal Object called LCD



void setup() {
  
  
}


void loop() {

  
  
}

Dat is beter.

  1. Je kunt de '3' weglaten, de compiler zal weten dat er 3 elementen zijn.
  2. Je kunt de naam van het effect ook aan de struct toevoegen.
  3. Je kunt het pin nummer aan de struct toevoegen.
  4. *lastDebounceTime moet een unsigned variable zijn en int is te klein.
  5. Je hebt al eerder uitgevonden dat String objects een verspilling van geheugen zijn. Gebruik zogenaamde c-strings (karakter arrays).

Twee vragen.

Wat bedoel je met de naam van het effect ?

Wat bedoel je met de naam van het effect ?
De effecten die wij gemaakt hebben, hebben niks te maken met een button of je moet bedoelen dat de naam buttonUp is ?

Je hebt gelijk; te vroeg in de morgen, meer koffie nodig.

:slight_smile:

En hoe verander ik ook alweer dit in een c-strings array

String menuItems[3] = {"Sweep", "staart", "Twee keer"}; 

Ik heb String in char verandert maar dan is de compiler totaal niet blij

of is het zo simpel als dit:

char menuItems[3][10] = {"Sweep", "Staart", "Twee keer"}; 

Dat is een mogelijkheid. Je kunt de 3 weglaten

char menuItems[][10];

Of je kunt pointers gebruiken

const char *menuItems[] = {"Sweep", "Staart", "Twee keer"};

Of misschien iets netter als je veel meer effecten hebt (waar de regel erg lang gaat worden)

const char *menuItems[] = {
  "Sweep",
  "Staart",
  "Twee keer",
};

oke,

Dan ga ik weer verder en nu ik het zie , herken ik het van een van de vorige "opdrachten" die ik heb gemaakt.