2 * @file makingYourOwnAnim.ino
3 * @brief Example showing how to manually fill a bar meter based on analog input WITHOUT built-in animations.
5 * This example show how you can construct your own animations.
6 * The animation built here displays a live analog signal level.
7 * The fill level is updated manually using setPixel() and show(), without calling preset animations().
8 * No delay() is used — a non-blocking loop based on millis() ensures responsiveness.
11 * - Supported driver with complatible library (SBK_MAX72xx or SBK_HT16K33 libraries)
12 * - Bar meter display or leds array wired to driver
13 * - A live analog signal connected to A0
16 * Samuel Barabé (Smart Builds & Kits)
24#define ANALOG_PIN A0 ///< Analog input pin
25#define UPDATE_INTV 50 ///< Refresh interval in milliseconds
26unsigned long lastUpdate = 0; ///< animations update tracking
28// ──────────────────────────────────────────────
29// SELECT YOUR DRIVER SETUP
30// Uncomment one of the following driver configurations
31// ──────────────────────────────────────────────
33/* === [A] Using MAX7219/MAX7221 via SOFTWARE SPI (any 3 digital pins) === */
34// #define DIN_PIN A4 ///< Define software SPI Data In pin
35// #define CLK_PIN A5 ///< Define software SPI Clock pin
36// #define CS_PIN A3 ///< Define SPI Chip Select pin
37// #include <SBK_MAX72xxSoft.h>
38// SBK_MAX72xxSoft driver(DIN_PIN, CLK_PIN, CS_PIN, 1); ///< Construct MAX72xx software SPI driver instance for 1 device : (DataIn pin, Clock pin, Chip Select pin, devices number)
39// #include <SBK_BarDrive.h>
40// SBK_BarDrive<SBK_MAX72xxSoft> bar(&driver, 0, MatrixPreset::BL28_3005SK); ///< Construct using matrix type bar meter preset (auto-mapped layout) : (driver, device index, MatrixPreset type)
42/* === [B] Using MAX7219/MAX7221 via HARDWARE SPI (dedicated MCU SPI pins) === */
43// #define CS_PIN A3 ///< Define SPI Chip Select pin
44// #include <SBK_MAX72xxHard.h>
45// SBK_MAX72xxHard driver(CS_PIN, 1); ///< Construct MAX72xx hardware SPI driver instance for 1 device : (Chip Select pin, devices number)
46// #include <SBK_BarDrive.h>
47// SBK_BarDrive<SBK_MAX72xxHard> bar(&driver, 0, MatrixPreset::BL28_3005SK); ///< Construct using matrix type bar meter preset (auto-mapped layout) : (driver, device index, MatrixPreset type)
49/* === [C] Using HT16K33 via I2C === */
50#include <SBK_HT16K33.h>
51const uint8_t NUM_DEV = 1; ///< Only one device : DEV0
52const uint8_t DEV0_IDX = 0; ///< Device DEV0 index
53const uint8_t DEV0_ADD = 0x70; ///< I2C Address (typically 0x70–0x77)
54const uint8_t DEV0_NUM_ROWS = 8; ///< 20-SOP HT16K33 with only 8 rows, 24-SOP has 12 rows, 28-SOP has 16 rows
55SBK_HT16K33 driver(NUM_DEV);
56#include <SBK_BarDrive.h>
57SBK_BarDrive<SBK_HT16K33> bar(&driver, 0, MatrixPreset::BL28_3005SK); ///< Construct using matrix type bar meter preset (auto-mapped layout) : (driver, device index, MatrixPreset type)
62#ifdef SBK_HT16K33_IS_DEFINED
63 // HT16K33 driver instance setup (demo uses a single device)
64 driver.setAddress(DEV0_IDX, DEV0_ADD); // Set I2C address for device 0
65 driver.setDriverRows(DEV0_IDX, DEV0_NUM_ROWS); // Set number of active anode outputs (rows)
69 bar.setDirection(BarDirection::FORWARD); // Optional: use REVERSE for opposite orientation
73 * @brief Main update loop using non-blocking timing.
77 uint32_t now = millis();
78 if (now - lastUpdate >= UPDATE_INTV)
82 // Read and map signal
83 uint16_t rawValue = analogRead(ANALOG_PIN);
84 uint8_t segs = map(rawValue, 0, 1023, 0, bar.getSegsNum());
86 // Update bar manually
87 for (uint8_t i = 0; i < bar.getSegsNum(); i++)
89 bar.setPixel(i, i < segs);
92 bar.show(); // Push changes to the display