Week 10 Fab Academy 2026 · Lab Rwanda

Output
Devices

Driving three output devices from the custom ESP32-S3 board — a 1.3" OLED display, an LED on GPIO 2, and a small servo motor — each controlled and programmed to do something useful.

BoardESP32-S3
Display1.3" OLED
LEDGPIO 2
ActuatorServo Motor
Status✓ All Working
OLED DisplayLED OutputServo MotorI²C ProtocolPWMU8g2 LibraryESP32ServoGPIO 2Power Measurement OLED DisplayLED OutputServo MotorI²C ProtocolPWMU8g2 LibraryESP32ServoGPIO 2Power Measurement
Overview

Introduction

Output Devices week shifts the focus from reading the world to acting on it. A microcontroller is only as useful as what it can drive — displays, lights, motors. On my custom ESP32-S3 board, I worked with three output devices: a 1.3" OLED display over I²C, an LED on GPIO 2, and a small servo motor driven by PWM.

Each device represents a different output category — visual information, simple digital switching, and physical actuation — and together they demonstrate the range of things an embedded board can do beyond just reading sensors.

Display 1.3" OLED
ProtocolI²C
Resolution128 × 64 px
LibraryU8g2
ShowsText / readings
PinsSDA + SCL
Digital LED
PinGPIO 2
ControldigitalWrite()
DimmingPWM / analogWrite
UseStatus / trigger
Current limitResistor on board
Actuator Servo Motor
ControlPWM signal
LibraryESP32Servo
Range0° – 180°
TriggerSensor reading
Power3.3 / 5 V
This Week

Assignments

Group Assignment
Measure the power consumption of an output device.

As a group, we used a multimeter in series with an output device to measure current draw under different operating conditions — comparing idle vs active power and understanding what each device actually costs the power supply.

Individual Assignment
Add an output device to a microcontroller board you've designed, and program it to do something.

For my individual work, I connected and programmed all three output devices on the custom ESP32-S3 board — driving the OLED to display sensor readings, blinking the LED as a status indicator, and sweeping the servo in response to input.

Process

Step-by-Step

Each output device was set up and tested independently before being combined into a single unified sketch that drives all three simultaneously.

Output 01
1.3" OLED Display I²C · U8g2 · 128×64
Step 01
Install the U8g2 Library
Opened the Arduino IDE Library Manager and searched for U8g2 by oliver. Installed it — U8g2 supports a wide range of monochrome displays including the SH1106 and SSD1306 controllers commonly found on 1.3" OLEDs, and handles all the I²C communication internally.
Library ManagerU8g2SH1106 / SSD1306
🖼️
Add image — U8g2 library installed
Step 02
Wire & Initialize the OLED
Confirmed the OLED's SDA and SCL lines connect to the ESP32-S3's I²C pins. Identified the correct U8g2 constructor for the display controller — using the hardware I²C variant for reliable communication. The display address is typically 0x3C.
SDA / SCLI²C Address 0x3CHardware I²C

Tip: If the display doesn't initialize, try swapping the constructor between SH1106 and SSD1306 — both are common on 1.3" modules and look identical from the outside.

