Git Product home page Git Product logo

md_uiswitch's Introduction

MD_UISwitch Universal User Interface Switch Library

arduino-library-badge

This library uniformly encapsulates the use of different types of switches for user input devices. The library is easily extended for additional switch types through a class hierarchy and inheritance model, following the code for existing switch types.

The library includes the following features:

  • Software debounce for all switch types.
  • Automatically detect switch press, double press, long press and auto repeat.
  • Can work with low/high or high/low transitions.
  • Timers are all software configurable - debounce time, double press time, long press time, and auto repeat period time.

Switch arrangements handled by the library are:

  • Momentary on type switches (MD_Switch_Digital class)
  • User managed signals eg, I/O expanders (MD_Switch_User class)
  • Analog resistor ladder switches (MD_Switch_Analog class)
  • Keypad matrix (MD_Switch_Matrix class)
  • Keypad matrix using 4017 IC (MD_Matrix_4017KM class)

If you like and use this library please consider making a small donation using PayPal

Library Documentation

md_uiswitch's People

Contributors

alf45tar avatar arduino12 avatar majicdesigns avatar scls19fr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

md_uiswitch's Issues

Version 2.0 is not backward compatible with 1.2.x

I using your fantastic library for my PedalinoMini project but with the latest version 2.0 nothing is working ad before. Most of the time press is not reported or block the execution.
PedalinoMini is working on ESP32 board with Arduino framework.

Thanks
alf45tar

Thinking about also using PCF8574

Hi.
Do you have any plan for using I2C expander PCF8574 or other expanders?
It could be nice if you also can expand you library with some I2C expanders.

It's a very good library to handle buttons.

Issue in 2.0.0 with multiple MD_UISwitch_Digital instances

Subject of the issue

I'm having an issue with the library where it does't seem to handle having multiple instances of the MD_UISwitch_Digital class instantiated in the code. Not sure if I have something configured wrong, but based on the documentation, this seems correct. (See below.)

Your Environment

Library Version: 2.0.0
Arduino IDE version: 1.8.8
Hardware model/type: ESP8266 / Wemos D1

Steps to Reproduce

With the code below, if you don't define MDUISWITCH_ENABLE and log the raw button states, the code outputs correctly. (In my case B1 and B2 have external pull-downs, B3 uses an internal pull-up, but the issue presents itself regardless of which buttons are wired up where...)

When using MD_UISwitch_Digital, BTN2 and BTN3 do not respond to any changes on the GPIO pins. For example, a single press of BTN1 yields:
B3: KEY_DOWN
B1: KEY_DOWN
B3: KEY_UP
B1: KEY_UP
B3: KEY_PRESS
B1: KEY_PRESS

BTN2 doesn't respond at all, although it does work correctly without MD_UISwitch.

BT3 single push generates:
B2: KEY_DOWN
B3: KEY_DOWN
B1: KEY_DOWN
B2: KEY_UP
B3: KEY_UP
B1: KEY_UP
B2: KEY_PRESS
B3: KEY_PRESS
B1: KEY_PRESS

If I downgrade to 1.2.1, things work fine, so this is something new in 2.0.

Code Demonstrating the Issue

#include <MD_UISwitch.h>

#define MDUISWITCH_ENABLE

#ifdef MDUISWITCH_ENABLE

MD_UISwitch_Digital BTN1(D1, HIGH);
MD_UISwitch_Digital BTN2(D2, HIGH);
MD_UISwitch_Digital BTN3(D7, LOW);

#endif


void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
  pinMode(D1, INPUT);
  pinMode(D2, INPUT);
  pinMode(D7, INPUT_PULLUP);

#ifdef MDUISWITCH_ENABLE
  BTN1.begin();
  BTN2.begin();
  BTN3.begin();
#endif
}

void loop() {
 #ifndef MDUISWITCH_ENABLE
  bool b1State = digitalRead(D1);
  bool b2State = digitalRead(D2);
  bool b3State = digitalRead(D7);
  Serial.println("B1: " + String(b1State) + ", B2: " + String(b2State) + ", B3: " + String(b3State));
#endif

#ifdef MDUISWITCH_ENABLE
  MD_UISwitch::keyResult_t b1_result = BTN1.read();
  logButtonState("B1", b1_result);
  MD_UISwitch::keyResult_t b2_result = BTN2.read();
  logButtonState("B2", b2_result);
  MD_UISwitch::keyResult_t b3_result = BTN3.read();
  logButtonState("B3", b3_result);
#endif

  delay(100);
  
}

