Skip to content

Latest commit

ย 

History

35 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฑ Bingo Flashboard

An ESP32-S3 N16R8 development board drives a 105-LED 12V WS2811 bingo board โ€” and serves a full React web UI over WiFi so phones, tablets, and laptops can call games, join cards, hear call-outs, and print signed bingo sheets.

Connect to the BINGO network โ†’ open http://bingo.local (fallback http://192.168.4.1) โ†’ pick Board or Card mode โ†’ play.


โœจ Whatโ€™s in the box

๐ŸŽฎ Gameplay ๐Ÿ’ก Lights ๐Ÿ“ฑ Clients ๐Ÿ” Safety
42 game types 19 themes Board host UI PIN + 7-day token
Auto / manual calling Screensavers (13) Printed QR cards Unlock lockout
Physical buttons Called-number banner Live card sync Device-signed cards
Caller audio + jokes Winner animations Odds drawer Optional home WiFi

๐Ÿงฉ Hardware

Board: ESP32-S3 N16R8 development board โ€” ESP32-S3-WROOM-1, 16 MB flash, 8 MB PSRAM, dual USB-C, 44-pin DevKitC-1 layout

Strip: WS2811 ร— 105, 12V, single data line

Wire by GPIO numbers on the silkscreen (not classic 30-pin ESP32 charts). Full pinout: WIRING.md

Function GPIO Silkscreen Connect
LED data 4 4 (J1) Strip DIN
Button 1 16 16 (J1) Momentary โ†’ GND
Button 2 18 18 (J1) Momentary โ†’ GND (not 17)
Status LED 2 2 (J3) Header GPIO (onboard RGB is separate)
Ground โ€” G 12V (โˆ’) + strip GND

โš ๏ธ Never put 12V on ESP32 pins. Tie all grounds together. Power the board via USB-C (UART port) or 5V (J1).

๐ŸŽ›๏ธ Physical buttons

Button Short press Long press (~700โ€ฏms)
1 (game type) Cycle game type (when allowed) Reset active game
2 (draw / winner) Draw next (automatic style only) Winner / keep-going โ€” or, on a fresh manual game with zero calls: switch to automatic and draw the first number (does not turn on UI auto-call Play)

Any button exits LED test / screensaver.


๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   WiFi AP "BINGO"    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ESP32 firmware    โ”‚ โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ โ”‚  Browser (React SPA) โ”‚
โ”‚  FastLED โ†’ 105 LEDsโ”‚   REST + WebSocket   โ”‚  Board / Card / OCR  โ”‚
โ”‚  SPIFFS โ†’ UI+MP3s  โ”‚   Push snapshots     โ”‚  Served from /data   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  • Firmware: src/main.cpp โ€” game engine, LEDs, auth, cards, WiFi, NVS
  • Frontend: frontend/ โ€” Vite + React + TypeScript + Tailwind + shadcn/ui
  • SPIFFS: custom partition (~14โ€ฏMB) for UI + multi-voice caller packs โ€” partitions/bingo.csv (SPIFFS usable โ‰ˆ75% of partition; erase flash after map changes)
  • Dev mock: if the board is unreachable, the UI falls back to an in-memory mock API

๐ŸŽฏ Game features

Calling

  • Automatic โ€” Draw next / header Play timer / Button 2 short press
  • Manual โ€” Tap numbers on the board; Button 2 long-press can convert a blank manual game to automatic + first draw
  • Undo last call
  • Power-loss recovery โ€” call order / current / pool restore from NVS
  • Default auto-call interval: 10 seconds (configurable; Play stays UI-driven)

Game types

48 types in the generated catalog (Classics, Letters & Symbols, Shapes & Frames, Blocks & Arrows, Pictures, Combos & Rules, plus Battleship). The board/new-game UI uses a searchable, filterable picker with mini pattern previews. Physical Button 1 cycles every type in catalog order when changing type is allowed.

Canonical definitions live in scripts/generate-game-types.mjs (generates frontend + firmware tables). Multi-orientation types cycle display patterns on the LED matrix (synced to the UI). Double Bingo wins on any two Traditional lines; Blackout Lite wins at any 20 covered cells.

