10. Output Devices¶
Group assignment¶
Group assignment: Measure the power consumption of an output device.
Overview¶
This week our group assignment was about measuring how much power an output device actually draws. Rather than test something in isolation, we decided to look at a real board from our lab — Ani Petrosyan’s final project, which uses LED strips switched by 50N03 MOSFETs. It felt more useful to measure something that would actually be running, so we could also help Ani understand the limits of her design.
Ani’s board runs on 12V DC, stepped down to 5V by a voltage regulator for the microcontroller and sensors. The LED strips connect through 50N03 MOSFETs. The datasheet lists a 50A maximum continuous drain current, but that number assumes a heatsink. Ani’s board has no heatsink, so we worked from the thermal resistance specs instead and set a conservative practical limit of 5A.
Measuring the strip¶
We connected an LED strip with 5 sections (25mm each) to the bench supply (YIHUA 3010D III), set to 12V with a 1A current limit. The supply’s built-in display showed around 0.13A, but the readout only has two decimal places, so we didn’t trust it for a calculation.

We switched to a multimeter connected in series to get a more precise reading.

The multimeter read 142.1 mA for the full 5-section strip.

Calculations¶
With the measured current we could work out the actual power consumption and how much strip the MOSFET can safely drive without a heatsink.
Power consumption of the 5-section strip:
P = V × I = 12V × 0.1421A ≈ 1.7 W
Per section: 142.1 mA ÷ 5 = 28.42 mA
We applied a 30% safety derating to the 5000 mA practical limit to leave headroom for ambient temperature and PCB heating during long operation:
5000 mA × 0.7 = 3500 mA
Maximum sections: 3500 ÷ 28.42 ≈ 123 sections
Maximum strip length: 123 × 25mm = 3075mm ≈ 3.08m
Power consumption at maximum safe strip length:
P = 12V × (123 × 0.02842A) = 12V × 3.496A ≈ 42 W
So without a heatsink, the 50N03 can safely drive just over 3 meters of this LED strip — more than enough for Ani’s project.
Individual assignment¶
Individual assignment: Add an output device to a microcontroller board and program it to do something.
Servo Motor Control¶
As part of testing the output devices, I connected a 9g micro servo motor to the XIAO RP2040 to verify that the microcontroller could generate PWM signals and accurately control servo position.
The servo motor has three wires:
- Brown – Ground (GND)
- Red – +5V Power Supply
- Orange – PWM Signal
Wiring¶
| Servo Wire | XIAO RP2040 |
|---|---|
| Brown | GND |
| Red | 5V |
| Orange | D0 |
Code¶
For this I used ChatGPT as a programming assistant. The prompt I provided was:
“Write an Arduino program for the Seeed Studio XIAO RP2040 that controls a 9g micro servo motor connected to pin D0. The servo should continuously move between 0°, 90°, and 180°, with a one-second delay between each position.”
It returned the following sketch, which I uploaded and tested:
#include <Servo.h>
Servo servo;
void setup() {
servo.attach(D0);
}
void loop() {
servo.write(0);
delay(1000);
servo.write(90);
delay(1000);
servo.write(180);
delay(1000);
}
The program includes the Servo library, attaches the servo to pin D0, and continuously moves it through three positions — 0°, 90°, and 180° — with a one-second pause at each. The servo.write() function sets the angle, and delay() gives the motor time to reach each position before the next command.
After uploading the code, the servo moved smoothly and repeatedly between all three positions, confirming the PWM output was working correctly and the wiring was good.

Vahan — Final Project Output System¶
For my individual assignment I focused on the output side of Vahan, my final project — a CO/CO₂ gas monitoring safety device designed for forge environments. The name means “shield” in Armenian, which reflects what the device is meant to do: warn a metalworker before gas levels become dangerous. Vahan’s outputs are three LEDs and a buzzer, all driven by the XIAO RP2040 based on live readings from the MQ-7 gas sensor.
A note on the MQ-7: technically it is an input device, not an output. I included it here because the output logic of Vahan only makes sense when you understand what triggers it. The sensor reading is the starting point for everything — without it, the LEDs and buzzer have no context. I had already documented the MQ-7 in detail during Week 9 — Input Devices, so here I use it only as the logical entry point for the output chain.
Hardware¶
The board used for this assignment is the same Vahan board I designed in Week 9 — Electronics Design, where I documented the full KiCad schematic and PCB layout. The board has four output components wired to the XIAO RP2040:

| Output | Pin | Function |
|---|---|---|
| Green LED | D3 | Safe — gas below 200 ppm |
| Yellow LED | D2 | Warning — gas 200–600 ppm |
| Red LED | D1 | Danger — gas above 600 ppm |
| Buzzer | D6 | Alert — pulsing at warning, continuous at danger |
The MQ-7 analog output connects to pin A0. Power enters through a 12V barrel jack and is regulated down to 5V by an NCP1117 voltage regulator for the microcontroller and sensors.

Firmware¶
The firmware runs on the XIAO RP2040 using the Arduino framework. I wrote it in three stages, adding one layer at a time so I could test each part before moving on. For each stage, I used an AI coding assistant to help me write the firmware, giving it a specific prompt and then testing the resulting code on the actual hardware.
Step 1 — Reading the sensor¶
For this stage I prompted the AI assistant: “Write Arduino code for a XIAO RP2040 that reads an MQ-7 gas sensor on pin A0 and prints the raw value to the Serial Monitor every 300ms.” It returned the sketch below.
Before doing anything with outputs, I needed to confirm the MQ-7 was giving sensible readings. The MQ-7 sensor can be purchased from ozon This first sketch just reads the analog pin and prints the raw value to the Serial Monitor every 300ms — nothing else.
#define MQ7_PIN A0
void setup() {
Serial.begin(115200);
}
void loop() {
int gas = analogRead(MQ7_PIN);
Serial.println(gas);
delay(300);
}
Watching the values in normal air and then holding a lighter near the sensor gave me a feel for the range. That’s where the 200 and 600 thresholds came from — not arbitrary numbers, but values I observed during this step.
Step 2 — Adding LEDs¶
I went back to the AI assistant with the working sensor code and asked: “Add three LEDs to this code — green on pin D3, yellow on D2, red on D1. Turn on green if the gas reading is below 200, yellow if it’s between 200 and 600, and red if it’s above 600.” It gave me the updated sketch below, which I then tested on the board.
With the thresholds set, I added the three LEDs. Standard 5mm LEDs can be purchased from amazon. Each maps to one alert state — green for safe, yellow for warning, red for danger. The logic is simple: reset all three at the start of each loop, then turn on only the one that matches the current reading.

#define MQ7_PIN A0
#define RED_LED D1
#define YELLOW_LED D2
#define GREEN_LED D3
void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
}
void loop() {
int gas = analogRead(MQ7_PIN);
Serial.println(gas);
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
if (gas < 200) {
digitalWrite(GREEN_LED, HIGH);
}
else if (gas < 600) {
digitalWrite(YELLOW_LED, HIGH);
}
else {
digitalWrite(RED_LED, HIGH);
}
delay(300);
}
The LEDs responded exactly as expected — green in clean air, then switching to yellow and red as I introduced gas near the sensor.
Step 3 — Adding the buzzer¶
For the final stage I asked the AI assistant: “Add a buzzer on pin D6. Keep it off when safe, make it pulse on and off every 300ms during warning, and keep it continuously on during danger.” I took the resulting code, uploaded it, and tested all three states on the actual hardware.
The last piece was the buzzer. I wanted it to behave differently at each alert level to reinforce what the LED is showing: pulsing at warning (something is wrong, pay attention), continuous at danger (leave now). At safe level the buzzer stays off.
For this output I chose an active buzzer rather than a passive one. An active buzzer has its own internal oscillator circuit, so it produces a single fixed tone as soon as it’s powered — I just need to switch it on and off in code, without generating a tone signal myself. A passive buzzer, by contrast, requires the microcontroller to drive it with a specific frequency to produce sound, which would have added unnecessary complexity for what is essentially a simple alert signal. Active buzzers can be purchased from Amazon or similar electronics suppliers.
Key specifications, from the manufacturer datasheet:

| Parameter | Value |
|---|---|
| Rated Voltage | 6V DC |
| Operating Voltage | 4 to 8V DC |
| Rated Current | ≤30 mA |
| Sound Output at 10cm | ≥85 dB |
| Resonant Frequency | 2300 ±300 Hz |
| Tone | Continuous |
| Operating Temperature | -25°C to +80°C |
The wiring follows a series resistor on the A0 line between the buzzer and the PCB header, with the second buzzer terminal returning through GND:

#define MQ7_PIN A0
#define RED_LED D1
#define YELLOW_LED D2
#define GREEN_LED D3
#define BUZZER_PIN D6
void setup() {
Serial.begin(115200);
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
}
void loop() {
int gas = analogRead(MQ7_PIN);
Serial.println(gas);
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(BUZZER_PIN, LOW);
if (gas < 200) {
// SAFE — green LED on, no buzzer
digitalWrite(GREEN_LED, HIGH);
delay(300);
}
else if (gas < 600) {
// WARNING — yellow LED, pulsing buzzer
digitalWrite(YELLOW_LED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
delay(300);
digitalWrite(BUZZER_PIN, LOW);
delay(300);
}
else {
// DANGER — red LED, continuous buzzer
digitalWrite(RED_LED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
delay(300);
}
}

The three states are designed so a forge worker can understand the situation without looking closely at the device — green means keep working, yellow means ventilate, red means stop and leave.

Testing¶
I tested the complete system by cycling through all three states manually. In normal air the green LED stayed on and the buzzer was silent. Holding a lighter near the sensor brought the reading above 200 and the yellow LED came on with the pulsing buzzer. At higher concentrations the red LED activated with a continuous tone. Throughout the test the serial output matched what the LEDs were showing, confirming the full chain from sensor reading to physical output was working correctly.