void logButtonState(const char* buttonName, MD_UISwitch::keyResult_t state)
{
  switch (state)
  {
  case MD_UISwitch::KEY_NULL:      /* Serial.print("KEY_NULL"); */  break;
  case MD_UISwitch::KEY_UP:        Serial.printf("%s: KEY_UP\n", buttonName);     break;
  case MD_UISwitch::KEY_DOWN:       Serial.printf("%s: KEY_DOWN\n", buttonName);     break;
  case MD_UISwitch::KEY_PRESS:      Serial.printf("%s: KEY_PRESS\n", buttonName);     break;
  case MD_UISwitch::KEY_DPRESS:    Serial.printf("%s: KEY_DPRESS\n", buttonName);     break;
  case MD_UISwitch::KEY_LONGPRESS: Serial.printf("%s: KEY_LONGPRESS\n", buttonName);     break;
  case MD_UISwitch::KEY_RPTPRESS:  Serial.printf("%s: KEY_RPTPRESS\n", buttonName);     break;
  default:                         Serial.printf("%s: KEY_UNKNWN\n", buttonName);     break;
  }
}

Example MD_UISwitch compilation error

Good day.

I need some help to solve a extrange issue.

I have a compilation error seems because some issue with the library code, when try to compile example sketch for three analog switch buttons attached on a ESP8266 Wemos D1 mini:

"Arduino\libraries\MD_UISwitch\src\MD_UISwitch.cpp:43:5: error: return-statement with no value, in function returning 'MD_UISwitch::keyResult_t' [-fpermissive]"

Below my code (little changed from example to test only analog switch readings), but I too tried directly the example sketch downloaded with the library with same result:

`#include <MD_UISwitch.h>

#define TITLE "Analaog Input"

const uint8_t ANALOG_SWITCH_PIN = A0;       // switches connected to this pin

// These key values work for most LCD shields
MD_UISwitch_Analog::uiAnalogKeys_t kt[] =
{
  { 672, 15, 'R' },  // Right
  { 274, 15, 'C' },  // Left
  { 145, 15, 'L' },  // Down
  { 945, 15, 'D' },  // Right+Center
  { 405, 15, 'I' },  // LEft+Center
};

MD_UISwitch_Analog S(ANALOG_SWITCH_PIN, kt, ARRAY_SIZE(kt));

void setup(void)
{
  Serial.begin(115200);
  Serial.print(F("\n[MD_UISwitch "));
  Serial.print(F(TITLE));
  Serial.print(F(" Example]"));

  S.begin();
  S.enableDoublePress(false);
  S.enableLongPress(false);
  //S.enableRepeat(false);
  S.enableRepeatResult(true);
}

void loop()
{
  MD_UISwitch::keyResult_t k = S.read();

  switch (k)
  {
    case MD_UISwitch::KEY_NULL:      /* Serial.println("NULL"); */  break;
    case MD_UISwitch::KEY_PRESS:     Serial.print("\nKEY_SINGLE "); break;
    case MD_UISwitch::KEY_DPRESS:    Serial.print("\nKEY_DOUBLE "); break;
    case MD_UISwitch::KEY_LONGPRESS: Serial.print("\nKEY_LONG   "); break;
    case MD_UISwitch::KEY_RPTPRESS:  Serial.print("\nKEY_REPEAT "); break;
    default:                         Serial.print("\nKEY_UNKNWN "); break;
  }
  if (k != MD_UISwitch::KEY_NULL)
  {
    if (S.getKey() >= ' ')
    {
      Serial.print((char)S.getKey());
      Serial.print(" ");
    }
    Serial.print("[0x");
    Serial.print(S.getKey(), HEX);
    Serial.print("]");
  }
`}````

multiple push button

I have 10 push button? Any example how to use your library to use with multiple button? thanks

Debouncing Algorithm sensitive to short presses

Hello Marco,

I see an issue with the debouncing algorithm. It doesn't ignore presses shorter than the debounce time. When I press a single digital button shorter than the duration set in setDebounceTime(), the keyResult_t still returns a KEY_SINGLE event.

Isn't the whole idea of debouncing such that only after the button has been continuously and steadily pressed for the time defined in setDebounceTime(), only then it is supposed to send the logical signal of a keypress?

I tested this with a purposefully long debounce time of 400 ms:

#include <MD_UISwitch.h>

// Define what type of testing is being done
#define TEST_DIGITAL_SIMPLE 1

#if TEST_DIGITAL_SIMPLE
#define TITLE "Simple Digital"

const uint8_t DIGITAL_SWITCH_PIN = 2;       // switch connected to this pin
const uint8_t DIGITAL_SWITCH_ACTIVE = LOW;  // digital signal when switch is pressed 'on'

MD_UISwitch_Digital S(DIGITAL_SWITCH_PIN, DIGITAL_SWITCH_ACTIVE);
#endif

