Go Down

Topic: Projekt: LCDMenuLib - LCD Menü mit mehreren Ebenen (4Bit/I2C/ShiftReg/...) (Read 66045 times) previous topic - next topic

Jomelo

Hi,
irgendwie haben damit mehrere Leute ab und zu Probleme. Ab und zu läuft es auch ohne Probleme.
Es gibt eine debounce Lib die sich um das Entprellen von Tastern / Schaltern kümmert.

Kommentier in der Loop mal LCDMenuLib_control_digital aus und binde direkt die Lib ein mit den Funktionen die du benötigst.

Pseudocode:
Code: [Select]

if(debounce_dein_button_enter() ...)
   LCDML.Button_enter();

if (...)
   LCDML.Button_up_down_left_right(_LCDMenuLib_button_up);

if ..
   LCDML.Button_up_down_left_right(_LCDMenuLib_button_down);

// oder einen dieser virtuellen Menu Buttons
LCDML.Button_up_down_left_right(_LCDMenuLib_button_left);
LCDML.Button_up_down_left_right(_LCDMenuLib_button_right);
LCDML.Button_quit();


Ich hoffe das führt zum Ziel.
Falls du eine Lauffähige Version hast, würde ich mich über die Lösung freuen und den Code bei mir integrieren.

Hallo, danke für deine Hilfe, aber das übersteigt meine Programmier fähigkeiten :smiley-roll:

Aber ich habe das Problem Hardwaremässig gelöst mit einem 100n Kondensator parallel zum Taster.
Jetzt funktioniert es sehr gut.
Kann auch an meinen billig Printtastern gelegen haben die mit sicherheit noch erheblich mehr prellen als andere "bessere" Taster.
Nochmal DANKE!!!

sschultewolter

Mechanische Taster prellen immer, mal mehr und mal weniger. DEN nicht-prellenden mechanischen Taster gibt es nicht. Wenn ja, dann auch nur weil entsprechend mit ICs bereits das Signal entprellt wird. Kondensator reicht für die meisten Fälle
Keinen technischen Support über PN!

flansch

Hallo,

bin wirklich begeistert von dieser Bibliothek und hab jetzt schon einige Zeit damit experimentiert. Nun hatte ich das MacBook nicht im Haus und wollte mein Projekt unter Ubuntu 14.04 weiter bearbeiten. Leider kann ich hier nicht kompilieren, bekomm folgenden Output:

Code: [Select]

In file included from /home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib.h:118:0,
                from lcdml.ino:7:
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_0_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:54:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_18_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:55:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_19_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:56:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_20_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:57:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_21_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:58:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_22_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:59:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_23_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:60:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_24_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:61:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_25_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:62:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_26_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^
lcdml.ino:63:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:104:54: error: variable 'g_LCDMenuLib_lang_27_var' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM prog_char g_LCDMenuLib_lang_ ## name ##_var[]  = content;\
                                                     ^

< und so weiter ... >


lcdml.ino:88:1: note: in expansion of macro 'LCDMenuLib_element'
/home/flansch/sketchbook/libraries/LCDMenuLib/LCDMenuLib_makros.h:245:46: error: variable 'g_LCDMenuLib_lang_table' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 PROGMEM const char *g_LCDMenuLib_lang_table[] = { LCDMenuLib_lang_repeat(N) }; LCDMenuLib_initObjects()
                                             ^
lcdml.ino:89:1: note: in expansion of macro 'LCDMenuLib_createMenu'


Soweit ich das herausgefunden habe, hat sich beim Kompiler gcc von Version 4.6.0 auf 4.6.1 etwas verändert, möglicherweise liegt's an den Named Address Spaces (http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Named-Address-Spaces.html). Auf dem MacBook hab ich Kompilerversion 4.2.1, unter Ubuntu 4.8.2. Ich hab nun schon versucht das selbst zu beheben, produziere damit aber immer nur neue Fehlermeldungen  :( Hab einfach noch zu wenig Erfahrung mit dem Arduino, und C-Programmierung ist bei mir inzwischen tatsächlich schon Jahrzehnte her...

