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);
}
}
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:
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.