Trinket sketch to build a react or 'like' button that counts button presses and displays them on a 7-segment or 14-segment LED backpack.

You need the following hardware to build this device:

Usage

Load the right sketch in Arduino depending on your hardware. The 7-segment display should use the TrinketReactCounter_7segment sketch, and the 14-segment quad alphanumeric display should use the TrinketReactCounter_14segment sketch. Make sure the following libraries are installed too (using the library manager or a manual install):

// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries
//
// SPDX-License-Identifier: MIT

// Adafruit Trinket React Counter Sketch - 7-segment display
//
// Use a 7-segment LED backpack to display the number of times a 
// button has been pressed.  Great for building a physical 'like'
// or react button.  The value will be stored  in EEPROM so it 
// will persist between power down/up.
//
// NOTE: As-is this sketch needs to run on a Trinket because it
// assumes the switch on pin #1 has a pull-down resistor to ground.
// If using another board without this pull-down you can explicitly
// add a ~10kohm resistor from digital #1 to ground.
//
// Author: Tony DiCola
// License: MIT (https://opensource.org/licenses/MIT)
#include <EEPROM.h>
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"


// Uncomment the line below to reset the counter value in EEPROM to zero.
// After uncommenting reload the sketch and during the setup the counter
// will be reset.  Then comment the line again and reload to start again
// (if you don't comment it out then every time the board powers on it
// will reset back to zero!).
//#define RESET_COUNT

// OR just hold the button for longer than the RESET_HOLD_SECOND below
// to reset the count!

// Configuration:
#define LED_BACKPACK_ADDRESS   0x70   // I2C address of the backpack display.
                                      // Keep the default 0x70 unless you
                                      // change the backpack's address bridges.

#define COUNT_BUTTON_PIN       1      // Digital input connected to the button that
                                      // will increase the count. This line should
                                      // have a pull-down resistor to ground.  The
                                      // opposite side of the button should be
                                      // connected to a high level like 5V or 3.3V.

#define COUNT_ADDRESS          0      // Address in EEPROM to store the counter.
                                      // This will take 2 bytes (16-bit value).
                                      // You don't need to change this unless you
                                      // want to play with different EEPROM locations.

#define RESET_HOLD_SECONDS     5      // Number of seconds to hold the button down to
                                      // force a reset of the count to zero.  Set to 0
                                      // to disable this functionality.

// 7-segment display
Adafruit_7segment backpack = Adafruit_7segment();
uint32_t holdStart = 0;

void update_display() {
  // Get the count value from EEPROM and print it to the display.
  uint16_t count;
  EEPROM.get(COUNT_ADDRESS, count);
  backpack.print(count, DEC);
  backpack.writeDisplay();
}

void setup() {
  // Setup button inputs.
  pinMode(COUNT_BUTTON_PIN, INPUT);
  
  // Initialize the LED backpack display.
  backpack.begin(LED_BACKPACK_ADDRESS);

  // Clear the count in EEPROM if desired.
  #ifdef RESET_COUNT
    uint16_t count = 0;
    EEPROM.put(COUNT_ADDRESS, count);
  #endif

  // Update the display with the current count value.
  update_display();

  // Reset the last known time the button wasn't being held.
  holdStart = millis();
}

void loop() {
  // Take a couple button readings with a small delay in between to detect when
  // the signal changes from high to low, i.e. the button was released.
  int firstCount = digitalRead(COUNT_BUTTON_PIN);
  delay(20);
  int secondCount = digitalRead(COUNT_BUTTON_PIN);

  // Check for count button release.
  if (firstCount == HIGH && secondCount == LOW) {
    // Button was released!
    // Increment the count value stored in EEPROM.
    uint16_t count;
    EEPROM.get(COUNT_ADDRESS, count);
    count += 1;
    EEPROM.put(COUNT_ADDRESS, count);
    // Update the display with the latest count value.
    update_display();
  }

  // Reset the hold start if the button wasn't pressed (i.e. first and last were not both high levels).
  if ((firstCount != HIGH) || (secondCount != HIGH)) {
    holdStart = millis();
  }

  // Check if the button has been held for the amount of reset time.
  if ((RESET_HOLD_SECONDS > 0) && ((millis() - holdStart) >= (RESET_HOLD_SECONDS*1000))) {
    // Reset to zero and update the display!
    uint16_t count = 0;
    EEPROM.put(COUNT_ADDRESS, count);
    update_display();
    // Reset the hold time to start over again.
    holdStart = millis();
    // Flash the display a few times to give time to remove finger.
    for (int i=0; i<5; ++i) {
      delay(200);
      backpack.clear();
      backpack.writeDisplay();
      delay(200);
      update_display();
    }
  }
}
// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries
//
// SPDX-License-Identifier: MIT

// Adafruit Trinket React Counter Sketch - 14-segment quad alpha display
//
// Use a 14-segment quad alphanumeric LED backpack to display the 
// number of times a button has been pressed.  Great for building
// a physical  'like' or react button.  The value will be stored 
// in EEPROM so it will persist between power down/up.
//
// NOTE: As-is this sketch needs to run on a Trinket because it
// assumes the switch on pin #1 has a pull-down resistor to ground.
// If using another board without this pull-down you can explicitly
// add a ~10kohm resistor from digital #1 to ground.
//
// Author: Tony DiCola
// License: MIT (https://opensource.org/licenses/MIT)
#include <EEPROM.h>
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"