Läuft das bei jemandem unter Ubuntu bzw. mit 'nem aktuelleren Kompiler?

Jomelo

Hi, ich installier mir mal eben Ubuntu (VirtualBox) und werde das testen, aber bis ich dann dazu eine Lösung herausgefunden habe, die sich in allen Versionen übersetzen lässt kann es etwas dauern.

Hallo,
ich hab da noch mal ein paar Fragen. Ganz einfach für euch bestimmt...
Erstmal was aktuelles:
Ich will einen Schrittmotor ansteuern und ihn einzelne Schritte machen lassen. Je nachdem wie viel grad er sich drehen soll.
bekomme aber eine Fehlermeldung, die ich nicht verstehe... hab mir gedacht ich mach das über ne einfache for schleife.
              for( int a = 0; a = schritt_anzahl; a++ )
                {
                  takt_output = HIGH;
                  delay(pause);
                  takt_output = LOW;
                  delay(pause);
                }
Die Fehlermeldung:
LCDML_function:252: error: lvalue required as left operand of assignment
252 ist der takt_output = HIGH;

Ich vermute das ich den Digitalen I/O völlig falsch definiert habe... Könnte mir wer sagen wo ich das mache?
Habe als letztes versucht in lcdml unter pin settings fest zu legen.

#define takt_output                      3

Dann habe ich in void setup

pinMode(takt_output, OUTPUT);

eingefügt...Ab ich denke ich habe da wieder was missverstanden und das geht ganz anders..

Jetzt zu ein paar allgemeinen fragen wenn es euch nichts aus macht.

lcd.print(F("3 mal Links drucken"));

was hat das mit dem (F("xxxx")) auf sich? Geht ja auch ohne...

Bei mir sind die Tx & Rx (D0 & D1) immer High. Warum? Kann ich die auch noch als "freie" I/O´s benutzen?
Wenn ja, natürlich noch die frage wie?

Und zu guter letzt bin ich durch die Aufteilung des Programms in die drei tabs ein wenig verwirrt( wobei ich idese aufteilung sehr gut finde, da sie das alles viel übersichtlicher macht).
Aber wo deffiniere ich generell die I/O´s und wo globale Variablen?

Schon mal danke für eure Zeit und Gedult

Jomelo

Globale Variablen kannst du überall definieren, ich mach das immer entweder im ersten Tab, oder nur über den Funktionen in denen ich diese benötige. Der beste Weg ist mein erster Vorschlag.

Zu den anderen Fragen, erstell bitte ein neues Thema, da die Diskussion hier nur Verwirrung stiftet, bzw. benutz die Boardsuche zum F(..) Makro ;-)

skorpi08


Zu den anderen Fragen, erstell bitte ein neues Thema


Brauch er/sie nicht, gibts bereits paar Seiten zurück:
http://forum.arduino.cc/index.php?topic=256916.0
Ansonsten, :D

http://arduino.cc/en/Tutorial/DigitalPins
http://arduino.cc/en/Reference/PinMode
http://arduino.cc/en/Reference/DigitalRead
http://arduino.cc/en/Reference/DigitalWrite
http://arduino.cc/en/Tutorial/HomePage
Nicht Mensch, nicht Tier: Programmierer halt...

Alles klar, werde ich mich schlau lesen.
Vielen dank Ihr beiden.

P.S.: er  ;)

Hallo
ich möchte das Menü für eine Satelliet-Positionierer verwenden.
Jetzt möchte ich einen Sensor ununterbrochen in der void loop (Rotary Messrad-Encoder)
laufen lassen um der Position zu berechnen.

                  menu 1      menu 2           menu 3      menu 4
