11 - Lab Multiply Click Detection

Video

# Lab: Multiply-Click Detection - Advanced Button Patterns ## Objective Learn to detect different button click patterns (single, double, and triple clicks) using the TinkerBlock TK04 Push Button module. The button's built-in LED will light when pressed, and we'll use Serial communication to monitor and analyze click patterns within a time window. ## Learning Outcomes - Understand timing-based button pattern detection - Learn about click counting and time windows - Master advanced button state management - Create responsive multi-click detection systems - Use timing functions for pattern recognition - Use Serial communication for pattern analysis and debugging ## Required Components ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250722123351.png?v=1753819645) 1. **Lonely Binary UNO R3** - Main Arduino board 2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3 3. **TinkerBlock TK04 - Push Button** - Push button module with 4-pin connector ## Theory ### Click Pattern Detection - **Single Click**: One button press and release - **Double Click**: Two button presses within a time window (e.g., 500ms) - **Triple Click**: Three button presses within a time window - **Time Window**: Maximum time allowed between clicks to be considered a pattern ### Timing Concepts - **millis()**: Returns milliseconds since Arduino started (non-blocking) - **Time Windows**: Critical for distinguishing between intentional patterns and accidental clicks - **Click Counting**: Tracking number of clicks within the time window - **State Management**: Managing different phases of click detection ### Pattern Recognition Logic 1. **Detection Phase**: Monitor for button presses 2. **Timing Phase**: Wait for additional clicks within time window 3. **Action Phase**: Execute appropriate response based on click count 4. **Reset Phase**: Prepare for next pattern detection ### Key Functions Used - `pinMode(pin, mode)`: Configures a pin as input or output - `digitalRead(pin)`: Reads the state of a digital pin (HIGH or LOW) - `millis()`: Returns milliseconds since Arduino started (non-blocking) - `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 ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250722123629.png?v=1753819650) ## 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 Push Button Module:** - Take the TinkerBlock TK04 - Push Button 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 - **Signal** pin to digital pin D5 3. **Important Notes:** - No breadboard or jumper wires required - 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: Double-Click Detection // Push button connected to digital pin D5 // Define the button pin const int buttonPin = 5; // Button input pin // Timing constants const unsigned long CLICK_WINDOW = 500; // Time window for multi-click detection (ms) const unsigned long DEBOUNCE_TIME = 50; // Debounce delay (ms) // Variables for click detection int lastButtonState = LOW; // Previous button state unsigned long lastClickTime = 0; // Time of last button press int clickCount = 0; // Number of clicks in current window bool waitingForMoreClicks = false; // Whether we're waiting for more clicks void setup() { // Configure button pin as input pinMode(buttonPin, INPUT); // Initialize serial communication for debugging Serial.begin(9600); Serial.println("Double-Click Detection Lab Started"); Serial.println("Click patterns:"); Serial.println(" Single click: Pattern detected"); Serial.println(" Double click: Pattern detected"); Serial.println(" Triple click: Pattern detected"); Serial.println(" Press the button to see click patterns!"); } void loop() { // Read the current button state int buttonState = digitalRead(buttonPin); // Detect button press (transition from LOW to HIGH) if (buttonState == HIGH && lastButtonState == LOW) { unsigned long currentTime = millis(); // Check if this is the first click or within the time window if (currentTime - lastClickTime > CLICK_WINDOW) { // New click sequence started clickCount = 1; waitingForMoreClicks = true; Serial.println("First click detected"); } else { // Additional click within time window clickCount++; Serial.print("Click "); Serial.print(clickCount); Serial.println(" detected"); } lastClickTime = currentTime; delay(DEBOUNCE_TIME); // Debounce delay } // Check if time window has expired and we have clicks to process if (waitingForMoreClicks && (millis() - lastClickTime > CLICK_WINDOW)) { // Time window expired, process the click pattern processClickPattern(clickCount); // Reset for next pattern clickCount = 0; waitingForMoreClicks = false; } // Update last button state lastButtonState = buttonState; // Small delay to prevent too rapid reading delay(10); } void processClickPattern(int clicks) { Serial.print("Processing "); Serial.print(clicks); Serial.print(" click(s): "); switch(clicks) { case 1: // Single click Serial.println("SINGLE CLICK detected!"); break; case 2: // Double click Serial.println("DOUBLE CLICK detected!"); break; case 3: // Triple click Serial.println("TRIPLE CLICK detected!"); break; default: // More than 3 clicks - special pattern Serial.print("SPECIAL PATTERN detected: "); Serial.print(clicks); Serial.println(" clicks!"); break; } } ``` ## Code Explanation ### Setup Function ```cpp void setup() { pinMode(buttonPin, INPUT); Serial.begin(9600); } ``` - Configures pin D5 as input for button reading - Initializes serial communication for debugging ### Main Loop Logic ```cpp void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && lastButtonState == LOW) { // Button press detected // Check timing and update click count } if (waitingForMoreClicks && (millis() - lastClickTime > CLICK_WINDOW)) { // Time window expired, process pattern processClickPattern(clickCount); } } ``` **Click Detection:** - Detects button press transitions (edge detection) - Tracks timing between clicks using `millis()` - Counts clicks within the time window - Waits for time window to expire before processing **Timing Management:** - `CLICK_WINDOW = 500`: 500ms window for multi-click detection - `lastClickTime`: Records when each click occurred - `millis() - lastClickTime > CLICK_WINDOW`: Checks if time window expired ### Pattern Processing Function ```cpp void processClickPattern(int clicks) { switch(clicks) { case 1: Serial.println("SINGLE CLICK detected!"); break; case 2: Serial.println("DOUBLE CLICK detected!"); break; case 3: Serial.println("TRIPLE CLICK detected!"); break; default: Serial.println("SPECIAL PATTERN detected!"); break; } } ``` **Pattern Responses:** - **1 Click**: "SINGLE CLICK detected!" - **2 Clicks**: "DOUBLE CLICK detected!" - **3 Clicks**: "TRIPLE CLICK detected!" - **4+ Clicks**: "SPECIAL PATTERN detected: X clicks!" ### Key Variables - **clickCount**: Number of clicks in current window - **lastClickTime**: Timestamp of last button press - **waitingForMoreClicks**: Flag indicating active detection - **CLICK_WINDOW**: Time window for pattern detection ## Testing and Verification 1. **Upload the code to Lonely Binary UNO R3** 2. **Open Serial Monitor** in Arduino IDE (Tools → Serial Monitor) 3. **Test different click patterns:** - **Single click**: Serial shows "1 click(s): SINGLE CLICK detected!" - **Double click** (within 500ms): Serial shows "2 click(s): DOUBLE CLICK detected!" - **Triple click** (within 500ms): Serial shows "3 click(s): TRIPLE CLICK detected!" - **4+ clicks**: Serial shows "X click(s): SPECIAL PATTERN detected: X clicks!" 4. **Verify timing:** - Clicks must be within 500ms to be counted as a pattern - Wait more than 500ms between patterns 5. **Verify connections:** - Ensure the TK04 module is firmly connected to the shield - Check that the shield is properly seated on the Arduino - Confirm the button's built-in LED is visible and working ## Troubleshooting ### Button doesn't detect clicks properly: - Check if the TinkerBlock shield is properly seated on the Arduino - Ensure the TK04 module is firmly connected to the shield - Verify the module is connected to a slot that uses D5 pin - Check if code uploaded successfully to the Lonely Binary UNO R3 - Open Serial Monitor to see if button presses are being detected ### Click patterns not recognized: - Check Serial Monitor output to see click detection messages - Verify timing between clicks is less than 500ms - Try adjusting the `CLICK_WINDOW` value if needed - Ensure button debouncing is working properly ### Button's built-in LED doesn't light: - Check if the TK04 module is properly powered (VCC and GND connections) - Verify the module is firmly seated in the shield - Try reconnecting the module to a different 4-pin slot ### Multiple clicks detected for single press: - This indicates button bounce - increase `DEBOUNCE_TIME` to 100ms - Check if the button module is properly seated - Try cleaning the module connector pins if necessary ### 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. Adjustable Click Window Make the click window configurable: ```cpp const unsigned long CLICK_WINDOW = 300; // Faster response // or const unsigned long CLICK_WINDOW = 1000; // Slower response ``` ### 2. Different Pattern Responses Create more complex pattern responses: ```cpp void processClickPattern(int clicks) { switch(clicks) { case 1: Serial.println("SINGLE CLICK - Quick response"); break; case 2: Serial.println("DOUBLE CLICK - Medium response"); break; case 3: Serial.println("TRIPLE CLICK - Complex response"); Serial.println(" Analyzing pattern..."); delay(500); Serial.println(" Pattern confirmed!"); break; case 4: Serial.println("QUADRUPLE CLICK - Special sequence"); Serial.println(" Sequence 1: Complete"); delay(300); Serial.println(" Sequence 2: Complete"); delay(300); Serial.println(" All sequences: DONE"); break; } } ``` ### 3. Click Counter with Reset Add a reset function for long press: ```cpp unsigned long pressStartTime = 0; bool buttonWasPressed = false; void loop() { int buttonState = digitalRead(buttonPin); if (buttonState == HIGH && lastButtonState == LOW) { pressStartTime = millis(); buttonWasPressed = true; // ... existing click detection code } else if (buttonState == LOW && buttonWasPressed) { unsigned long holdTime = millis() - pressStartTime; if (holdTime > 2000) { // Long press - reset click counter clickCount = 0; waitingForMoreClicks = false; Serial.println("Long press - Click counter reset"); } buttonWasPressed = false; } // ... rest of existing code } ``` ## Questions for Understanding 1. What is the purpose of the `CLICK_WINDOW` constant? 2. How does the code distinguish between single and double clicks? 3. Why do we use `millis()` instead of `delay()` for timing? 4. What happens if you click the button 4 times within the time window? 5. How could you modify the code to detect a quadruple click? 6. What is the difference between `waitingForMoreClicks` and `clickCount`? 7. How would you change the timing to make the system more or less sensitive? ## Next Steps - Try connecting multiple TK04 push buttons to different 4-pin slots - Experiment with different click patterns and timing windows - Learn about interrupt-based button handling for more responsive detection - Explore other TinkerBlock input modules (sensors, switches) - Try creating more complex gesture recognition systems - Implement click patterns for different button combinations ## 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 - [ ] TK04 Push Button module connected to shield (D5) - [ ] Code uploaded successfully to Lonely Binary UNO R3 - [ ] Single click detected correctly - [ ] Double click detected correctly - [ ] Triple click detected correctly - [ ] Serial Monitor shows correct click detection patterns - [ ] Button's built-in LED lights when pressed - [ ] Troubleshooting completed (if needed) - [ ] Experiment variations tried - [ ] Questions answered

RELATED ARTICLES