// Uncomment the line below to reset the counter value in EEPROM to zero.
// After uncommenting reload the sketch and during the setup the counter
// will be reset.  Then comment the line again and reload to start again
// (if you don't comment it out then every time the board powers on it
// will reset back to zero!).
//#define RESET_COUNT

// OR just hold the button for longer than the RESET_HOLD_SECOND below
// to reset the count!

// Configuration:
#define LED_BACKPACK_ADDRESS   0x70   // I2C address of the backpack display.
                                      // Keep the default 0x70 unless you
                                      // change the backpack's address bridges.

#define COUNT_BUTTON_PIN       1      // Digital input connected to the button that
                                      // will increase the count. This line should
                                      // have a pull-down resistor to ground.  The
                                      // opposite side of the button should be
                                      // connected to a high level like 5V or 3.3V.

#define COUNT_ADDRESS          0      // Address in EEPROM to store the counter.
                                      // This will take 2 bytes (16-bit value).
                                      // You don't need to change this unless you
                                      // want to play with different EEPROM locations.

#define RESET_HOLD_SECONDS     5      // Number of seconds to hold the button down to
                                      // force a reset of the count to zero.  Set to 0
                                      // to disable this functionality.

// 14-segment quad alphanumeric display
Adafruit_AlphaNum4 backpack = Adafruit_AlphaNum4();
uint32_t holdStart = 0;

void update_display() {
  // Get the count value from EEPROM and print it to the display.
  uint16_t count;
  EEPROM.get(COUNT_ADDRESS, count);
  // Use writeDigitRaw function to write out each digit for the thousands,
  // hundreds, tens, and ones place.
  int thousands = count / 1000;
  int remainder = count % 1000;
  int hundreds = remainder / 100;
  remainder = remainder % 100;
  int tens = remainder / 10;
  remainder = remainder % 10;
  // Check if the value is too large to display and just print dashes.
  if (thousands >= 10) {
    backpack.writeDigitAscii(0, '-');
    backpack.writeDigitAscii(1, '-');
    backpack.writeDigitAscii(2, '-');
    backpack.writeDigitAscii(3, '-');
  }
  else
  {
    // Print out the number starting from the first non-zero digit.
    if (thousands > 0) {
      backpack.writeDigitAscii(0, '0'+thousands);
      backpack.writeDigitAscii(1, '0'+hundreds);
      backpack.writeDigitAscii(2, '0'+tens);
      backpack.writeDigitAscii(3, '0'+remainder);
    }
    else if (hundreds > 0) {
      backpack.writeDigitAscii(1, '0'+hundreds);
      backpack.writeDigitAscii(2, '0'+tens);
      backpack.writeDigitAscii(3, '0'+remainder);
    }
    else if (tens > 0) {
      backpack.writeDigitAscii(2, '0'+tens);
      backpack.writeDigitAscii(3, '0'+remainder);
    }
    else {
      backpack.writeDigitAscii(3, '0'+remainder);
    }
  }
  backpack.writeDisplay();
}

void setup() {
  // Setup button inputs.
  pinMode(COUNT_BUTTON_PIN, INPUT);
  
  // Initialize the LED backpack display.
  backpack.begin(LED_BACKPACK_ADDRESS);

  // Clear the count in EEPROM if desired.
  #ifdef RESET_COUNT
    uint16_t count = 0;
    EEPROM.put(COUNT_ADDRESS, count);
  #endif

  // Update the display with the current count value.
  update_display();

  // Reset the last known time the button wasn't being held.
  holdStart = millis();
}

void loop() {
  // Take a couple button readings with a small delay in between to detect when
  // the signal changes from high to low, i.e. the button was released.
  int firstCount = digitalRead(COUNT_BUTTON_PIN);
  delay(20);
  int secondCount = digitalRead(COUNT_BUTTON_PIN);

  // Check for count button release.
  if (firstCount == HIGH && secondCount == LOW) {
    // Button was released!
    // Increment the count value stored in EEPROM.
    uint16_t count;
    EEPROM.get(COUNT_ADDRESS, count);
    count += 1;
    EEPROM.put(COUNT_ADDRESS, count);
    // Update the display with the latest count value.
    update_display();
  }

  // Reset the hold start if the button wasn't pressed (i.e. first and last were not both high levels).
  if ((firstCount != HIGH) || (secondCount != HIGH)) {
    holdStart = millis();
  }

  // Check if the button has been held for the amount of reset time.
  if ((RESET_HOLD_SECONDS > 0) && ((millis() - holdStart) >= (RESET_HOLD_SECONDS*1000))) {
    // Reset to zero and update the display!
    uint16_t count = 0;
    EEPROM.put(COUNT_ADDRESS, count);
    update_display();
    // Reset the hold time to start over again.
    holdStart = millis();
    // Flash the display a few times to give time to remove finger.
    for (int i=0; i<5; ++i) {
      delay(200);
      backpack.clear();
      backpack.writeDisplay();
      delay(200);
      update_display();
    }
  }
}

This guide was first published on Mar 13, 2016. It was last updated on Mar 13, 2016.

This page (Software) was last updated on Oct 21, 2021.

Text editor powered by tinymce.