Calcifer's Cook-Off! utilizes an events and services framework to organize the software running the game system.
Services
Detects button presses, keystrokes (debug), and IR pan state changes
Button- / Pan-related events to KitchenSMService
Simulated key events (debug mode)
PanPulledOff, PanPushedOn
ButtonPushed (for all pans)
Button rising edges
Pan IR transitions (present ↔ absent)
Keystrokes for debug simulation
Main state machine controlling all pan states (Cooking, Burning, CoolDown, Done, Idle)
ES_INIT
ES_TIMEOUT
Button events(ButtonPushed)
Pan presence events(PanPulledOff, PanPushedOn)
Global inactivity & countdown timers
GameOver
Pan state transitions
Servo & LED update triggers
Handles scrolling and static messages on the LED matrix (WELCOME, GAMEOVER, ERROR, countdown)
ES_INIT
ES_NEW_INFO
ES_TIMEOUT (scroll timer)
ES_CountDown
LED update requests
Internal scroll events
Direct write instructions to LEDService
Refreshes and updates the LED matrix display using a two-state (Idle/Update) FSM
ES_INIT
ES_NEW_INFO
ES_UPDATING (internal)
ES_TIMEOUT
ES_UPDATING
Completion signals back to PrintService
Set up SPI, ADC, GPIO, PWM, timers, and all pan structures
Initialize each pan’s state to Welcome, reset counters, and clear LEDs
Display WELCOME message
Transition into Welcome for each pan
Cooking
Every Counter Timer timeout:
Increase cooked counter
Add a “doneness” pixel to LED matrix
Restart counter timer
When BurningStart timer expires:
Switch to Burning
Turn on red LED, turn off green LED
Turn on speaker
If PanPulledOff:
Stop burn timer
Transition to ReadyforCOOK
When FoodCooked counter reaches 24 (DISHCOMPLETE):
Transition to Done
Countdown timer expiration → Idle (Game Over)
No-Input timer expiration → Error + global TIMEOUT → Game Over
CoolDown
If PanPushedOn:
Stop cool timer
Return to Burning, turn speaker back on
When Cool timer expires:
Turn on green LED, turn off red LED
Transition to ReadyforCOOK
Events Monitored:
Cool timer timeout
PanPushedOn
Countdown / No-Input / Timeout timers (same behavior as above)
ReadyforCOOK
Wait for PanPushedOn:
Randomize burn delay
Restart burningStart timer
Restart counter timer
Transition to Cooking
Countdown, No-Input, Timeout → possible Game Over
Idle (Game Over & Reset)
Display GAME OVER message
Turn off all LEDs and speaker
Stop all pan timers
Move servo to dispense reward if required
Wait 7 seconds
Reset all pans to Welcome, clear counters
Re-display WELCOME screen
Restart for next game
Events:
GoIdle (from multiple states)
SERVO_TIMER for reward servo toggling
COUNTDOWN_OVER_DISPLAY_TIMER to return to Welcome
Show WELCOME message on the display (only pan 0 triggers message)
Wait for ButtonPushed
Ensure all pans are placed on their IR sensors
Clear display modules
Randomly choose a burn delay
Read potentiometer multiplier
Start:
Cooking counter timer
Burning-start timer
Game countdown timer
No-input timer
Turn on the green LED for that pan
Transition to Cooking
Events Received:
ButtonPushed
PanPushedOn / PanPulledOff (indirect global timers reset)
Burning
Every Counter Timer timeout:
Increase burnt counter
Add burn pixel to LED matrix
Restart timer
If FoodBurnt counter reaches 8 (FOODBURN):
Turn off red LED
Turn off speaker if no other pan is burning
Transition to Done
If PanPulledOff:
Pick random cool-down delay
Start Cool timer
Turn off speaker if no other pan burning
Transition to CoolDown
Countdown, No-Input, and Timeout behave same as Cooking state
Done
Turn off both LEDs
Track how many pans have finished
If all pans are Done:
Trigger Game Over → Idle
Also handles:
Countdown decrease
No-Input error
Global timeout → Idle
Message Routing
All display messages are sent via SPI to the PrintService using:
ES_NEW_INFO
ES_CountDown
ES_NEW_MESSAGE (depending on what is triggered)
Code Listing
Click the link below to see the code repository: