10-Output devices¶
Assignments¶
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.
Individual assignment:¶
- Add an output device to a microcontroller board you’ve designed and program it to do something.
Learning outcomes - Demonstrate workflows used in controlling an output
The road map i made for this week can be accesed here

Group Assignment¶
You can access our group assignment here
Reflection
Measuring a device’s power usage ended up being a really interesting hands-on activity. Our group prepared well, gathered the needed tools, and followed safety steps, which made the setup smooth. Connecting the power supply through the multimeter to the device felt like doing a small technical mission.
The biggest takeaway for me was clearly understanding the difference between measuring voltage and current. Voltage is checked in parallel to read the potential between two points, while current must be measured in series so the multimeter sits in the actual path of the flow. Thinking of voltage as “pressure” and current as “flow” made it easier to grasp.
Seeing the power meter come alive was satisfying, and doing the power calculations afterward was surprisingly fun. Using the formula Power = Voltage × Current with real measurements made the whole concept much clearer and more meaningful.
Individual Assignments¶
Before i start my assignments, I have a short terminology check on libaries and boards because i kept getting them mixed up, so its a shoot note for me.
Library A library in Arduino is a collection of pre-written code that provides functions, classes, or routines to simplify the use of specific hardware or perform specific tasks. Libraries allow you to interact with sensors, displays, motors, or other devices without writing low-level code from scratch.
Difference
Aspect Library Board Configuration Type Software Hardware/Software setup Purpose Provides functions to control hardware Ensures microcontroller and IDE know how to interface with the hardware Example Adafruit_SSD1306 for OLED Selecting ESP32-C3 in Arduino IDE and mapping pins 2–5 for motors Scope Affects code you write Affects how your code interacts with the hardware
Summary: Libraries are software tools that help you control devices, while board configuration ensures that the software and physical hardware are correctly aligned. They are distinct, but both are necessary for a functional Arduino project.
This is the pcb i made in the previous weeks for my assignments. I did not initally use this for all the components testing. I only used it for testing the olde but it turned ot there was a short circuit in my soldering so it didnt work.


This is the final pcb (the one i used for my project in the end)

To make my PCB, I first designed the schematic in KiCad, placing all components and connecting them according to the circuit. After verifying the connections, I moved to the PCB layout editor, arranged the components on the board, and routed all the traces while keeping clearances and orientation in mind. Once the layout was complete, I exported the Gerber files, which I then loaded into Quintorrres to prepare the files for milling and fabrication. The software helped me verify the layers and generate the toolpaths for the CNC machine. Finally, I milled the board, and soldered the components.Then i checked the connections with a multimeter to make sure it was soldered well.
You can access more info on how to program and make a board in my electronics production week assignment here
Matrix Display Test¶
The first component I’ll be using is the matrix display so for the eyes of the bot. While testing and learning about this component, I was able to change up and make a few different animations!


