Week 9: Input Devices

Overview

This week, I focused on testing and documenting input devices using the Seeed Studio XIAO RP2040 microcontroller mounted on a custom board that I designed and milled in a previous assignment. The board includes breakout headers for all I/O pins, a pushbutton, and three indicator LEDs: blue, orange, and red.

Considering the requirements of this assignment, I aimed to:

board2 inputs

For this assignment, I tested:

Checklist

Group Assignment: Input Devices

For more details, visit the group assignment page: Group Assignment - Week 9

Findings

Nothing to see here

Xiao RP2040

The XIAO RP2040 is a compact microcontroller board based on the RP2040 chip. It features USB-C, 11 GPIOs, and supports multiple communication protocols, making it ideal for small embedded projects.

Technical reference and datasheet: Seeed Studio - Xiao RP2040

pinoutRP2040

Custom Board with Xiao RP2040

I designed and milled a custom board in a previous assignment to serve as a base for testing sensors and output devices. The board includes labeled headers, a button, and three onboard LEDs for feedback.

board1

Sensor 1: Photoresistor (KY-018)

This analog sensor detects light intensity. It outputs a voltage that varies with light exposure, which we read using an analog input pin. Data was visualized using the Serial Plotter.

Technical reference: KY-018 Photoresistor Module

pinoutPhoto
photoresistor
[Video showing sensor behavior in light/dark]

    const int ldrPin = A2;  // Analog pin where the LDR is connected
    int lightValue;         // Variable to store the LDR reading

    void setup() {
    Serial.begin(9600);             // Start serial communication
    pinMode(ldrPin, INPUT);         // Set LDR pin as input
    }

    void loop() {
    // Read analog value from the LDR (range: 0 to 1023)
    lightValue = analogRead(ldrPin);

    // Print only the value, so it's compatible with the Serial Plotter
    Serial.println(lightValue);

    delay(50);  // Short delay to make the plot smoother
    }
            

The photoresistor outputs an analog voltage that varies with the amount of light it receives. In the code, the analog value is read from pin A2 using analogRead(). The result is printed to the Serial Monitor, and visualized in the Arduino Serial Plotter. Brighter light results in lower values, and darkness increases the reading.

Sensor 2: Mercury Tilt Sensor (KY-027)

This sensor uses a small mercury capsule to detect tilt or vibration. Different LED patterns were triggered based on the number of spikes detected over time.

Note: This sensor contains mercury, which is considered toxic. For safety, modern alternatives like accelerometers or solid-state tilt switches are recommended.

Technical reference: KY-027 Magic Light Cup Module

pinoutmercury
mercury
[Video showing LED response to vibration]

    const int sensorLED = D3;     // Onboard LED of the KY-027 module
    const int sensorPin = D2;     // Digital output from the KY-027 sensor
    int sensorValue;
    int previousValue = LOW;
    int triggerCount = 0;
    
    void setup() {
        Serial.begin(9600);                
        pinMode(sensorLED, OUTPUT);       
        pinMode(sensorPin, INPUT);        
    }
    
    void loop() {
        sensorValue = digitalRead(sensorPin);  
    
        // Detect tilt or vibration (LOW → HIGH)
        if (sensorValue == HIGH && previousValue == LOW) {
        triggerCount++;
        }
    
        previousValue = sensorValue;
    
        // Control the onboard LED
        digitalWrite(sensorLED, sensorValue);
    
        // Print values in a format suitable for the Serial Plotter
        // Format: sensorValuetriggerCount
        Serial.print(sensorValue);
        Serial.print("\t");
        Serial.println(triggerCount);
    
        delay(100);
    }
                
            

This code monitors tilt or vibration activity using the KY-027 sensor connected to a digital input. Each time a HIGH signal is detected, a timestamp is recorded. Over a moving time window (1.5 seconds), the code counts how many spikes occurred. Based on the count, it activates one or more LEDs with different flashing patterns to indicate low, moderate, or continuous vibration. This approach simulates basic signal processing with visual feedback.

Sensor 3: Impact Sensor (KY-031)

This digital sensor detects physical impacts or knocks. The LED responds with a flash on impact and data is plotted in the Serial Plotter.

Technical reference: KY-031 Knock Sensor Module

pinoutimpact
[Image of KY-031 connected to board]
[Video showing impact detection]

    const int sensorPin = D0;   // KY-031
    const int ledBlue   = D7;
    const int ledOrange = D6;
    const int ledRed    = D1;

    const int maxSpikes = 10;
    unsigned long spikeTimes[maxSpikes];
    int spikeIndex = 0;

    unsigned long lastRedToggle = 0;
    bool redState = false;

    void setup() {
    Serial.begin(9600);
    pinMode(sensorPin, INPUT);
    pinMode(ledBlue, OUTPUT);
    pinMode(ledOrange, OUTPUT);
    pinMode(ledRed, OUTPUT);

    digitalWrite(ledBlue, LOW);
    digitalWrite(ledOrange, LOW);
    digitalWrite(ledRed, LOW);
    }

    void loop() {
    int hit = digitalRead(sensorPin);
    unsigned long now = millis();

    // Record spikes
    if (hit == HIGH) {
        spikeTimes[spikeIndex] = now;
        spikeIndex = (spikeIndex + 1) % maxSpikes;
        delay(50);  // debounce
    }

    // Count recent spikes
    int spikeCount = 0;
    for (int i = 0; i < maxSpikes; i++) {
        if (now - spikeTimes[i] < 1500) {
        spikeCount++;
        }
    }

    // RED FLASH MODE
    if (spikeCount >= 4) {
        digitalWrite(ledBlue, HIGH);
        digitalWrite(ledOrange, HIGH);

        // Flash red LED fast (toggle every 100 ms)
        if (now - lastRedToggle > 100) {
        redState = !redState;
        digitalWrite(ledRed, redState ? HIGH : LOW);
        lastRedToggle = now;
        }

    } else {
        // Reset red LED state
        digitalWrite(ledRed, LOW);
        redState = false;

        if (spikeCount >= 2) {
        // Moderate: blue solid, orange flashing
        digitalWrite(ledBlue, HIGH);
        if ((now / 100) % 2 == 0) {
            digitalWrite(ledOrange, HIGH);
        } else {
            digitalWrite(ledOrange, LOW);
        }
        } else if (spikeCount == 1) {
        // Single spike: blue flash
        digitalWrite(ledBlue, HIGH);
        delay(100);
        digitalWrite(ledBlue, LOW);
        delay(100);
        digitalWrite(ledOrange, LOW);
        } else {
        // No activity: all off
        digitalWrite(ledBlue, LOW);
        digitalWrite(ledOrange, LOW);
        }
    }

    delay(50);
    }

            

The KY-031 detects physical impacts as short digital pulses. The code reads the sensor on pin D2 and sends the result to the Serial Plotter. A spike (HIGH) briefly activates the onboard or external LED. If multiple spikes occur over a short period, the LED behavior escalates accordingly. This provides both visual and plotted feedback of how often and how intensely impacts are detected.

Sensor 4: Pushbutton

A simple pushbutton was used to test digital input and LED interaction. When pressed, different LED patterns are triggered to reflect button state.

[Image of button and LED on board]
[Video showing button press test]
// Arduino code here...

Download Project Files

All project files, including board design and Arduino code, are available below: