Skip to content

9. Input devices

Group Assignment

This week’s task was to probe an input device’s analog and digital signals using an oscilloscope. Under the guidance of Onik Babajanyan, we measured signals from input devices connected to our PCB.

oscilloscope

We applied voltage to the analog pin of a potentiometer. As we rotated it, the waveform rose and fell smoothly in proportion to the movement — a continuous, gradual change.

Next we connected the oscilloscope to the digital pin of a photoresistor. Switching the light on and off produced sharp, immediate transitions — the signal jumping between high and low with no in-between.

We repeated the light test on the analog pin instead, and this time the transitions were smooth, similar to the potentiometer behavior.

Analog signals change continuously, reflecting gradual shifts in input, while digital signals switch abruptly between two discrete states. Seeing both behaviors on the oscilloscope made the difference concrete rather than just theoretical.


Individual Assignment

In this assignment, I explored the difference between analog and digital signals using a potentiometer connected to my custom PCB based on the Seeed XIAO RP2040.

An analog signal is continuous and can take any value within a range, while a digital signal only has two states — HIGH (ON) or LOW (OFF). The LED in this project works using digital control, while the potentiometer gave me a simple way to generate and observe an analog signal directly.

With the potentiometer turned to its minimum position, the reading was close to 0; at the middle position, it sat around 500; and at the maximum position, it reached close to 1023.

Potentiometer Potentiometer

The Seeed XIAO RP2040 supports both analog and digital input/output, with four analog-capable pins: A0 (GPIO 26), A1 (GPIO 27), A2 (GPIO 28), and A3 (GPIO 29). For this experiment, I used A0.

Potentiometer Wiring

The wiring diagram below was created using the same SVG diagram tool used in Week 2 for the Smart Workshop block diagram.

Potentiometer wiring diagram

PCB Connection

Internally, the potentiometer’s voltage is converted into a digital value by the microcontroller’s ADC (Analog to Digital Converter): 0V reads as 0, around 1.65V reads as roughly 512, and the full 3.3V reads as 1023.

AI prompt used: “Write Arduino code for XIAO RP2040 that reads a potentiometer on pin A0 and prints the raw value to the Serial Monitor.”

int value = analogRead(26);  // read analog value from A0 (GPIO26)
Serial.println(value);        // print to Serial Monitor

Sensor Integration

After getting comfortable with the potentiometer, I moved on to testing an actual sensor: an infrared obstacle detection sensor, which detects the presence of an object in front of it.

Sensor Sensor

The sensor was connected to my custom PCB using three pins — VCC → 3.3V, GND → GND, and OUT → GPIO pin — which let the microcontroller read a digital signal from it. The board used here is the one designed in Week 6 and milled in Week 8.

IR sensor wiring diagram

Sensor to PCB

Based on this sensor input, I wrote code to define a clear system behavior, with two main states: a normal state, where the green LED stays on, and a detection state, where the yellow and red LEDs activate and blink.

AI prompt used: “Write Arduino code for XIAO RP2040 that reads a digital IR obstacle sensor on D0. Keep the green LED on D3 on by default. When the sensor detects an object, turn off green and blink yellow (D2) and red (D1) alternately every 200ms.”

Code

In normal conditions, the system stays in this safe state with the green LED on. As soon as the sensor detects an object, it switches state: the green LED turns off, and the yellow and red LEDs turn on and start blinking to indicate an alert.

The video below shows this behavior in real time:

Additional Sensor Testing

To get more practice with different types of input devices, I also tested an HC-SR505 PIR Motion Sensor and an MQ-7 Gas Sensor.

The MQ-7 is especially relevant for me, since it’s the sensor I plan to use in my Final Project. My project is meant to improve safety in a blacksmith workshop, so understanding the gas sensor’s behavior now — before integrating it into the final system — was a good opportunity to verify how it actually works.

HC-SR505 PIR Motion Sensor

The HC-SR505 is a compact passive infrared (PIR) motion sensor that detects movement by measuring changes in infrared radiation emitted by people or animals.

Working principle: All objects with a temperature above absolute zero emit infrared radiation. The HC-SR505 has a pyroelectric sensor that detects changes in IR radiation level — when a person or animal moves through its field of view, the sensor picks up the change and outputs a HIGH signal for approximately 8 seconds before returning LOW.

Datasheet: HC-SR505 Datasheet PDF

HC-SR505 datasheet

Purchase: HC-SR505 on Amazon | HC-SR505 on AliExpress

Parameter Value
Operating voltage 4.5V – 20V
Quiescent current < 60 µA
Output signal HIGH 3.3V / LOW 0V
Detection distance up to 3 meters
Detection angle < 100°
Delay time ~8 seconds
Dimensions 10 × 23 mm

I connected it the same way as the obstacle sensor — VCC → 3.3V, GND → GND, OUT → GPIO pin.

PIR sensor wiring diagram

AI prompt used: “Write Arduino code for XIAO RP2040 that reads an HC-SR505 PIR motion sensor on pin D8 and prints 1 or 0 to the Serial Monitor depending on whether motion is detected.”

#define PIR_PIN D8  // PIR sensor output connected to D8

void setup() {
  pinMode(PIR_PIN, INPUT);   // set D8 as digital input
  Serial.begin(115200);       // start serial communication
}

void loop() {
  Serial.println(digitalRead(PIR_PIN));  // 1 = motion detected, 0 = no motion
  delay(100);
}

The sensor successfully detected motion, and the results showed up correctly in the Serial Monitor — 1 when motion detected, 0 when clear. One thing I noticed during testing is that it didn’t reliably pick up small hand movements close to the sensor, but it responded much better when a person actually walked through its field of view.

Serial Monitor — PIR sensor output (1=motion, 0=no motion)

MQ-7 Gas Sensor

The MQ-7 is a gas sensor designed to detect carbon monoxide (CO), with both analog and digital outputs. Since this is the sensor going into my Final Project, I wanted to see how its output actually changes as gas concentration changes.

Working principle: The MQ-7 uses a tin dioxide (SnO₂) sensing element. In clean air, SnO₂ has high resistance. When CO molecules contact the surface, the resistance drops — the analog output voltage rises as CO concentration increases. The sensor requires a warm-up period after power-on before readings are reliable.

Datasheet: MQ-7 Datasheet — SparkFun

Purchase: MQ-7 on SparkFun | MQ-7 on Amazon

Parameter Value
Operating voltage 5V
Detection gas Carbon monoxide (CO)
Detection range 20 – 2000 ppm
Output Analog (AOUT) + Digital (DOUT)
Preheat time ≥ 24 hours (first use)

MQ-7 wiring diagram

In the first test, I just read the raw analog value:

AI prompt used: “Write Arduino code for XIAO RP2040 that reads an MQ-7 gas sensor on pin A0 and prints the raw ADC value to the Serial Monitor every 500ms.”

#define MQ7_PIN A0  // MQ-7 analog output connected to A0

void setup() {
  Serial.begin(115200);  // start serial at high baud rate
}

void loop() {
  int gas = analogRead(MQ7_PIN);  // read 12-bit ADC value (0-4095)

  Serial.print("Raw Value: ");
  Serial.println(gas);  // higher value = more CO

  delay(500);
}

The Serial Monitor shows the raw ADC values rising as gas concentration increases — starting around 228 in clean air, then climbing to 625 and beyond when gas is introduced:

Serial Monitor — MQ-7 raw values rising

Serial Monitor — MQ-7 values reaching maximum

The values on the Serial Monitor increased as gas concentration increased, confirming the sensor was responding correctly to changes in the environment.

In the second test, I converted that raw value into an actual voltage reading, to get a more meaningful number than just the raw ADC output:

AI prompt used: “Extend the previous MQ-7 code to also calculate and print the voltage in volts, based on the 12-bit ADC range (0-4095) and 3.3V reference.”

#define MQ7_PIN A0  // MQ-7 analog output