void setup() {
  Serial.begin(57600);
  Serial.print(F("\n[MD_UISwitch "));
  Serial.print(F(TITLE));
  Serial.print(F(" Example]"));

  S.begin();
  S.enableDoublePress(false);
  S.enableLongPress(false);
  S.enableRepeat(false);
  S.enableRepeatResult(true);
  setDebounceTime(400);

}

void loop() {
  // put your main code here, to run repeatedly:
  MD_UISwitch::keyResult_t k = S.read();

  switch(k)
  {
    case MD_UISwitch::KEY_NULL:      /* Serial.println("NULL"); */  break;
    case MD_UISwitch::KEY_PRESS:     Serial.print("\nKEY_SINGLE "); break;
    case MD_UISwitch::KEY_DPRESS:    Serial.print("\nKEY_DOUBLE "); break;
    case MD_UISwitch::KEY_LONGPRESS: Serial.print("\nKEY_LONG   "); break;
    case MD_UISwitch::KEY_RPTPRESS:  Serial.print("\nKEY_REPEAT "); break;
    default:                         Serial.print("\nKEY_UNKNWN "); break;
  }
  if (k != MD_UISwitch::KEY_NULL)
  {
    if (S.getKey() >= ' ')
    {
      Serial.print((char)S.getKey());
      Serial.print(" ");
    }
    Serial.print("[0x");
    Serial.print(S.getKey(), HEX);
    Serial.print("]");
  }

}

Unable to get a long press response from MD_UISwitch_Digital

IMPORTANT

Before submitting this issue

  • Have you tried using the latest version of the library?
  • Have you checked this has not already been submitted and/or resolved?
  • If you are requesting help a better choice may be the Arduino forum

Subject of the issue

I am unable to get a long press event to fire.

Your Environment

Library Version: 2.1.0
Arduino IDE version: 1.8.13
Hardware model/type: ESP8266
OS and Version: Windows 10

Steps to Reproduce

Using a momentary-on switch wired like this, I've been able to get a single press response and a double press response, but not a long press response.

Expected Behaviour

When I press and hold the button, after I let go, a long press response should have been received.

Actual Behaviour

If I press and hold the button, I receive a single press response while the button is still held down. I do not ever get a long press response.

Code Demonstrating the Issue

I'm running the code block before. On the button, I will do a single press, then a double press, then press and hold for long press and paste the Serial Monitor output.

#include <MD_UISwitch.h>
#define BUTTON_PIN                14    // GPIO Pin
MD_UISwitch_Digital Button(BUTTON_PIN, HIGH);

void setup() {
    Serial.begin(115200);
    Button.begin();
    Button.enableDoublePress(true);
    Button.enableLongPress(true);
    Button.enableRepeatResult(true);
}

void loop() {
    MD_UISwitch::keyResult_t k = Button.read();
    switch(k) {
    case MD_UISwitch::KEY_UP:        Serial.print("\nKEY_UP ");     break;
    case MD_UISwitch::KEY_DOWN:      Serial.print("\n\nKEY_DOWN ");   break;
    case MD_UISwitch::KEY_PRESS:
        Serial.print("Single press");
        Serial.println("\n");
        break;
    case MD_UISwitch::KEY_DPRESS:
        Serial.print("Double press");
        Serial.println("\n");
        break;
    case MD_UISwitch::KEY_LONGPRESS:
        Serial.print("Long press");
        Serial.println("\n");
        break;
    }
}

The Serial Monitor reads:

KEY_DOWN 
KEY_UP Single press



KEY_DOWN 
KEY_UP 

KEY_DOWN 
KEY_UP Double press



KEY_DOWN Single press


KEY_UP 

Thanks

I really appreciate the library and you taking the time to address the issue. I'm pretty new at this Arduino stuff, and the project I'm working on is the first C++ I've ever written. If it's user error, I humbly apologize for wasting your time!

False positive for KEY_SINGLE

Hello Marco,

I have tried your UI_Switch library with the test code below and I'm getting a false positive KEY_SINGLE detect about 1 in 20 times or even more often when I press the standard Arduino push button (attached image borrowed from ladyada.net)
6mmswitch_t

I used the following code (also attached):

#include <MD_UISwitch.h>

// Define what type of testing is being done
#define TEST_DIGITAL_SIMPLE 1

#if TEST_DIGITAL_SIMPLE
#define TITLE "Simple Digital"

const uint8_t DIGITAL_SWITCH_PIN = 2;       // switch connected to this pin
const uint8_t DIGITAL_SWITCH_ACTIVE = LOW;  // digital signal when switch is pressed 'on'

