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

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

## 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 
                                
                            
                            

 
	   
	 
	   
	 
	   
	 
	   
	 
	   
	 
	   
	 
	   
	