East        astra 2           astra 3         astra 1         hotbird              west
limit                                                                                                        limit
0----------53-----------78-----  -84--------102--->>>>>-----200


Und diese Daten verwenden und in alle Menüpunkte angezeigen.
Der Zähler zählt aber das wird nicht live auf das lcd angezeigt.
Der LCD-Anzeige wird nicht dynamisch aktualisiert.
Wie kan ich das ändern hat jemand eine Lösung dar für.

ich habe das Forum gelesen , vielleicht , dass die Lösung bereits erwähnt wurde.
aber Deutsch ist nicht meine Sprache.





int sensorCounter = 0;   // counter for the number of sensor puls
int sensorState = 0;         // current state of the sensor
int lastsensorState = 0;     // previous state of the sensor
const int  sensorPin = 10;    // the pin that the sensor is attached to


LCDMenuLib_element(0  , Item         , Item_1        , "Satellite"          , FUNC);
LCDMenuLib_element(1  , Item_1       , Item_1_1      , "Back  "             , FUNC_back);
LCDMenuLib_element(2  , Item_1       , Item_1_2      , "Astra 1  "          , FUNC_astra);
LCDMenuLib_element(3  , Item_1       , Item_1_3      , "Astra 2  "          , FUNC);
LCDMenuLib_element(4  , Item_1       , Item_1_4      , "Astra 3 "           , FUNC);
LCDMenuLib_element(5  , Item_1       , Item_1_5      , "Hotbird  "          , FUNC);
LCDMenuLib_element(6  , Item_1       , Item_1_6      , "Eutelsat"           , FUNC);
LCDMenuLib_element(7  , Item_1       , Item_1_7      , "Nilesat  "          , FUNC);
LCDMenuLib_element(8  , Item         , Item_2        , "Setup"              , FUNC);
LCDMenuLib_element(9  , Item_2       , Item_2_1      , "Set limits"         , FUNC);
LCDMenuLib_element(10 , Item_2       , Item_2_2      , "Offset"             , FUNC);
LCDMenuLib_element(11 , Item_2       , Item_2_3      , "Back"               , FUNC_back);
LCDMenuLib_element(12 , Item_2_1     , Item_2_1_1    , "East limit"         , FUNC);
LCDMenuLib_element(13 , Item_2_1_1   , Item_2_1_1_1  , "Back"               , FUNC_back);
LCDMenuLib_element(14 , Item_2_1     , Item_2_1_2    , "West limit"         , FUNC);
LCDMenuLib_element(15 , Item_2_1_2   , Item_2_1_2_1  , "Back"               , FUNC_back);
LCDMenuLib_element(16 , Item_2_1     , Item_2_1_3    , "Back"               , FUNC_back);