Battleship is an elimination game: last card still afloat wins; a card sinks when all its populated numbers are called (same-call co-survivors share). Sparse cards (blanks allowed, FREE at center) are supported. LED indicator: looping 1โ†’25 chase. Sink LEDs invert the board (uncalled lit); from call 38 the current number strobes red.

Cards may include blank cells; pattern wins only require populated cells in the mask. HMAC domain bingo-card-v2 covers all 25 cells (including blanks); legacy full-card signatures are still accepted.

Winners

  • Declare / clear winner (UI + Button 2 long-press)
  • Card-driven winners + keep-going with claimed pattern masks
  • Winner LED phases (board sparkle โ†’ scroll)
  • Winner activation can wait while call-out audio is still playing

๐Ÿ”Š Caller audio

Pre-recorded voice packs on SPIFFS / frontend/public/cv/{F1,F2,M1,M2}/ (short paths โ€” SPIFFS max ~31 chars):

  • Numbers B-1 โ€ฆ O-75
  • Utility: on, jokes-on, bingo
  • Optional jokes for every number (joke-B-1 โ€ฆ joke-O-75)

Board UI: Settings โ†’ Caller โ†’ voice + speech rate ยท unlock with a tap โ†’ volume / jokes ยท keepalive for iOS/Android ยท firmware audio hold so the next auto-draw waits for the clip (countdown still runs).

Regenerate with OpenAI TTS (requires .env OPENAI_API_KEY + ffmpeg):

CALLER_VOICE_PACKS=Male1,Male2,Female2 node scripts/generate-caller-audio-openai.mjs

Legacy macOS say generator (single pack):

./scripts/generate-caller-audio.sh

๐Ÿƒ Card mode & printable cards

  • Full 5ร—5 card with FREE center; re-roll / auto-sync
  • Join the live board session (no seed)
  • Joined cards: only called numbers markable; winner flash + confetti
  • Settings โ†’ Cards:
    • Download signed PDF (4 cards / page; FREE cell = QR)
    • Copy shareable claim links
  • QR / link joins via POST /card/claim with HMAC over the boardโ€™s stable device id
  • Scanning while already unlocked as Board can verify authenticity without switching modes

๐Ÿ” Board access

  • Default PIN: 1975 (change in Settings โ†’ Access)
  • Session token TTL: 7 days, persisted in NVS (survives reboot)
  • 5 failed unlocks โ†’ 30โ€ฏs lockout (429)
  • Mutating board APIs require X-Board-Token
  • Public paths: unlock, card join/mark/leave/claim/state sync
  • Expired auth prompts unlock in place (no forced Card-mode switch)

๐Ÿ’ก LED features

Feature Notes
Layout CSV-mapped; letters โ†’ numbers โ†’ game-type matrix
Themes 19 (static + animated)
Color modes Theme / solid / custom letter colors
Header color Dedicated BINGO letter LEDs
Game-type color Dedicated 5ร—5 matrix
Vibrance 0โ€“100 boost for strip punch
Current beacon Color + flash / pulse / strobe
Letter-full mode When a column is complete: on / off / number theme
Called-number banner Optional ~3โ€ฏs letter+digits glyph across the board
Screensavers 13 types on the full 21ร—5 matrix
LED test Sequenced strip test from Settings

๐Ÿ–ฅ๏ธ Web UI highlights

  • Mode chooser: Board vs Card
  • Odds drawer (Monte Carlo win estimates)
  • Per-mode light/dark themes (bingo-theme-board / bingo-theme-card; card defaults dark)
  • Settings tabs: LEDs ยท Screensaver ยท UI ยท Caller ยท Cards ยท WiFi ยท Webhooks ยท MQTT ยท Access
  • Optional STA WiFi join (home network) alongside / instead of AP-only use
  • Fullscreen, theme toggle, live player/card counts
  • UI-only BINGO color themes (do not change strip colors)

๐Ÿ“ก Networking

AP SSID BINGO
AP password washisnameo
AP IP 192.168.4.1
mDNS bingo.local
Config include/config.h

Realtime: WebSocket /ws (subscribe as board / card / none) + HTTP polling fallback.

Outbound integrations (STA required)

Settings โ†’ Webhooks and MQTT share the same event catalog. Each channel has its own enable checkboxes.

