M2tklib: Menu oon LCD, but buttons don't react

Hey,

I have a weird issue. I set up a Mega 2560 with two push buttons on inputs 6 and 7. They are debounced with hardware. Tested throughout, and it works well; for instance with led on/off examples.
Have downloaded latest M2tklkib, added LCD 16x2 (also works well) and using liquidCrystal. Now trying out examples. Have set correct inputs for buttons, correct LCD size, but the menu is not responding to any button push.

Retested without hardware debouncing, same result: no response seen.

Any suggestions where to look further?

Michel

Post your sketch

They are debounced with hardware.

What does this mean? Schematic?

Oliver

Code:
example StrList

/*

  StrList.pde

  m2tklib = Mini Interative Interface Toolkit Library
  
  Copyright (C) 2011  olikraus@gmail.com
  
  LiquidCrystal 16x4 example

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <LiquidCrystal.h>
#include "M2tk.h"
#include "utility/m2ghlc.h"

LiquidCrystal lcd(8,9,10,11,12,13);

uint8_t uiKeySelectPin = 6;
uint8_t uiKeyNextPin = 7;

const char *selected = "Nothing";
const char *el_strlist_getstr(uint8_t idx, uint8_t msg) {
  const char *s = "";
  if  ( idx == 0 )
    s = "Apple";
  else if ( idx == 1 )
    s = "Banana";
  else if ( idx == 2 )
    s = "Peach";
  else if ( idx == 3 )
    s = "Pumpkin";
  else if ( idx == 4 )
    s = "Corn";
  if (msg == M2_STRLIST_MSG_GET_STR) {
    /* nothing else todo, return the correct string */
  } else if ( msg == M2_STRLIST_MSG_SELECT ) {
    selected = s;
  }
  return s;
}

uint8_t el_strlist_first = 0;
uint8_t el_strlist_cnt = 5;

M2_STRLIST(el_strlist, "l2w12", &el_strlist_first, &el_strlist_cnt, el_strlist_getstr);
M2_SPACE(el_space, "w1h1");
M2_VSB(el_strlist_vsb, "l2w1r1", &el_strlist_first, &el_strlist_cnt);
M2_LIST(list_strlist) = { &el_strlist, &el_space, &el_strlist_vsb };
M2_HLIST(el_strlist_hlist, NULL, list_strlist);

M2_SPACE(el_vspace, "w1h1");

M2_LABEL(el_label,NULL, "Selected:");
M2_LABELPTR(el_labelptr,NULL, &selected);
M2_LIST(list_label) = { &el_label, &el_labelptr };
M2_HLIST(el_label_hlist, NULL, list_label);

M2_LIST(list) = { &el_strlist_hlist, &el_vspace, &el_label_hlist };
M2_VLIST(el_vlist, NULL, list);
M2_ALIGN(top_el, "-1|1W64H64", &el_vlist);

M2tk m2(&top_el, m2_es_arduino, m2_eh_4bs, m2_gh_lc);

void setup() {
  m2_SetLiquidCrystal(&lcd, 16, 4);
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyNextPin);
}

void loop() {
  m2.checkKey();
  //m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
}

Hardware debounce:
Followed excellent schematic of http://www.jeremyblum.com/2011/03/07/arduino-tutorial-10-interrupts-and-hardware-debouncing/
My interpretation is attached

ButtonsMenu.jpg

Please note that when I remove the hardware debounce, I also have non responsing buttons. Example is adjusted for my setup, and other tests on button response do work (eg LED on/off).

Thanks for looking into this!

Hi

M2tklib expects a LOW if the button is pressed. This behavior makes it easy to attach a button to M2tklib by adding one end of the button to the Arduino pin and the other to GND.

But it also possible to implement buttons for your hardware. Let me know if you want to write your own event source.

Oliver

Here is a code for a custom "event source" with internal debounce algorithm, where button press creates a HIGH level at the input pin.

uint8_t m2_my_event_source(m2_p ep, uint8_t msg) {
  switch(msg) {
    case M2_ES_MSG_GET_KEY:
      if ( digitalRead(7) == HIGH )
        return M2_KEY_NEXT;
      if ( digitalRead(6) == HIGH )
        return M2_KEY_SELECT;
      return M2_KEY_NONE;
    case M2_ES_MSG_INIT:
      return 0;
  }
  return 0;
}

Same event source, bypassing the m2tklib debounce algorithm:

uint8_t m2_my_event_source(m2_p ep, uint8_t msg) {
  switch(msg) {
    case M2_ES_MSG_GET_KEY:
      if ( digitalRead(7) == HIGH )
        return M2_KEY_EVENT(M2_KEY_NEXT);
      if ( digitalRead(6) == HIGH )
        return M2_KEY_EVENT(M2_KEY_SELECT);
      return M2_KEY_NONE;
    case M2_ES_MSG_INIT:
      return 0;
  }
  return 0;
}

To apply this modified event source, change

M2tk m2(&top_el, m2_es_arduino, m2_eh_4bs, m2_gh_lc);

to

M2tk m2(&top_el, m2_my_event_source, m2_eh_4bs, m2_gh_lc);

Oliver

Hey,

Thanks for the replies and work on this. I tested your revised code that should go around the software debouncing. However, it turned out that the circuit then is very sensitive (moving 2-3 items in a list) or non-responsive again.

I tried with different number of checkKey(), but that didn't change much.

So in the end will remove the hardware debounce, and test if my wake-up interrupt is not too disturbed by that.