Skip to main content

Project 2: Simulated Indoor Lighting Circuit

๐ŸŽฏ Project Objectivesโ€‹

Build a light switch simulation that:

  • Uses a push button to toggle a light on/off
  • Controls a full-color LED to emit white light when "on"
  • Displays current switch status on screen

๐Ÿ“‹ Required Hardwareโ€‹

ComponentQuantityConnection
Steamania JoyKit V21Main Controller
Push Button Module1Digital Input Pin
WS2812B Full-Color LED1On-board or External

๐Ÿ”ง Circuit Setupโ€‹

  1. Push Button: Connect to one of the digital input pins (e.g., DI0)
  2. WS2812B LED: Use on-board LED or connect to dedicated pin

๐Ÿ’ก Core Tasksโ€‹

Task 1: Configure Button as Digital Inputโ€‹

  • Use opcode 0x10 to configure IO pins
  • Set appropriate pin as digital input

Task 2: Implement Toggle Logicโ€‹

  • Detect button press (transition from HIGH to LOW or vice versa)
  • Toggle a state variable (0 = OFF, 1 = ON)
  • Implement debouncing to avoid false triggers

Task 3: Control LED Stateโ€‹

  • Turn LED white (0xFFFFFF) when switch is ON
  • Turn LED off (0x000000) when switch is OFF

Task 4: Display Statusโ€‹

  • Show "ON" or "OFF" text on screen
  • Optionally display current state indicator

๐Ÿ“ Reference Solutionโ€‹

Program Codeโ€‹

000 C7 0001 0000  ; Enable WS2812B LED control
001 10 0025 00F0 ; Configure IO pins: 4 inputs (0-3), 4 outputs (4-7)
002 10 0020 0000 ; Initialize state variable R20 = 0 (OFF)
003 10 0021 0000 ; Initialize previous button state R21 = 0
004 10 0028 FFFF ; Set foreground color to white (for text)
005 0E 0000 0010 ; Jump to main loop at line 010

; Main Loop - Start at line 010
010 14 0000 0000 ; Read digital inputs to R00
011 17 0000 0001 ; R00 = R00 AND 0x01 (check only DI0)
012 09 0000 0020 ; If R00 == R00 (button state), jump to line 020
; Actually: compare with previous state in R21

013 0E 0000 0030 ; Jump to update display (no change detected)

; Button Press Detected - Toggle State
020 11 0022 0020 ; Copy current button state to R22 (temp storage)
021 12 0020 0001 ; Toggle R20: if 0 then 1, if 1 then 0 (simplified)
022 0E 0000 0030 ; Jump to update LED and display

; Update LED and Display - Line 030
030 04 0000 0040 ; If R00 (state) > 0, jump to turn LED on
031 E4 0000 0000 ; Turn LED OFF (black)
032 55 000A 0000 ; Display "OFF" at position (10, 0)
033 0E 0000 0050 ; Jump to end of loop

040 E4 00FF FFFF ; Turn LED ON (white)
041 55 000A 0001 ; Display "ON" at position (10, 0)

; End of Loop - Line 050
050 11 0021 0000 ; Store current button state to R21 (previous)
051 02 0064 0000 ; Delay 100ms for debouncing
052 0E 0000 0010 ; Jump back to line 010 (main loop)

Improved Solution with Proper Toggle Logicโ€‹

000 C7 0001 0000  ; Enable WS2812B LED control
001 10 0025 00F0 ; Configure IO: lower 4 bits as input, upper 4 as output
002 10 0020 0000 ; R20 = Light state (0=OFF, 1=ON)
003 10 0021 0001 ; R21 = Previous button state (1 = not pressed)
004 10 0028 FFFF ; Set foreground color to white
005 0E 0000 0010 ; Jump to main loop

; Main Loop
010 14 0000 0000 ; Read DI to R00
011 17 0000 0001 ; R00 = R00 AND 0x01 (check DI0 only)
012 06 0001 0020 ; If R00 == 1 (button not pressed), jump to 020
013 06 0001 0050 ; If R00 == 1 (prev state also not pressed), jump to 050

; Button Pressed (transition from 1 to 0)
014 12 0020 0001 ; Toggle R20 (light state): 0โ†’1 or 1โ†’0
015 04 0000 0030 ; If R20 > 0 (light ON), jump to 030
016 E4 0000 0000 ; Turn LED OFF (black)
017 55 0A00 0000 ; Display "OFF"
018 0E 0000 0050 ; Jump to update previous state

020 0E 0000 0050 ; Button not pressed, skip toggle

030 E4 00FF FFFF ; Turn LED ON (white)
031 55 0A00 0001 ; Display "ON"

050 11 0021 0000 ; R21 = R00 (store current button state)
051 02 0096 0000 ; Delay 150ms (debounce)
052 0E 0000 0010 ; Loop back to start

Simplified and Corrected Solutionโ€‹

000 C7 0001 0000  ; Enable WS2812B LED control
001 10 0025 00F0 ; Configure IO pins: bits 0-3 as input, 4-7 as output
002 10 0020 0000 ; R20 = Light state (0=OFF, 1=ON)
003 10 0028 FFFF ; Set foreground color to white (for text display)
004 0E 0000 0010 ; Jump to main loop at line 010

; Main Loop - Check Button and Update State
010 14 0000 0000 ; Read digital inputs to R00
011 17 0000 0001 ; Mask to get only bit 0 (DI0): R00 = R00 AND 0x01
012 06 0001 0020 ; If DI0 == 1 (button NOT pressed), jump to 020 (skip)

; Button IS pressed (DI0 = 0)
013 12 0020 0001 ; Toggle R20: R20 = R20 + 1 (0โ†’1, 1โ†’2)
014 04 0001 0018 ; If R20 > 1, jump to 018 (reset to 0)
015 0E 0000 0019 ; Jump to update LED

018 10 0020 0000 ; R20 = 0 (reset state)

; Update LED Based on State
019 04 0000 001A ; If R20 > 0 (ON), jump to 01A
01A E4 0000 0000 ; LED OFF (black)
01B 55 0A00 0000 ; Display "OFF" at (10, 0)
01C 0E 0000 001E ; Jump to delay

01E E4 00FF FFFF ; LED ON (white: R=255, G=255, B=255)
01F 55 0A00 0001 ; Display "ON" at (10, 0)

; Delay and Loop
020 02 0096 0000 ; Delay 150ms (debounce)
021 0E 0000 0010 ; Jump back to line 010
000 C7 0001 0000  ; Enable WS2812B LED control
001 10 0025 00F0 ; Configure IO: lower 4 pins as input
002 10 0020 0000 ; R20 = Light state (0=OFF, 1=ON)
003 10 0021 0001 ; R21 = Previous button state (1=released)
004 10 0028 FFFF ; Set text color to white
005 0E 0000 0010 ; Jump to main loop

; Main Loop
010 14 0000 0000 ; Read DI to R00
011 17 0000 0001 ; R00 = R00 AND 0x01 (check DI0 only)
012 06 0001 0020 ; If button released (1), jump to 020
013 06 0001 0020 ; If previous also released, skip toggle

; Toggle state on button press
014 12 0020 0001 ; R20 = R20 + 1 (toggle)
015 04 0001 0017 ; If R20 > 1, jump to reset
016 0E 0000 0018 ; Jump to update

017 10 0020 0000 ; Reset: R20 = 0

; Update LED and display
018 04 0000 001A ; If R20 > 0, turn LED on
019 E4 0000 0000 ; LED OFF
01A 55 0A00 0000 ; Display "OFF"
01B 0E 0000 001D ; Jump to end

01C E4 00FF FFFF ; LED ON (white)
01D 55 0A00 0001 ; Display "ON"

; End loop
01E 11 0021 0000 ; R21 = R00 (store button state)
01F 02 0096 0000 ; Delay 150ms (debounce)
020 0E 0000 0010 ; Loop back

๐Ÿ” Detailed Explanationโ€‹

Initialization (Lines 000-005)โ€‹

Line 000: C7 0001 0000

  • Enable WS2812B full-color LED control module
  • Required before using opcode 0xE4

Line 001: 10 0025 00F0

  • Configure IO pin directions
  • R25 = IO configuration register
  • 00F0 = Binary 11110000 = Lower 4 pins as input, upper 4 as output

Line 002: 10 0020 0000

  • Initialize light state variable R20 to 0 (OFF)
  • R20 will toggle between 0 (OFF) and 1 (ON)

Line 003: 10 0021 0001

  • Initialize previous button state R21 to 1 (released)
  • Used for edge detection

Line 004: 10 0028 FFFF

  • Set foreground color to white (0xFFFF in RGB565)
  • Used for text display

Line 005: 0E 0000 0010

  • Jump to main loop at line 010

Button Detection and Toggle (Lines 010-017)โ€‹

Line 010: 14 0000 0000

  • Read digital input values to R00
  • Each bit represents one DI pin status

Line 011: 17 0000 0001

  • R00 = R00 AND 0x01
  • Mask to check only DI0 (bit 0)
  • Result: R00 = 0 (pressed) or 1 (released)

Line 012: 06 0001 0020

  • If R00 == 1 (button released), jump to 020
  • Skip toggle logic when button not pressed