MD_UISwitch_Digital S(DIGITAL_SWITCH_PIN, DIGITAL_SWITCH_ACTIVE);
#endif

void setup() {
  Serial.begin(57600);
  Serial.print(F("\n[MD_UISwitch "));
  Serial.print(F(TITLE));
  Serial.print(F(" Example]"));

  S.begin();
  S.enableDoublePress(false);
  S.enableLongPress(false);
  S.enableRepeat(false);
  S.enableRepeatResult(true);

}

void loop() {
  // put your main code here, to run repeatedly:
  MD_UISwitch::keyResult_t k = S.read();

  switch(k)
  {
    case MD_UISwitch::KEY_NULL:      /* Serial.println("NULL"); */  break;
    case MD_UISwitch::KEY_PRESS:     Serial.print("\nKEY_SINGLE "); break;
    case MD_UISwitch::KEY_DPRESS:    Serial.print("\nKEY_DOUBLE "); break;
    case MD_UISwitch::KEY_LONGPRESS: Serial.print("\nKEY_LONG   "); break;
    case MD_UISwitch::KEY_RPTPRESS:  Serial.print("\nKEY_REPEAT "); break;
    default:                         Serial.print("\nKEY_UNKNWN "); break;
  }
  if (k != MD_UISwitch::KEY_NULL)
  {
    if (S.getKey() >= ' ')
    {
      Serial.print((char)S.getKey());
      Serial.print(" ");
    }
    Serial.print("[0x");
    Serial.print(S.getKey(), HEX);
    Serial.print("]");
  }

}

Debounce_test.zip

Navigation problem with ADKeyboard Module v2 DFRobot

Hello,

The navigation doesn't work correctly with this component some button work but randomly, i try to change the debounce time but nothing change, the solution is to add a delay(50) in the MD_UISwitch::keyResult_t MD_UISwitch_Analog::read(void) function, and with this, all work fine.

// work out what key this is
for (uint8_t i = 0; i < _ktSize; i++)
{
if ((v >= (_kt[i].adcThreshold - _kt[i].adcTolerance)) &&
(v <= (_kt[i].adcThreshold + _kt[i].adcTolerance)))
{
idx = i;
UI_PRINTS("\nV : ");
UI_PRINTS(v);
UI_PRINTS("\nACT : ");
UI_PRINTS(_kt[i].adcThreshold);
delay(50); // Ajout d'un délai pour éviter le bug des boutons qui fonctionne mal
break;
}
}

The programme works fine without this delay modification with the DFRobot shield LCD Keyshield 1.1 (after change the key value of course).

Best regards

Detect multiple concurrent button presses or long presses.

I'm really digging this library, great work.

I am trying to detect when two buttons are held simultaneously for a period of time (longpress).

I've tried a basic IF statement using both switches KEY_DOWN during the loop but have had no luck.

Thanks,
Pete

Tolerance to "too long" long press

IMPORTANT

Before submitting this issue
[ ] Have you tried using the latest version of the library?
YES
[ ] Have you checked this has not already been submitted and/or resolved?
YES
[ ] If you are requesting help a better choice may be the Arduino forum
CONSIDERED

Subject of the issue

My aim was to use this library to detect button presses for a MIDI foot pedal. I am using an UNO and have wired up 4 momentary switches in the internal pullup mode to 4 digital pins. The sample application works, but I made 2 small change, i.e.:

    BTN[i]->setPressTime(250);
    BTN[i]->setLongPressTime(1200);

which get me close the the more typical button press behaviour seen in such pedals, since otherwise, with default values most typical short presses were also being detected as long presses. However, I notice to behaviours which I'd like to change if possible. One is, that once in every 3-5 long-presses, I get one which is followed up by a "ghost short press". This is quite consistent, and this "ghost short press" seems to happen when I release the button after a long press.

Another observation is that long presses that are perhaps a bit too long, get detected as a short press (for the "press" transition) and another short press (apparently for the "release" transition). Can this behaviour be altered in the way that a long press, could be somewhat longer long-press can be had ?

Your Environment

Library Version: 2.1
Arduino IDE version: 1.8.10
Hardware model/type: Arduino UNO clone (w/ CH340 chip)
OS and Version: Lubuntu 19.10 64-bit on host PC

HowTo detect 2 keys pressed simultaneously with MD_UISwitch_Digital()

Hello,

pressing 2 keys simultaneously is often used to enter some kind of setup or factory default procedures.
I am facing the problem to detect 2 simultaneously pressed keys with MD_UISwitch_Digital().

Pressing one button for long time results in 'key repeat' answers from .read method.
When pressing the second button, the .read method answers 'KEY_NULL' as if no button is pressed.

regards
Wolfgang

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.