Output Devices
Group Assignment:
- measure the power consumption of an output device
Individual Assignment:
- add an output device to a microcontroller board you've designed and program it to do something
OLED
OLED is a self-illuminating display technology that provides superior image quality with perfect blacks, high contrast, and fast response times. It's widely used in premium displays but has limitations including potential burn-in and shorter lifespan compared to some alternatives. (From Claude, Prompt: What are OLED?)
I started by using an OLED from the fab inventory. It is very simple to connect VCC, GND, SDA, and SCL. But make sure you connect it correctly, as I did not and fried one screen. I plugged it in, went to connect my microcontroller, and then there was smoke and it was dead. Second try it worked, and I was able to display text on the screen. Next, I went to Claude and asked it to change the script I got from Adrian and made it count how many times I pressed a button. When I was about to take a video, the screen decided to stop working. Once I figure that out, I will add a video here.
(Video)
Here is the code
#include <U8g2lib.h>
// OLED display using SSD1306 driver
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset= */ U8X8_PIN_NONE);
const int buttonPin = D7; // Button connected to 3.3V
int buttonState = LOW; // Current state of the button
int lastButtonState = LOW; // Previous state of the button
int pressCount = 0; // Number of button presses
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup(void) {
Serial.begin(115200);
while (!Serial) {}
delay(100);
Serial.println("OLED Button Counter - Setup (3.3V logic)");
pinMode(buttonPin, INPUT); // For 3.3V button, use INPUT with external pulldown
u8g2.begin();
}
void loop(void) {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
// Count only when button is pressed (HIGH)
if (buttonState == HIGH) {
pressCount++;
}
}
}
lastButtonState = reading;
// Display on OLED
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 10, "Puffin has entered:");
char buf[20];
snprintf(buf, sizeof(buf), "%d times", pressCount);
u8g2.drawStr(0, 30, buf);
u8g2.sendBuffer();
delay(50);
}
E-ink
E-Ink is a paper-like display technology that uses electrically charged particles to create images, offering high readability and extremely low power consumption, but with slower refresh rates than conventional displays. (From Claude, Prompt: What is E-Ink?)
I used the E-Ink breakout board from Seeed. It was a bit of a hassle to get working. One thing to note here is the screen takes a while to update, so it confused me when nothing was happening, but I just had to wait a little bit. Also, you have to let the screen rest in between refreshes; otherwise, it will not turn white. I used this documentation from Seeed and the example clock script. Here is an image:
LCD
I think this is what i am going to use for my final project. It is simple to connect and the code is very simple. I began by getting a grove LCD and connecting it to a board with a XIAO ESP32C3 and asked my good friend ChatGPT to write some code. Most is written by AI but a good portion is my own. Quick note is i am using a custom Arduino Libery from Seed. Downloadable here. Here is the main code. It is quite simple but a good start the next step will be adding a step response and making it count when someone touches it.
#include <Wire.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
const int buttonPin = 20;
int lastButtonState = LOW;
int pressState = 0;
int inCount = 0;
int outCount = 0;
void setup() {
delay(500);
pinMode(buttonPin, INPUT);
lcd.begin(16, 2);
lcd.clear();
// --- LOADING SCREEN ---
lcd.setCursor(0, 0); // Left-aligned
lcd.print("PuffIN & OUT!");
const char* dots[] = { "Loading. ", "Loading.. ", "Loading..." };
for (int i = 0; i < 5; i++) {
lcd.setCursor(0, 1);
lcd.print(dots[i % 3]);
delay(1000);
}
// --- MAIN DISPLAY ---
lcd.clear();
lcd.setCursor(0, 0); // Left-aligned again
lcd.print("PuffIN & OUT!");
lcd.setCursor(0, 1);
lcd.print("IN: 0 OUT: 0");
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (lastButtonState == LOW && buttonState == HIGH) {
if (pressState == 0) {
inCount++;
} else {
outCount++;
}
pressState = 1 - pressState;
lcd.setCursor(0, 1);
lcd.print(" ");
char buffer[17];
snprintf(buffer, sizeof(buffer), "IN: %-3d OUT: %-3d", inCount, outCount);
lcd.setCursor(0, 1);
lcd.print(buffer);
delay(200); // debounce
}
lastButtonState = buttonState;
}