/*
Arduino | off-topic
Project: NorthAccelBarbieWorldChallenge
Author: alexsbmagalhaes
Date: Friday, December 19, 2025 8:45 PM
https://wokwi.com/projects/450102709398201345
What does it do?
Counts up when pressing the right button
Counts down when pressing the left button
Press and release the button to increment/decrement by 1
Long press to go by 10
This revision uses LC_baseTools, https://github.com/leftCoast/LC_baseTools,
to handle the debouncing and short / long press of the buttons.
Arrays are used to greatly shorten (to about 25% of the original) the code
needed to show digits on the seven segment display.
*/
#include <mechButton.h>
const int NUM_DIGS = 2;
const int NUM_SEGS = 7;
const int DIG_PINS[] = {4, 5};
const int SEG_PINS[] = {3, 2, 9, 7, 10, 6, 8};
// lookup table, which segments are on for each value
const byte SEG_BYTES[] = {
0xFC, /* 0 */
0x60, /* 1 */
0xDA, /* 2 */
0xF2, /* 3 */
0x66, /* 4 */
0xB6, /* 5 */
0xBE, /* 6 */
0xE0, /* 7 */
0xFE, /* 8 */
0xF6, /* 9 */
0x00 /* blank */
};
int displayValue = 0;
mechButton dnBtn(12);
mechButton upBtn(11);
timeObj dnShortTimer(250, false);
timeObj dnLongTimer(1000, false);
timeObj upShortTimer(250, false);
timeObj upLongTimer(1000, false);
void downBtnClbk(void) {
if (dnBtn.getState()) { // if button released
if (!dnShortTimer.ding() && dnShortTimer.getFraction() != 1) { // and some time spent before first timer expired...
displayValue--; // displayValue down by 1
}
dnShortTimer.reset(); // reset timers, go to rest state
dnLongTimer.reset();
} else { // if button pressed
dnShortTimer.start(); // start short timer
}
}
void upBtnClbk(void) {
if (upBtn.getState()) { // see downBtnClbk comments
if (!upShortTimer.ding() && upShortTimer.getFraction() != 1) {
displayValue++;
}
upShortTimer.reset();
upLongTimer.reset();
} else {
upShortTimer.start();
}
}
// show a number on a specific digit
void showDigit(int num, int digit) {
// loop through each segment
for (int i = 0; i < NUM_SEGS; i++) {
digitalWrite(SEG_PINS[i], bitRead(SEG_BYTES[num], NUM_SEGS - i));
}
// toggle digit pin
digitalWrite(DIG_PINS[digit], LOW); // enable digit
digitalWrite(DIG_PINS[digit], HIGH); // disable digit
}
// display a multi-digit number on the 7-segment display
void showNumber(int number) {
int digitArray[NUM_DIGS] = {
(number / 10) % 10,
number % 10
};
for (int i = 0; i < NUM_DIGS; i++) {
showDigit(digitArray[i], i);
}
}
void setup() {
Serial.begin(115200);
// setup button callback functions
dnBtn.setCallback(downBtnClbk);
upBtn.setCallback(upBtnClbk);
// set pin modes
for (int i = 0; i < NUM_SEGS; i++) {
pinMode(SEG_PINS[i], OUTPUT);
}
for (int i = 0; i < NUM_DIGS; i++) {
pinMode(DIG_PINS[i], OUTPUT);
}
}
void loop() {
idle(); // Do the magic. (Runs things like the button.)
if (upShortTimer.ding()) { // if the short timer has gone off...
upLongTimer.start(); // start the long timer.
upShortTimer.reset(); // shut off the short timer.
displayValue += 10; // more than short, initial +10
}
if (upLongTimer.ding()) { // if the long timer went off...
displayValue += 10; // increment by 10
upLongTimer.start(); // restart long timer
}
if (dnShortTimer.ding()) { // same as up timers above, but down
dnLongTimer.start();
dnShortTimer.reset();
displayValue -= 10;
}
if (dnLongTimer.ding()) {
displayValue -= 10;
dnLongTimer.start();
}
if (displayValue > 99) displayValue = 99;
if (displayValue < 0) displayValue = 0;
// this must be called often
showNumber(displayValue);
}
Up
Down