Step 03
Display Text & Sensor Readings
Wrote a sketch that initializes the OLED and displays multiple items — a title line, live temperature and humidity from the DHT sensor, and the variable resistor ADC value — updating the screen every 2 seconds. Used U8g2's drawStr() and setCursor() to lay out the information cleanly across the 128×64 pixel canvas.
drawStr()setFont()clearBuffer()sendBuffer()
// OLED Display — Show sensor readings #include <Arduino.h> #include <U8g2lib.h> #include <Wire.h> #include <DHT.h> // — Match constructor to your OLED controller — U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); #define DHT_PIN 4 #define DHT_TYPE DHT11 #define POT_PIN 34 DHT dht(DHT_PIN, DHT_TYPE); void setup() { u8g2.begin(); dht.begin(); } void loop() { float temp = dht.readTemperature(); float hum = dht.readHumidity(); int pot = analogRead(POT_PIN); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_6x10_tf); u8g2.drawStr(0, 12, "ESP32-S3 Board"); u8g2.drawHLine(0, 15, 128); char line[32]; u8g2.setFont(u8g2_font_5x8_tf); snprintf(line, sizeof(line), "Temp: %.1f C", temp); u8g2.drawStr(0, 30, line); snprintf(line, sizeof(line), "Hum: %.1f %%", hum); u8g2.drawStr(0, 42, line); snprintf(line, sizeof(line), "Pot: %d", pot); u8g2.drawStr(0, 54, line); u8g2.sendBuffer(); delay(2000); }
🖼️
Add image — OLED displaying sensor data
🖼️
Add image — OLED close-up on board
Output 02
LED on GPIO 2 digitalWrite · PWM · Status indicator
Step 04
Basic LED Blink & Status Logic
GPIO 2 is configured as an output and used as a visual status indicator. In the basic sketch, the LED blinks at a regular interval to show the board is alive. In the combined sketch, the LED logic is tied to a trigger condition — for example, blinking faster when the DHT sensor reads above a temperature threshold, turning on solid when the potentiometer crosses the midpoint.
GPIO 2pinMode OUTPUTdigitalWrite()Status Indicator
// LED on GPIO 2 — status indicator #define LED_PIN 2 void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { // Basic blink — board alive indicator digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500); // — In combined sketch: tie to sensor threshold — // if (temperature > 30.0) digitalWrite(LED_PIN, HIGH); // else digitalWrite(LED_PIN, LOW); }
🖼️
Add image — LED on, board powered
🖼️
Add image — LED triggered by sensor threshold
Output 03
Servo Motor PWM · ESP32Servo · 0°–180°
Step 05
Install ESP32Servo Library
The standard Arduino Servo.h library doesn't work correctly on ESP32 boards. Installed ESP32Servo by Kevin Harrington from the Library Manager — it uses the ESP32's hardware timer channels to generate accurate PWM signals for servo control.
Library ManagerESP32ServoHardware Timer PWM
🖼️
Add image — ESP32Servo library install
Step 06
Wire & Control the Servo
Connected the servo signal wire to a PWM-capable GPIO pin. Wrote a sketch that attaches the servo and sweeps it from 0° to 180° and back in a loop. Then extended it so the servo position is mapped directly from the potentiometer value — turning the variable resistor physically moves the servo arm, giving immediate tactile-to-mechanical feedback.
Servo.attach()Servo.write()map()PWM GPIO

Power note: Servos can draw significant current on movement. If the board resets when the servo moves, power the servo from an external 5V supply and share only the GND with the ESP32-S3.

// Servo Motor — mapped to potentiometer #include <ESP32Servo.h> #define SERVO_PIN 13 // PWM-capable GPIO #define POT_PIN 34 Servo myServo; void setup() { myServo.attach(SERVO_PIN, 500, 2400); // min/max pulse µs Serial.begin(115200); } void loop() { int raw = analogRead(POT_PIN); // 0 – 4095 int angle = map(raw, 0, 4095, 0, 180); // map to degrees myServo.write(angle); Serial.print("Pot: "); Serial.print(raw); Serial.print(" Servo: "); Serial.print(angle); Serial.println("°"); delay(20); // servo update rate ~50Hz }
🖼️
Add image — servo connected to board
🖼️
Add image — servo arm moving positions
Combined
All Three Outputs Together OLED + LED + Servo · unified sketch
Step 07
Unified Output Sketch
Merged all three output sketches into one firmware. The OLED shows live sensor readings, the LED lights up when temperature exceeds a threshold, and the servo position tracks the potentiometer — all running together in a single loop, demonstrating the ESP32-S3 handling multiple output devices simultaneously without conflict.
Unified FirmwareOLED + LED + ServoSensor-triggered

Result: All three outputs respond in real time — the display updates with fresh readings every 2 seconds, the LED reacts to temperature, and the servo follows the potentiometer — confirming the board can drive multiple output types simultaneously.

🖼️
Add image — all three outputs active simultaneously
Results

Summary

OLED Resolution
128× 64 px
OLED Protocol
I²C0x3C
LED Pin
GPIO2
Servo Range
0 – 180°
Servo Control
PWM50Hz
All Outputs
✓ Working
Takeaways

Conclusion

Working with three different output types in the same week made the variety of ways a microcontroller can interact with the physical world very concrete. The OLED communicates structured information over I²C, the LED gives instant binary feedback via a single GPIO, and the servo converts a PWM signal into physical rotation — three completely different mechanisms, all driven from the same board.

Tying the servo position and LED trigger to live sensor readings rather than hardcoded values was the most valuable part — it shows how input and output devices work together as a system, which is the foundation for any real embedded application.

OLED Display U8g2 Library I²C Protocol LED GPIO 2 Servo Motor ESP32Servo PWM Control Sensor-triggered Output
← Week 09 · Input Devices All Assignments →