The code for the blinking eye is from chatgpt.
prompt:Create an Arduino sketch to animate an eye on a single 8x8 LED matrix using a MAX7219 and the LedControl library (DIN=12, CLK=11, CS=10). Include frames for fully open, half-closed (top lid down), fully closed, and half-closed (bottom lid up). Loop the animation with appropriate delays and use a function to display each frame neatly.
#include <LedControl.h>
// DIN = 12, CLK = 11, CS = 10
LedControl lc = LedControl(12, 11, 10, 1);
byte eyeOpen[8] = {
B01111110,
B10000001,
B10000001,
B10111101,
B10111101,
B10000001,
B10000001,
B01111110
};
// Half-closed eye (top lid coming down) (vertical flipped)
byte eyeHalfClosed1[8] = {
B00001110,
B00110010,
B01000010,
B01111110,
B01111110,
B01000010,
B00110010,
B00001110
};
// Closed eye (vertical flipped)
byte eyeClosed[8] = {
B00011000,
B00011000,
B00011000,
B00011000,
B00011000,
B00011000,
B00011000,
B00011000
};
// Half-closed eye (bottom lid going up) (vertical flipped)
byte eyeHalfClosed2[8] = {
B00001110,
B00110010,
B01000010,
B01111110,
B01111110,
B01000010,
B00110010,
B00001110
};
void setup() {
lc.shutdown(0, false);
lc.setIntensity(0, 8);
lc.clearDisplay(0);
}
void loop() {
displayFrame(eyeOpen);
delay(6000);
displayFrame(eyeHalfClosed1);
delay(500);
displayFrame(eyeClosed);
delay(1000);
displayFrame(eyeHalfClosed2);
delay(500);
}
void displayFrame(byte frame[8]) {
for (int i = 0; i < 8; i++) {
lc.setRow(0, i, frame[i]);
}
}
Code explaination¶
8×8 LED Matrix Eye Animation
This Arduino sketch controls an 8×8 LED matrix using the LedControl library to display a blinking eye animation. The matrix is driven by a MAX7219 chip connected through pins DIN=12, CLK=11, and CS=10, with a single device in the chain.
Code to Physical Mapping
Four frames are defined using 8-byte arrays: open eye, two half-closed variations, and closed eye. Each byte represents one row of the matrix, and each bit in the byte corresponds to a single LED in that row:
Bit 7 (MSB) → leftmost LED
Bit 0 (LSB) → rightmost LED A bit value of 1 turns the LED on, while 0 turns it off. This mapping allows the 2D patterns in code to be directly translated into physical LED states on the matrix.
Animation Logic
In setup(), the matrix is initialized, brightness is set, and the display is cleared. The loop() function animates the blinking by sequentially displaying each frame with specific delays:
Open eye: 6 seconds
Half-closed variations: 0.5 seconds each
Closed eye: 1 second
The helper function displayFrame() iterates through each row and sends the byte pattern to the driver, creating the blinking effect..
Reflection / Learning
This code was initially generated with ChatGPT to provide a working test for the animation. I only had to modify pin assignments, and adjust frame timing. I had a fun time making my own animations for the code after i understod how it works, and trying to make different shapes to see which one i wantd to use as the eyes for the final bot in the end.
This was just the test program i ran to get familar with this component. Later onwards, I combined the expressions with the movement(motor)and ultrasonic.
### Motor
I used two dc motors for my bot for the movement. The movemente i made with the motors include forward, backward turning and delay’s in between movements.
I usd chatgpt for this code
prompt:Write an Arduino sketch for a Xiao ESP32-C3 to control two DC motors (Motor A: pins D2/D3, Motor B: pins D4/D5). Implement functions to move the motors forward, backward, left, right, and stop, each running for 2 seconds with short delays to prevent pin conflicts. Loop through these movements continuously.
// Motor A control pins
const int in1 = 2; // D2 on Xiao ESP32-C3
const int in2 = 3; // D3
// Motor B control pins
const int in3 = 4; // D4
const int in4 = 5; // D5
void setup() {
// Set all motor control pins as output
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
// Ensure motors are off at start
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
void loop() {
forward();
left();
backward();
right();
stop();
}
void forward(){
// === FORWARD ===
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
delay(100); // short delay to avoid pin conflict
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(2000); // run forward for 2 seconds
}
void backward(){
// === REVERSE ===
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
delay(100);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(2000); // run reverse for 2 seconds
}
void right (){
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
delay(100);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(2000); // run reverse for 2 seconds
}
void left(){
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
delay(100);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(2000); // run reverse for 2 seconds
}
void stop(){
// === STOP ===
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
delay(2000); // pause for 2 seconds
}
Code explaination¶
his code controls two DC motors connected to an ESP32-C3 board using four GPIO pins (IN1–IN4). Motor A is connected to pins 2 and 3, and Motor B to pins 4 and 5. The motors are powered through a separate 5 V supply via a motor driver (L293D/L298N or equivalent) to protect the microcontroller and provide sufficient current. The ground of the motor supply and the ESP32-C3 are connected to ensure a common reference.
Board Configuration and Programming
In the setup() function, all motor pins are configured as outputs and initialized to LOW to ensure the motors are off at startup. No additional libraries are required for this control; all operations are handled directly through GPIO pin configuration, distinguishing this from software libraries used for higher-level devices (e.g., OLED, LED matrix).
The loop() function repeatedly calls movement functions—forward(), left(), backward(), right(), and stop()—to make the motors move in sequence. Each function sets the pins HIGH or LOW to control rotation direction:
Forward: both motors rotate forward
Backward: both motors rotate backward
Turning: one motor forward, one backward for left or right turns
Stop: all pins LOW
Short delays are included between movements to prevent pin conflicts, ensure the motor driver switches safely, and allow each motion to run for about two seconds.
Challenges and Iterations
During initial testing, the motors did not respond correctly due to incorrect pin wiring and insufficient current from the microcontroller. Adding a dedicated motor driver and adjusting pin connections resolved these issues. Additionally, timing delays had to be fine-tuned to avoid abrupt stops and unintended reversals.
Learning Outcomes
Through this exercise, I learned:
How to map GPIO outputs to physical motor control.
How to safely drive motors using a separate power source and motor driver.
How to sequence movements programmatically to achieve desired robot motion.
The importance of testing pin configurations and wiring carefully before applying power.
How to interpret and debug unexpected motor behavior by analyzing both hardware and code.
This project reinforced my understanding of the difference between hardware configuration (pin setup, power supply, driver) and software libraries, as well as the practical challenges of controlling motors on a microcontroller platform.
After learning the code of the motors though, i needed to learn how to make the connections, which lead to alot of issues in the future(power connections done wrong)
While learning how to connect the motors to the motor driver with an arduino, i kept having issues where it would show me its connected, but the code didnt work.

After multiple failed attempts, i reached out to my instructor and got some resources and suggestions

After looking carefully at this diagram, I realised
1- I got the ground and power connections with the motor driver and ardunio wrong. I was trying to connect the power of my arduino to the board, when it turns out only ground is required.
2- I inversed the ground and power of the motor driver. I honestly made this mistake many more times even after this. I almost burned a motor driver, and ended up frying 2 laptops.😅
3- that I conneced the motors inversed, so even after the motors were moving, the direction was mixed up.
While my instructor was explaining he drew this diagram to help me understand better.

After i was able to understand all of this,I fixed all the connections and then tested it out with arduino.

Here an overview of all the components i learned working together!

Oled¶
This is what i initally tryed out for this week before completing my final project, but i didnt test it out with my working mcb, i just used a xaio directly.Because of that it didnt fit the requirements for this weeks assignment. Even so heres a short writeup on the oled when i did try it out.

I got this code from chatgpt
prompt:Write an Arduino sketch for a Seeeduino XIAO to display a light meter on a 128×32 OLED using the Adafruit_SSD1306 and Adafruit_GFX libraries. Initialize the OLED, clear the display, and show the text “L Meter:” at the top and “www.electroniclinic.com ” at the bottom. Include placeholders for reading an LDR sensor but keep them commented out.
/*
Light meter
Oled interfacing with Seeeduino XIAO
Download Libraries:
https://www.electroniclinic.com/arduino-libraries-download-and-projects-they-are-used-in-project-codes/
*/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// int LDR = A0;
// int LDR_DATA;
// int F_value; // LDR sensor final value
void setup() {
Serial.begin(57600);
// pinMode(LDR, INPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(2000);
display.clearDisplay();
display.setTextColor(WHITE);
}
void loop() {
// F_value = readSensor();
display.clearDisplay();
// display R G B Values
display.setTextSize(2);
display.setCursor(0,0);
display.print("L Meter:");
// display.setTextSize(3);
// display.setCursor(0, 28);
// display.print(F_value);
display.setTextSize(1);
display.setCursor(0, 56);
display.print("www.electroniclinic.com");
display.display();
}
// int readSensor()
// {
// LDR_DATA = analogRead(LDR);
// LDR_DATA = map(LDR_DATA,0,1023,0,100);
// return(LDR_DATA);
// delay(1000);
// }
Errors¶
1- The first error I faced was checking the power with a multimeter. The first few times the connection was just not done right, but afterwards, even if i got the connection correct, it turned out that my mcb had short circuited, so i needed to make a new microcontroller. Even so, when i tryed it out with just the xaio board it did end up working.

2- During the connection process, i also, like i mentioned made quite a few wrong connections, so i burned up the oled.It didn’t exactly burn, it just heated up but i felt like i should mention it in my errors.