12 - Lab LED Toggle Control

Video

# Lab: LED Toggle Control - Button Input with LED Output ## Objective Learn to combine digital input and output by using the TinkerBlock TK04 Push Button to control the TinkerBlock TK01 LED. Pressing the button once will turn the LED on, pressing it again will turn the LED off, creating a toggle functionality. ## Learning Outcomes - Understand how to combine digital input and output - Learn about button state detection and edge triggering - Master button debouncing techniques - Create interactive toggle circuits - Use Serial communication for debugging ## Required Components 1. **Lonely Binary UNO R3** - Main Arduino board 2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3 3. **TinkerBlock TK01 - XL LED** - LED module with 4-pin connector 4. **TinkerBlock TK04 - Push Button** - Push button module with 4-pin connector ## Theory ### Input/Output Integration - **Digital Input**: Reading button states to detect user interaction - **Digital Output**: Controlling LED based on button input - **Integration**: Combining both to create interactive circuits ### Button State Detection - **Level Detection**: Reading current button state (HIGH/LOW) - **Edge Detection**: Detecting transitions between states - **Toggle Logic**: Using edge detection to change LED state ### Button Debouncing - **Mechanical Bounce**: Rapid on/off signals when button is pressed/released - **Debouncing**: Filtering out unwanted signals to get clean button presses - **Methods**: Software delays, state tracking, or hardware filtering ### Key Functions Used - `pinMode(pin, mode)`: Configures pins as input or output - `digitalRead(pin)`: Reads the state of a digital pin (HIGH or LOW) - `digitalWrite(pin, value)`: Sets a digital pin HIGH or LOW - `Serial.begin(baud)`: Initializes serial communication - `Serial.print()` and `Serial.println()`: Outputs data to Serial Monitor - `delay(milliseconds)`: Pauses the program for a specified time ## Circuit Diagram ``` Lonely Binary UNO R3 ↓ TinkerBlock UNO R3 Shield ↓ TinkerBlock TK01 - XL LED Module (D3) TinkerBlock TK04 - Push Button Module (D5) ``` ## Connection Instructions 1. **Assemble the Hardware:** - Place the TinkerBlock UNO R3 Shield onto the Lonely Binary UNO R3 - Ensure all pins are properly aligned and seated - The shield should fit snugly on top of the Arduino board 2. **Connect the LED Module:** - Take the TinkerBlock TK01 - XL LED module - Align the 4-pin connector with any available 4-pin slot on the shield - Gently push the module into the slot until it clicks into place - The module will automatically connect: - **GND** pin to ground - **VCC** pin to 5V power - **NC** pin remains unconnected - **D3** pin to digital pin D3 3. **Connect the Push Button Module:** - Take the TinkerBlock TK04 - Push Button module - Align the 4-pin connector with another available 4-pin slot on the shield - Gently push the module into the slot until it clicks into place - The module will automatically connect: - **GND** pin to ground - **VCC** pin to 5V power - **NC** pin remains unconnected - **Signal** pin to digital pin D5 4. **Important Notes:** - No breadboard or jumper wires required - Both modules have built-in current limiting resistors - The TK04 push button has a built-in 10kΩ pull-down resistor - The button's built-in LED will light when pressed - Multiple 4-pin slots are available on the shield for expansion ## Code ```cpp // Lab 4: LED Toggle Control // LED connected to digital pin D3 // Push button connected to digital pin D5 // Define the pins const int ledPin = 3; // LED output pin const int buttonPin = 5; // Button input pin // Variables for button state tracking int ledState = LOW; // Current LED state int lastButtonState = LOW; // Previous button state int buttonPressCount = 0; // Count of button presses void setup() { // Configure LED pin as output pinMode(ledPin, OUTPUT); // Configure button pin as input pinMode(buttonPin, INPUT); // Initialize serial communication for debugging Serial.begin(9600); Serial.println("LED Toggle Control Lab Started"); Serial.println("Press the button to toggle the LED"); } void loop() { // Read the current button state int buttonState = digitalRead(buttonPin); // Detect button press (transition from LOW to HIGH) if (buttonState == HIGH && lastButtonState == LOW) { // Button was just pressed buttonPressCount++; // Toggle LED state ledState = !ledState; // Update LED digitalWrite(ledPin, ledState); // Print status to Serial Monitor Serial.print("Button pressed! Count: "); Serial.print(buttonPressCount); Serial.print(" | LED: "); if (ledState == HIGH) { Serial.println("ON"); } else { Serial.println("OFF"); } // Debounce delay delay(50); } // Update last button state lastButtonState = buttonState; // Small delay to prevent too rapid reading delay(10); } ``` ## Code Explanation ### Setup Function ```cpp void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); Serial.begin(9600); } ``` - Configures pin D3 as output for LED control - Configures pin D5 as input for button reading - Initializes serial communication for debugging ### Loop Function ```cpp void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && lastButtonState == LOW) { ledState = !ledState; digitalWrite(ledPin, ledState); } } ``` **Edge Detection:** - `buttonState == HIGH && lastButtonState == LOW`: Detects button press transition - Only triggers when button changes from not pressed to pressed - Prevents multiple triggers from a single button press **Toggle Logic:** - `ledState = !ledState`: Toggles between HIGH and LOW - `digitalWrite(ledPin, ledState)`: Updates LED to match new state - LED stays in new state until next button press **Debouncing:** - `delay(50)`: Prevents multiple triggers from button bounce - `lastButtonState = buttonState`: Tracks previous state for edge detection ### State Variables - **ledState**: Current state of the LED (HIGH/LOW) - **lastButtonState**: Previous button state for edge detection - **buttonPressCount**: Tracks total number of button presses ## Testing and Verification 1. **Upload the code to Lonely Binary UNO R3** 2. **Open Serial Monitor** in Arduino IDE (Tools → Serial Monitor) 3. **Observe the behavior:** - Initial state: LED should be off - First button press: LED should turn on, Serial shows "LED: ON" - Second button press: LED should turn off, Serial shows "LED: OFF" - Pattern should continue: on/off/on/off... - Button press count should increment with each press 4. **Verify connections:** - Ensure both modules are firmly connected to the shield - Check that the shield is properly seated on the Arduino - Confirm both LEDs are visible and not obstructed ## Troubleshooting ### Button doesn't toggle LED: - Check if the TinkerBlock shield is properly seated on the Arduino - Ensure both TK01 and TK04 modules are firmly connected to the shield - Verify the modules are connected to slots that use D3 and D5 pins - Check if code uploaded successfully to the Lonely Binary UNO R3 - Open Serial Monitor to see if button presses are being detected ### LED doesn't change state: - Check if the TK01 LED module is properly connected - Verify the LED module is connected to a slot that uses D3 pin - Check Serial Monitor output to confirm button is being read correctly - Ensure both modules are powered (VCC and GND connections) ### Button triggers multiple times: - This indicates button bounce - the debounce delay may need adjustment - Try increasing the delay(50) to delay(100) or higher - Check if the button module is properly seated ### Serial Monitor shows no output: - Ensure Serial Monitor is set to 9600 baud rate - Check that Serial.begin(9600) is in setup() - Verify the correct COM port is selected in Arduino IDE ## Experiment Variations ### 1. Different Toggle Patterns Create different LED patterns with button presses: ```cpp int patternState = 0; void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && lastButtonState == LOW) { patternState = (patternState + 1) % 4; // Cycle through 4 states switch(patternState) { case 0: digitalWrite(ledPin, LOW); Serial.println("LED: OFF"); break; case 1: digitalWrite(ledPin, HIGH); Serial.println("LED: ON"); break; case 2: digitalWrite(ledPin, LOW); Serial.println("LED: OFF"); break; case 3: digitalWrite(ledPin, HIGH); Serial.println("LED: ON"); break; } delay(50); } lastButtonState = buttonState; delay(10); } ``` ### 2. Hold Button for Different Behavior Different behavior for short press vs. long press: ```cpp unsigned long pressStartTime = 0; bool buttonWasPressed = false; void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && !buttonWasPressed) { // Button just pressed pressStartTime = millis(); buttonWasPressed = true; } else if (buttonState == LOW && buttonWasPressed) { // Button released unsigned long holdTime = millis() - pressStartTime; if (holdTime < 1000) { // Short press - toggle LED ledState = !ledState; digitalWrite(ledPin, ledState); Serial.println("Short press - LED toggled"); } else { // Long press - turn LED off ledState = LOW; digitalWrite(ledPin, ledState); Serial.println("Long press - LED turned off"); } buttonWasPressed = false; } delay(10); } ``` ### 3. Multiple LED States Create more complex LED control patterns: ```cpp int ledMode = 0; void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && lastButtonState == LOW) { ledMode = (ledMode + 1) % 3; switch(ledMode) { case 0: digitalWrite(ledPin, LOW); Serial.println("Mode 0: LED OFF"); break; case 1: digitalWrite(ledPin, HIGH); Serial.println("Mode 1: LED ON"); break; case 2: // Blinking mode for(int i = 0; i < 5; i++) { digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); delay(200); } Serial.println("Mode 2: LED blinked 5 times"); break; } delay(50); } lastButtonState = buttonState; delay(10); } ``` ## Questions for Understanding 1. What is the difference between level detection and edge detection? 2. Why do we need to track the previous button state? 3. What is button bounce and how does debouncing help? 4. How does the toggle logic work with `ledState = !ledState`? 5. Why do we use `delay(50)` after detecting a button press? 6. What would happen if we removed the edge detection logic? 7. How could you modify the code to require a double-click to toggle the LED? ## Next Steps - Try connecting multiple TK01 LED modules to different 4-pin slots - Experiment with different button control patterns and timing - Learn about interrupt-based button handling for more responsive control - Explore other TinkerBlock input modules (sensors, switches) - Try creating more complex state machines with multiple buttons and LEDs ## Safety Notes - Always disconnect power before connecting or disconnecting modules - Handle the TinkerBlock shield and modules carefully to avoid bending pins - Ensure proper alignment when connecting modules to prevent damage - The built-in resistors in the modules prevent component damage - Keep the Lonely Binary UNO R3 and shield in a stable position during operation --- **Lab Completion Checklist:** - [ ] TinkerBlock shield properly seated on Lonely Binary UNO R3 - [ ] TK01 LED module connected to shield (D3) - [ ] TK04 Push Button module connected to shield (D5) - [ ] Code uploaded successfully to Lonely Binary UNO R3 - [ ] LED toggles on/off with each button press - [ ] Serial Monitor shows correct button press count and LED states - [ ] Troubleshooting completed (if needed) - [ ] Experiment variations tried - [ ] Questions answered