void setup()
{   
  LCDMenuLib_setup(_LCDMenuLib_cnt);  /* Setup for LcdMenuLib */
  Serial.begin(9600);                 /* start serial */
  pinMode(sensorPin, INPUT);     // initialize the sensor pin as a input:
 

void loop()

  //LCDMenuLib_control_analog();      /* lcd menu control - config in tab "LCDML_control" */
  //LCDMenuLib_control_digital();     /* lcd menu control - config in tab "LCDML_control" */
  //LCDMenuLib_control_serial();        /* lcd menu control */
  LCDMenuLib_control_rotary();
  LCDMenuLib_loop();   /* lcd function call */
  FUNC_sensorCounter();
// Serial.println(LCDMenuLib_getActiveFuncId()); 
  //other function 

void FUNC_sensorCounter ()
{

// read the sensor input pin:
  sensorState = digitalRead(sensorPin);

  // compare the sensorState to its previous state
  if (sensorState != lastsensorState) {
    // if the state has changed, increment the counter
    if (sensorState == HIGH) {
      // if the current state is HIGH then the sensor
      // wend from low to high:
      sensorCounter++;       
     
    }
    else {      // if the current state is LOW then the sensor
                // wend from high to low:
    }
  } 
  lastsensorState = sensorState;// save the current state as the last state,
  //for next time through the loop

     }

***************************************************************************************
lcdml function

void FUNC_astra(void)
{
   /* setup function */
  if(!LCDML.FuncInit())
  {
 
   
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(sensorCounter);
}
/* end function for callback */
  if(LCDML.FuncEnd(0, 1, 1, 1, 1, 1)) /* (direct, up, down, left, right) */ 
  {
    /* do something bevor this function is closed */
  }
 
}


 
void FUNC_back(void)
{   
       
  LCDML.FuncInit();            /* setup function */
  LCDML.Button_quit();         /* quit button */   
  LCDML.FuncEnd(1,0,0,0,0,0);  /* direct func end */
}

********************************************************************************************

ROTARY ENCODER + BUTTON
Wenn jemand dies noch verwenden kann, so hab ich es gemacht mit meinem Drehgeber + Taste


LCDML
/* include libs */
#include <LiquidCrystal.h>
#include <LCDMenuLib.h>

#include <phi_interfaces.h>
#define Encoder1ChnA 2
#define Encoder1ChnB 3
#define EncoderDetent 20




//encoder mapping
char mapping1[]={'U','D'}; // This is a rotary encoder so it returns U for up and D for down on the dial.
phi_rotary_encoders my_encoder1(mapping1, Encoder1ChnA, Encoder1ChnB, EncoderDetent);
multiple_button_input* dial1=&my_encoder1;


//encoder button
#define enter_btn 6
#define total_buttons 1
char mapping[]={'E'};
byte pins[]={enter_btn};
phi_button_groups my_btns(mapping, pins, total_buttons);
multiple_button_input* pad1=&my_btns;
*********
snip---------

*********
void loop()

  //LCDMenuLib_control_analog();      /* lcd menu control - config in tab "LCDML_control" */
  //LCDMenuLib_control_digital();     /* lcd menu control - config in tab "LCDML_control" */
  //LCDMenuLib_control_serial();        /* lcd menu control */
  LCDMenuLib_control_rotary();
  LCDMenuLib_loop();   /* lcd function call */
***********************************************************************************

LCDML_control


void LCDMenuLib_control_rotary()
//rotary up-down
{
char temp;
temp=dial1->getKey(); // Use the phi_interfaces to access the same keypad
if (temp!=NO_KEY)
switch ( temp){
case 'U': LCDML.Button_up_down_left_right(_LCDMenuLib_button_up); break;
case 'D': LCDML.Button_up_down_left_right(_LCDMenuLib_button_down); break;
}
//rotary button
{
char temp1;
  temp1=my_btns.getKey(); // Use phi_button_groups object to access the group of buttons
//  temp=pad1->getKey(); // Use the generic multiple_button_interface to access the same hardware
  if (temp1!=NO_KEY) Serial.write(temp1);
  switch (temp1){
  case 'E': LCDML.Button_enter(); break;
}
}
}

Jomelo

Hello,

you can post code in code tags  with  [ code ] ... [ /code ] without spaces.

Your Problem is, that you try to change the content in the function setup. This setup is run only at first call or on an recall if you have chosed another menu element before.

Look on the examples with Timer or on this code:
Code: [Select]

/* copy this variable to your globals */
int sensorCounterOld = 0;

void FUNC_astra(void)
{
 /* setup function */      
 if(!LCDML.FuncInit())
 {
   /* do nothing else here */          
   lcd.clear();      
 }
 
 /* loop area: this is the part, to add code  */  
 if(sensorCounter != sensorCounterOld) { // only update your lcd when new data is available
sensorCounterOld = sensorCounter;  // your lcd is not so fast
lcd.clear();
lcd.setCursor(0,0);
lcd.print(sensorCounter);
 }
 /* end loop area */
 
 /* end function for callback */
 if(LCDML.FuncEnd(0, 1, 1, 1, 1, 1)) /* (direct, enter, up, down, left, right) */  
 {
   /* do something bevor this function is closed */      
 }
}

I hope it help you.

Thank you very  much for you fast answer Jomelo

Tried you code and it works.
Only thing is that the lcd only shows the counter  until the Rotary wheel moves.
It is blank when I acces the menu  astra or astra2.....
I'm glad I have asked it here.
I asked it on a Different Dutch forum to, but there was immediately thrown with difficult code when in fact it's as simple as that.


Thanks again.

Jomelo

Hi,
change my function to this and it works in all other functions:
Code: [Select]

/* copy this variable to your globals */
int sensorCounterOld = 0;

void FUNC_astra(void)
{
 /* setup function */      
 if(!LCDML.FuncInit())
 {    
   lcd.print(sensorCounter);  // <== this line is new        
   lcd.clear();      
 }
 
 /* loop area: this is the part, to add code  */  
 if(sensorCounter != sensorCounterOld) { // only update your lcd when new data is available
sensorCounterOld = sensorCounter;  // your lcd is not so fast
lcd.clear();
lcd.setCursor(0,0);
lcd.print(sensorCounter);
 }
 /* end loop area */
 
 /* end function for callback */
 if(LCDML.FuncEnd(0, 1, 1, 1, 1, 1)) /* (direct, enter, up, down, left, right) */  
 {
   /* do something bevor this function is closed */      
 }
}

Jomelo

Update: 31.07.2014
- Kann nun auch in der Arduino Version 1.5.x kompeliert werden
- Kann nun auch unter Linux übersetzt werden (Ubuntu 14.04)
- Leicht anders Verfahren um Menüelemente zu erzeugen (das alte funktioniert auch noch)
- zwei neue Makros die zu einer Element-ID den Text aus dem Flash laden
- eine neue Funktion in der Lib: getCursorPos(); => liefert die aktuelle Kursor Position.


Initialisierung des Menüs:
Code: [Select]

LCDMenuLib_add(0  , root         , 1  , "Information"        , FUNC_information);
LCDMenuLib_add(1  , root         , 2  , "Zeit Info"          , FUNC_timer_info);
LCDMenuLib_add(2  , root         , 3  , "Einstellungen"      , FUNC);
LCDMenuLib_add(3  , root_3       , 1  , "Werte veraendern"   , FUNC);
LCDMenuLib_add(4  , root_3       , 2  , "Irgendwas"          , FUNC);
LCDMenuLib_add(5  , root         , 4  , "Programme"          , FUNC);

"roor" steht für die Ebene 0. Sobald ein Element zu einer neuen Ebene hinzugefügt werden kann, ist dies mit root_"bezeichnung_der_ebene_davor" möglich. Die alte Intialisierung mit LCDMenuLib_element(....) ist weiterhin möglich. 

LCDMenuLib_getElementName(variable, element_id)
Kann, wenn das Element nicht existiert zu abstürzen führen.
Code: [Select]

char test[20];
LCDMenuLib_getElementName(test, 0);
Serial.println(test);


LCDMenuLib_getElementNameChecked(variable, element_id, check_variable)
Überprüft zusätzlich ob das Element existiert.
Code: [Select]

char test[20];
boolean check = False;
LCDMenuLib_getElementName(test, 0, check);
if(check == true) {
  Serial.println(test);
}


@flansch
Das kompilieren mit der neusten gcc Komiler Version ist nun möglich

@clic
Danke für den Tipp mit den digitalen Anschlüssen 0 und 1, diese sind natürlich für die Serielle-Schnittstelle und nicht für Buttons unter  LCDMenuLib_control_digital zu verwenden. Die Beispiele sind nun angepasst.

flansch

Hallo Jomelo,

danke für die rasche Reaktion, nun läuft auch bei mir unterm aktuellen Ubuntu wieder alles super  :)

lg
Flansch

Go Up