Event When
number_called Number drawn / called
number_undone Undo last call
winner_declared Winner declared (UI, card bingo, or Button 2)
winner_cleared Winner cleared / keep-going
game_started Game reset / new game
game_type_changed Game type changed
calling_style_changed Manual โ†” automatic

Webhooks: one HTTP POST URL + optional basic auth (username empty = no Authorization header). Password omit-on-save keeps the stored secret.

MQTT: broker host/port, optional username/password, publish topic, optional TLS (setInsecure). Master enable toggle. Publishes JSON to the configured topic when connected.

Payloads always include event, gameType, and callingStyle (automatic | manual). Browser caller voice is not sent.


๐Ÿ› ๏ธ Build & deploy

Needs: Node.js, npm, PlatformIO, Python 3 (for make qa)

One-command deploy

make deploy
# or pin the serial port (S3 boards often use usbmodem):
make deploy PIO_PORT=/dev/cu.usbmodem101

Pieces

make frontend-build   # Vite โ†’ data/ (prunes stale hashed assets; keeps MP3s)
make fw-upload        # firmware (esp32s3 + partitions/bingo.csv)
make fs-upload        # SPIFFS
make monitor          # serial @ 115200
make qa               # smoke tests โ†’ QA_BASE / QA_PIN

SPIFFS size guidance: UI + voice packs must fit in ~75% of the SPIFFS partition (filesystem overhead). Current map: ~2โ€ฏMiB app + ~14โ€ฏMiB SPIFFS. uploadfs writes the entire SPIFFS partition image. After changing partitions/bingo.csv, erase flash once before upload. Build prints prune size via scripts/prune-spiffs-data.mjs.

Local UI (no hardware)

cd frontend && npm install && npm run dev

Mock backend activates automatically if the ESP32 doesnโ€™t answer within ~2โ€ฏs. Force mock with VITE_MOCK=true.

Shared multi-tab mock (optional)

See frontend/dev/shared-mock-server.mjs for multi-browser mock sessions during development.


๐Ÿงช QA smoke tests

make qa
make qa QA_BASE=http://192.168.4.1 QA_PIN=1975

scripts/qa-board.py exercises unlock/lockout, game actions, screensaver quirks, LED test vs screensaver, auth headers, and more.


๐Ÿ“ Repo map

bingo-flashboard/
โ”œโ”€โ”€ src/main.cpp              # Firmware (game + LEDs + API + WS)
โ”œโ”€โ”€ include/config.h          # Pins, AP, PIN, NVS keys
โ”œโ”€โ”€ include/led_map.h         # Physical LED index maps
โ”œโ”€โ”€ partitions/bingo.csv      # Larger SPIFFS layout
โ”œโ”€โ”€ WIRING.md                 # ESP32-S3 wiring + pinout
โ”œโ”€โ”€ docs/                     # Hardware reference (optional diagrams)
โ”œโ”€โ”€ data/                     # SPIFFS payload (built UI + MP3s)
โ”œโ”€โ”€ frontend/                 # React app source
โ”‚   โ””โ”€โ”€ public/cv/{F1,F2,M1,M2}/  # Voice packs (short SPIFFS paths)
โ”œโ”€โ”€ scripts/
โ”‚   โ”œโ”€โ”€ generate-caller-audio-openai.mjs
โ”‚   โ”œโ”€โ”€ generate-caller-audio.sh
โ”‚   โ”œโ”€โ”€ prune-spiffs-data.mjs
โ”‚   โ””โ”€โ”€ qa-board.py
โ”œโ”€โ”€ Makefile                  # deploy helpers
โ””โ”€โ”€ platformio.ini

๐Ÿ”‘ Persistence cheatsheet

NVS (device): brightness, themes/colors, screensaver, auto-call seconds, game type, calling style, board PIN, device id, board token, letter-full / beacon / banner flags, WiFi STA creds, webhook URL/auth/flags, MQTT broker settings, live game snapshot, crash log.

Browser: UI themes (per mode), UI letter colors, auto-call seconds UI, board token/expiry, card id + card state, caller speech/jokes/rate prefs.


๐Ÿ“ License / notes

Personal / venue bingo hardware project. WiFi credentials and default PIN are intended for a local party AP โ€” change them before leaving the device on an open floor.

Happy daubing. ๐ŸŽ‰

About

Arduino/FastLED powered BINGO Flashboard application

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages