Toggle library (dlloyd)

Note: No C/C++ skills, just a novice 'Arduino programmer'.

Primarily addressed to @dlloyd, author of the Toggle library, but welcome advice from any other user of it.

Following the brief discussion that arose in the randomness thread I've dipped my toe in this new library. For my music box project I'm sure it will prove superior to the method I kludged together. So I hope to use it in my existing Switch/Case structure.

Although I've briefly studied several of the GitHub examples, including Press_Code.ino, the penny has not yet dropped on the crucial part: how to use the reported code. My first code, based closely on Press_Code.ino, hopefully explains the detailed issue:

// Tuesday 5 July 2022: My first attempt to understand and edit for my
// music box project. That needs to recognise 12 button actions, for use with
// Switch/Case structure. This first try is to print a result when
// pin 3 of my UNO has ben pressed 8 times.

/************************************************************************
  Press Code Example:
  ===================
  A simple example that demonstrates how fast-clicks, short presses and
  long presses can be automatically detected and combined into a byte code.

  ⦿ Up to 225 possible codes with one button. The returned code (byte) is easy to
    interpret when viewed in hex format. For example, `47` is 4 long, 7 short presses.
    F2 is double-click, F7 is 7 `F`ast clicks.

  ⦿ Fast-click mode is detected if the first several presses are less than 0.2 sec,
    then all presses are counted as fast, up to 15 max (code `FF`).

  ⦿ Detection of long presses occurs if the first press is greater than 0.2 sec,
    then all presses greater than 0.2 sec are counted as long
    and all presses less than 0.2 sec are counted as short presses.

  ⦿ Detect up to 15 short presses
  ⦿ Detect up to 14 long presses
  ⦿ Returns code after button is released for 0.5 sec
  ⦿ simplifies your code while adding maximum functionality to one button

  Try on Wokwi UNO: https://wokwi.com/projects/334284248581145170
          ESP32-S2: https://wokwi.com/projects/334320246564323924
  ***********************************************************************/
#include "Arduino.h"
#include <Toggle.h>

const byte buttonPin = 3;
byte code;

Toggle sw1(buttonPin);

void setup()
{
  //  while (!Serial) { }; // Leonardo. (So presumably redundant
  //  on mu UNO.)
  Serial.begin(115200);
  sw1.begin(buttonPin);
}

void loop()
{
  sw1.poll(); // sw1 seems to be the name assigned to buttonPin
  sw1.pressCode(1); // print: (1) on () off; Unsure of purpose,
  // but I get lines like these in serial monitor:
  // 13:35:40.727 ->  Pressed for:   189 ms
  // 13:35:41.102 ->  Pressed for:   174 ms
  // 13:35:41.478 ->  Pressed for:   184 ms
  // 13:35:41.851 ->  Pressed for:   159 ms
  // 13:35:42.223 ->  Pressed for:   184 ms
  // 13:35:42.643 ->  Pressed for:   189 ms
  // 13:35:43.021 ->  Pressed for:   179 ms
  // 13:35:43.352 ->  Pressed for:   164 ms
  // 13:35:43.869 ->  Code:          F8

  // Wanted the following code to indicate the result, but nothing
  // prints.
  // If sw1 has been pressed briefly 8 times (which it has) then
  // print a message to that effect.
  
  if (code == 0xF8)
  {
    Serial.print(F("code = "));
    Serial.println(code);
  }
}

It seems the bug in the Press_Code.ino example. The variable "code" is not connecting to library results.
Try to change the second line of the loop()

code = sw1.pressCode(1);
1 Like

Hello,

  • The WOKWi example uses pin 2, but the code above uses pin 3.
  • sw1.pressCode(1) Allows printing the timing results (diagnostics)`
  • Use code = sw1.pressCode() to print just your own results
  • Use Serial.println(code, HEX); to view in hex F8, otherwise will display 248

Thanks, that's had me baffled for over an hour! With that line changed to :

code = sw1.pressCode(1); // print: (1) on () off;

I get this output.

15:45:48.025 -> code = 248
15:46:08.635 -> code = 248
15:48:31.961 ->  Pressed for:	79 ms
15:48:32.286 ->  Pressed for:	104 ms
15:48:32.566 ->  Pressed for:	99 ms
15:48:32.889 ->  Pressed for:	79 ms
15:48:33.212 ->  Pressed for:	99 ms
15:48:33.490 ->  Pressed for:	85 ms
15:48:33.766 ->  Pressed for:	89 ms
15:48:34.090 ->  Pressed for:	109 ms
15:48:34.551 ->  Code:		F8
15:48:34.551 -> 
15:48:34.551 -> code = 248

Now I just need to get my head around the 'mapping' between these:
8 brief presses --> F8 --> 248

All the returned codes are in hex format .... so its easier (and more intuitive to leave it and work with it in hex ... 0xF8

More examples:

  • double-click ---> 0xF2
  • 3 long, 4 short (or fast) presses ---> 0x34
1 Like

Thanks, got it just before I saw your post!
F==> 15, and 16 x 15 + 8 = 248.

Here's my first attempt at some Switch/Case code. Does it look OK to you?

I will need 18 cases, as I'm going to replace not only all those currently using my Mode switch (unreliably) but also the OneButton double clicks, which are too sensitive about pressed and released durations for my liking.

// Tuesday 5 July 2022:
// Experimental code for Switch/Case structure.
// Presumably ALL cases are actioned, albeit the earlier ones
// for very brief durations? (As with my own method.)
// Much faster than my existing method.

#include <Toggle.h>

const byte buttonPin = A5;
byte code;

Toggle sw1(buttonPin); // Assign sw1 as buttonPin for library

void setup()
{
  Serial.begin(115200);
  sw1.begin(buttonPin); // Button being used to start extra folders
  pinMode(2, OUTPUT); // TEMPORARY
}

void loop()
{
  sw1.poll(); // sw1 assigned to buttonPin
  code = sw1.pressCode(1); // print: (1) on () off

  if (code != 0)
  {
    actionCases();
  }
}

void actionCases()
{
  switch (code)
  {
    case 0xF1:
      Serial.println(F("1 brief press made"));
      // Some other action, e.g. start playing a music folder
      delay(1);
      break;
    case 0xF2:
      Serial.print(F("code = "));
      Serial.println(code);
      // Some other action, e.g. start playing a music folder
      digitalWrite(2, HIGH); // Temporary
      break;
    default:
      //
      break;
  }
}


Looks OK, however you might want to give the button and the Toggle object a new name (i.e folder). Here's a simulation of your code with new names and the debug print turned off:

Folder_Code_Test.ino

Here's an example to show how you can give names to each switch case:

Folder_Code_Test2.ino

1 Like

Many thanks for checking. I was pleased to find that my original did work OK. And it doesn't need that test for zero that I included. I've now made the naming improvements you suggested. And a trivial edit to the debug prints. All works fine:
https://wokwi.com/projects/336545436891349588

But I was struggling for a day or so in vain to get it working in my main sketch. I just could not get folderCode to register any button press.

However, I've just found the cause!

I had faithfully copied across the same code, but a carelessly written if() statement had introduced a delay of about 100 ms into the loop. That went unnoticed by the music playing code, but not your time-sensitive library.

Off tomorrow for a walking holiday with my wife so no more coding for a week.

Big thank you for introducing me to your Toggle library. :slightly_smiling_face:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.