WEEK 10
Output Devices
Group assignment:
- Measure the power consumption of an output device.
- Document your work on the group work page and reflect on your individual page what you learned.
What I Learned From Teamwork
Installing libraries for our devices
In this group assignment, I learned how to search for the libraries for each of the output devices we used, and then we checked that the compilation was correct. For this exercise, we used Adrian Torres's FABXIAO board and, as a first device, an LCD screen.
Checking the power consumption of the devices
For this group assignment, we first created the code to program our LCD screen and our servo motor. Then the devices were connected to the board and the power consumption was measured with a multimeter. We measured the power consumption at rest and then while the devices were operating, and later verified it using the basic power formula. We also confirmed that the servo motor consumes more power than the LCD screen.
Conclusion
In conclusion, the multimeter is a very useful tool for measuring the power consumption of devices. We also confirmed that the servo motor consumes more power than the LCD screen, because the servo motor has an internal motor that requires more energy than the LCD. In addition, we verified that power consumption at rest is lower than power consumption while the devices are operating, since devices demand more energy during operation.
Individual assignment:
- Add an output device to a microcontroller board you've designed and program it to do something.
Testing my PCB with my 9g microservo
First, we verify whether the connections in the schematic are correct.
To do this, we open KiCad and load the project, then open the schematic to confirm the connections. In this case, the servo motor is connected to 5V and to ground, and it is wired to pin D0 on the XIAO.
Here you can see the fabrication process in Week08
Now, in the PCB layout, we check the physical connections for the Microservo by tracing each connection.
We place our correctly soldered board and make the corresponding connections. The microservo (9g) is wired with three cables: the red wire (5V) connects to the power supply, the brown/black wire (GND) connects to ground, and the yellow/orange wire (signal) connects to pin D0 on the XIAO RP2040. The button is connected to pin D3 with a pull-up configuration (INPUT_PULLUP). The LED is connected to pin D2 in series with a current-limiting resistor to ground. The LDR sensor module is connected to pin D1 (analog input) for light intensity readings. All components share a common ground connection for proper circuit operation.
We generated a first test code to verify that the servo motor works correctly. For this, we used Gemini as a base and made some modifications so the servo motor moves when a button is pressed. We also added an LED that turns on while the servo motor is moving.
#include <Servo.h> Servo myServo; int servoPin = D0; int buttonPin = D3; int ledPin = D2; bool state = false; // general state bool lastButtonState = HIGH; void setup() { myServo.attach(servoPin); pinMode(buttonPin, INPUT_PULLUP); pinMode(ledPin, OUTPUT); } void loop() { bool reading = digitalRead(buttonPin); // Detect button press (falling edge) if (lastButtonState == HIGH && reading == LOW) { state = !state; // toggle state if (state) { myServo.write(180); digitalWrite(ledPin, HIGH); } else { myServo.write(0); digitalWrite(ledPin, LOW); } delay(200); // simple debounce } lastButtonState = reading; }
This code controls the 9g microservo with button input and visual feedback. When the button on pin D3 is pressed, it triggers a state toggle: if the servo is at 0°, it moves to 180°, turns on the LED on pin D2, and stays there until the button is pressed again; then it returns to 0° and the LED turns off. The code uses a debounce delay to prevent accidental multiple presses, and the servo is controlled via PWM on pin D0. The state variable maintains the current position state, making it a simple but effective on/off control mechanism for the servo motor.
PROBLEM FOUND: The AI-generated code initially named the pins as pin = 0 instead of pin = D0. This caused issues with device recognition—some components worked partially while others didn't respond at all. The XIAO RP2040 uses GPIO pin naming with the D prefix (D0, D1, D2, D3, etc.), not just numeric values. After adding the D prefix, all devices responded correctly. This is an important lesson: always verify that the generated code matches your specific microcontroller's pin naming convention before uploading to the board.
The video shows that the servo motor moves correctly when the button is pressed, and the LED turns on while the servo motor is moving. This indicates that the code works correctly and that the output device is functioning properly.
Testing my PCB with the LDR sensor and the microservo
We generated a second test code to interact with the LDR sensor and the microservo. For this, we used Gemini as a base and made some modifications so the servo motor moves depending on light and darkness, from 0 to 180 degrees.
#include <Servo.h> Servo myServo; int ldrPin = D1; // your connection int servoPin = D0; int threshold = 500; // adjust it void setup() { myServo.attach(servoPin); Serial.begin(115200); } void loop() { int ldrValue = analogRead(ldrPin); Serial.println(ldrValue); if (ldrValue > threshold) { myServo.write(180); // light } else { myServo.write(0); // darkness } delay(100); }
This code demonstrates binary servo control based on light intensity from the LDR sensor. The program reads the analog value from the LDR module on pin D1 and compares it against a threshold value of 500. When light hits the sensor and the LDR value exceeds the threshold, the servo moves to 180° (maximum position); when it falls below the threshold (darker conditions), the servo returns to 0° (minimum position). The Serial.println() function sends the LDR readings to the Serial Monitor for debugging, helping verify that the sensor is detecting light changes correctly. The delay(100) creates a 100ms pause between readings, preventing the servo from jittering due to rapid sensor fluctuations. This is a simple binary control example—either the servo is at 0° or 180°—useful for on/off applications like opening/closing mechanisms based on ambient light.
The video shows that the microservo responds correctly to the changes in light detected by the LDR sensor. In this case, the test was done with light and darkness: using a flashlight for light and covering the sensor with my finger for darkness.
Running tests for my hexamodular
We used an AI-generated code to interact with the LDR module and the microservo. For this, we used Gemini as a base and made some modifications so the servo motor moves depending on light and darkness, from 0 to 180 degrees. We also added gradual movement so the servo motor moves smoothly instead of abruptly.
#include <Servo.h> Servo myServo; int ldrPin = D1; int servoPin = D0; int minLDR = 60; int maxLDR = 900; int currentAngle = 0; // current position void setup() { myServo.attach(servoPin); Serial.begin(115200); } void loop() { int ldrValue = analogRead(ldrPin); // Limit range ldrValue = constrain(ldrValue, minLDR, maxLDR); // Convert to target angle int targetAngle = map(ldrValue, minLDR, maxLDR, 0, 180); // Gradual movement (1 degree per cycle) if (currentAngle < targetAngle) { currentAngle++; } else if (currentAngle > targetAngle) { currentAngle--; } myServo.write(currentAngle); Serial.print("LDR: "); Serial.print(ldrValue); Serial.print(" Target: "); Serial.print(targetAngle); Serial.print(" Current: "); Serial.println(currentAngle); delay(15); // controls speed (lower = faster) }
This advanced code provides smooth, gradual servo control by mapping continuous LDR sensor values to servo angles. The program reads the LDR value and uses constrain() to limit it within the calibrated range of 60 to 900 (minLDR to maxLDR). The map() function then converts this constrained LDR range to a servo angle between 0° and 180°, creating a proportional relationship—brighter light = higher angle, darker light = lower angle. Unlike the previous binary example, this code implements gradual movement: the servo increments or decrements by 1° per loop cycle (controlled by delay(15)), preventing abrupt jumps and creating smooth animation. This is achieved by comparing currentAngle with targetAngle and slowly adjusting the position. The Serial.print() statements output real-time debugging information (LDR value, target angle, and current angle), allowing you to verify the sensor readings and servo response in the Arduino IDE's Serial Monitor. This smooth control method is ideal for applications requiring precise, gentle movement—like opening a door slowly, adjusting light intensity, or creating mechanical animations.
We observed that our microservo, installed in our cardboard model, moves gradually according to the intensity of the light detected by the LDR sensor.
Conclusions:
- I confirmed that my designed PCB works correctly by integrating a microservo as an output device and controlling it from the XIAO RP2040.
- I verified that the connection between the servo, button, LED, and LDR sensor allows physical and interactive responses to be generated from my own board.
- I learned to program different servo behaviors in Arduino IDE, from simple 0° and 180° movements to smoother gradual motion.
- I understood that calibrating the LDR values is essential to achieve a stable and accurate microservo response to changes in light and darkness.
- This practice reinforced the importance of checking connections, soldering, and pin assignment, since any error directly affects the operation of the output device.
- As a result, I now have a stronger foundation to integrate controlled movement into my final project, applying output devices in a functional way that is consistent with my proposal.
DOWNLOAD FILES
The following files contain the Arduino code examples, schematic diagrams, and PCB design files used in this week's assignment:
• Arduino Code Examples:
- WEEK10_ServoButton.ino - Button-controlled servo with LED feedback
- WEEK10_ServoLDR_Binary.ino - Binary LDR-controlled servo (0° or 180°)
- WEEK10_ServoLDR_Gradual.ino - Smooth gradual servo movement with LDR input