void setup() {
  Serial.begin(115200);
}

void loop() {
  int raw = analogRead(MQ7_PIN);              // raw ADC value 0-4095

  float voltage = (raw * 3.3) / 4095.0;      // convert to voltage 0-3.3V

  Serial.print("Raw: ");
  Serial.print(raw);                           // print raw value

  Serial.print(" | Voltage: ");
  Serial.print(voltage, 2);                    // print voltage with 2 decimal places
  Serial.println(" V");

  delay(500);
}

Serial Monitor — MQ-7 raw value and voltage output

The calculated voltage rose together with the gas concentration. Low values (~70 raw, ~0.06V) indicate clean air; high values (1023 raw, ~0.82V) indicate elevated gas concentration.

I also ran a third version of the MQ-7 code that prints a human-readable status alongside the raw value — “Clean Air”, “Medium Gas Level”, or “High Gas Level” — based on thresholds:

Serial Monitor — MQ-7 with status labels

Conclusion

This week’s assignment helped me understand the difference between analog and digital input devices, and how sensor data can be read and interpreted with a microcontroller — from a simple potentiometer all the way to real sensors like the infrared obstacle sensor, the PIR motion sensor, and the MQ-7 gas sensor.

Each sensor produced a different type of signal, and seeing them all read and processed by the Seeed XIAO RP2040 made the input → processing → output chain (sensor data → code logic → LED behavior) feel concrete rather than abstract.

The MQ-7 experiments were especially valuable, since this sensor will be part of my Final Project — testing it now let me verify its behavior and build some confidence with it before relying on it in the final system.


Board Redesign

For this week, I redesigned the board I had originally built in Week 6 and milled in Week 8. A few practical issues with the first version pushed me to redo the design.

Power input. The original board could only be powered through the USB-C port on the XIAO RP2040 itself. I wanted the option to power it from a 12V source instead, so I added a Conn_PWRJack_2x5.5mm barrel jack connector to the board.

Board Redesign

Since the rest of the board runs on 5V, I also added a voltage regulator — an NCP1117-1.5_SOT223, rated for around 1A or more — to step the 12V input down to a stable 5V.

Board Redesign

LEDs. On the original board, the red/yellow/green status LEDs were SMD components soldered directly onto the PCB. Since the final project is meant to sit inside an enclosure, and SMD LEDs aren’t very bright on their own, I decided to replace them with a ready-made module instead: the 5V LED Traffic Light Module for Arduino (OT2068-D41).

Board Redesign

I dedicated a 4-pin header to it — 1 GND pin and 3 logic pins (one per color), so the module can be driven the same way the SMD LEDs were before.

Board Redesign

Gas sensor. I’m now planning to use an MQ-7 for the gas readings, so I left a 3-pin header for it: +5V, GND, and one analog output pin.

Board Redesign

Buzzer. The buzzer I’m using is rated for around 1V, while the microcontroller’s logic pins output 3.3V. To bring the signal down closer to what the buzzer expects, I placed a resistor between the logic pin and the buzzer’s pin header, rather than connecting it directly.

Board Redesign

Spare sensor headers. As before, I kept a few extra pin headers broken out for sensors I haven’t decided on yet, so the board stays flexible for whatever I might need to add later.

Board Redesign

I2C headers. I added two 4-pin headers for I2C communication (+5V, GND, SDA, SCL), so I can either exchange data with another device over I2C or use the same header to supply it with power.

Board Redesign

GND zone bridges. Just like on the previous board, routing the GND zone on the PCB ended up splitting it into separate areas in a few places. I added three 0 Ω resistors to bridge those gaps and keep the ground plane fully connected.

Board Redesign

Schematic

Board Redesign

PCB Layout

Board Redesign

Milling and Soldering

I milled the new board and soldered on the components — the power jack, the voltage regulator, and all the pin headers.

Board Redesign

Files

kicad design files Project 1 - ZIP

kicad design files Project 2 - ZIP

Milling files SVG Project 1- ZIP

Milling files SVG Poject 2- ZIP