Line 013: 06 0001 0020

  • If previous state also released, skip
  • This creates edge detection (only toggle on press, not hold)

Line 014: 12 0020 0001

  • Toggle light state: R20 = R20 + 1
  • Alternates between 0 and 1

Line 015: 04 0001 0017

  • If R20 > 1, jump to reset line 017
  • Ensures R20 stays in range 0-1

Line 016: 0E 0000 0018

  • Jump to LED update section

Line 017: 10 0020 0000

  • Reset R20 to 0 (wraps around from 2 to 0)

LED Control (Lines 018-01D)โ€‹

Line 018: 04 0000 001A

  • If R20 > 0 (light is ON), jump to 01A

Line 019: E4 0000 0000

  • Turn LED OFF
  • RGB = (0, 0, 0) = Black

Line 01A: 55 0A00 0000

  • Display "OFF" text at position (10, 0)
  • Value 0000 represents OFF state

Line 01B: 0E 0000 001E

  • Jump to end of loop

Line 01C: E4 00FF FFFF

  • Turn LED ON
  • RGB = (255, 255, 255) = White

Line 01D: 55 0A00 0001

  • Display "ON" text at position (10, 0)

Loop Management (Lines 01E-020)โ€‹

Line 01E: 11 0021 0000

  • Store current button state to R21
  • R21 = R00 (save for next iteration)

Line 01F: 02 0096 0000

  • Delay 150 milliseconds
  • 0096 = 150 in decimal
  • Provides debouncing to prevent false triggers

Line 020: 0E 0000 0010

  • Jump back to line 010
  • Creates infinite loop for continuous monitoring

๐ŸŽจ State Transition Tableโ€‹

Current StateButton PressNew StateLED Action
OFF (0)PressedON (1)Turn ON (White)
ON (1)PressedOFF (0)Turn OFF (Black)
OFF (0)Not PressedOFF (0)No change
ON (1)Not PressedON (1)No change

๐Ÿ” Key Learning Pointsโ€‹

  1. Digital Input Reading: How to read button states from IO pins
  2. Edge Detection: Detecting button press vs. button hold
  3. Toggle Logic: Implementing on/off state machine
  4. Debouncing: Preventing false triggers with delays
  5. Conditional Control: Using comparisons for decision making
  6. RGB Color: Setting LED colors for different states

๐Ÿงช Testing Checklistโ€‹

  • Button is properly configured as digital input
  • LED turns on (white) when button is pressed
  • LED turns off when button is pressed again
  • Display shows correct "ON" or "OFF" status
  • Button debouncing works (no false triggers)
  • System responds reliably to repeated presses

๐Ÿ’ก Extension Challengesโ€‹

  1. Add Dimming: Use button hold to adjust LED brightness
  2. Multiple Colors: Cycle through different colors instead of just on/off
  3. Dual Button System: Add separate on and off buttons
  4. Auto-Off Timer: Automatically turn off after 5 minutes
  5. Status Indicator: Add a second LED to show power status
  6. Remote Control: Use infrared or Bluetooth for wireless control

๐Ÿ› Common Issues and Solutionsโ€‹

Issue 1: LED Flickers Rapidlyโ€‹

Cause: No debouncing or insufficient delay Solution: Increase delay time (line 01F) to 200-300ms

Issue 2: Button Doesn't Respondโ€‹

Cause: Incorrect IO configuration Solution: Verify line 001 sets correct pins as input

Issue 3: LED Toggles Multiple Timesโ€‹

Cause: Button bounce or delay too short Solution: Increase debounce delay or add additional filtering

Issue 4: Display Shows Wrong Textโ€‹

Cause: Incorrect state variable or comparison Solution: Check R20 value and comparison logic

Instructions Used in This Projectโ€‹

OpcodeNameDescriptionDocumentation Link
0x02DelaySet delay time in millisecondsDelay
0x04Greater Than JumpJump if R00 > immediate valueConditional Jumps
0x06Equal JumpJump if R00 == immediate valueConditional Jumps
0x0EUnconditional JumpJump to specified lineUnconditional Jump
0x10Write RegisterWrite immediate value to registerRegister Operations
0x11Copy RegisterCopy value from one register to anotherRegister Operations
0x12Add RegisterAdd immediate value to registerRegister Operations
0x14Read DIRead digital input pins to R00Digital I/O
0x17AND RegisterBitwise AND operationBitwise Operations
0x55Display TextDisplay register value on screenText Output
0xCBEnable WS2812BEnable LED control moduleExternal Devices
0xE4Set LED ColorSet RGB color for specific LEDLights & Music

Additional Referenceโ€‹