What I wanted to learn, and why it interested me: I wanted to learn how thermal printing could be used in simple, fun ways to make everyday life better. I thought it would be cool to combine a thermal printer with a photoresistor so it could react to light, printing cheerful messages in the morning and kind notes at night. The idea of building a little motivation buddy that responds to its environment interested me because it mixes creativity with tech and could make daily routines a bit more positive.
Final outcome: I built an interactive storyline using a thermal printer, two buttons, and a photoresistor. When the photoresistor senses light, the printer says “Good morning” and goes through your day with you by asking questions that you answer using the arcade buttons. The blue button means no and the yellow button means yes. There is also a switch on the side that stops and restarts the story. When the photoresistor detects darkness, the printer says “Good night” and tells a bedtime story with more questions that you answer the same way.
Images of final creative/exploratory output
A close up of the arcade buttons ,switch and the photoresistor(how the brightness is detected)
Video of the printer being using and creating the story line
Process images from development towards creative/exploratory output
Setting up the photoresistor so it detects light
Attaching one button at a time
Process and reflection:
First, I figured out how to connect the thermal printer to power and then how to connect it to the Arduino. After that, I set up the photoresistor, which determines if there is bright light or not. I then focused on getting the Arduino to print something based on the brightness. Once that worked, I created a simple storyline for both “Good morning” when it’s bright and “Good night” when it’s dark. After that, I wrote the questions and connected the arcade buttons so they could be used to respond. Lastly, I connected the switch that restarts the story.I learned that thermal printers are very versatile. I didn’t realize how important the light range was for the photoresistor and how tricky it could be to get it just right. The switch setup was also more complicated than I expected. Overall, the project turned out great, but I’m considering moving the switch outside the breadboard like the buttons to make it easier to use.
Technical details
Electrical schematic
/*
60-223 Intro to Physical Computing, fall 2025
Domain-specific Skill Building exercise: Choose Your Story
This sketch connects a thermal receipt printer, a photoresistor (light sensor),
two arcade buttons, and a toggle switch to an Arduino. The printer tells short,
funny stories that change based on the surrounding light. When the photoresistor
detects brightness, it prints a “Good Morning” story, and when it’s dark, it prints
a “Good Night” story. The yellow and blue arcade buttons let you make choices in the
story, like a mini choose your own adventure game. The toggle switch acts as a power
control, when it’s off, the system does nothing, and when it’s on, it restarts
and checks the light to begin the right story mode.
Pin mapping:
Arduino pin | role | details
------------------------------
5 TX Thermal Printer
6 RX Thermal Printer
8 input Switch
4 input Yellow Button
7 input Blue Button
A0 input Photoresistor
Released to the public domain by the author, October 2025
Danely Rodriguez, danelyr@andrew.cmu.edu
Prompt used for ChatGPT:
I want you to write me a complete Arduino sketch for a project using a thermal printer,
a photoresistor, two arcade buttons, and a toggle switch. The photoresistor should detect
light levels on pin A0 to decide between “daytime” and “nighttime” story modes. When it’s
bright, the printer should say “Good Morning” and tell a funny daytime story where I
can make choices by pressing the buttons. When it’s dark, it should print “Good Night”
and tell a silly nighttime story that also changes based on my button presses. The yellow
button on pin 4 should represent “yes,” and the blue button on pin 7 should represent “no.”
Each button press should print the next part of the story, with clear line spacing so
it’s easy to read. The toggle switch on pin 8 should act as an on/off control: when it’s
off, nothing runs, and when it’s on, it starts fresh, checks the light, and begins the
right story. The goal is to make a light-reactive, choose-your-own-adventure thermal printer
that’s playful, simple, and funny.
*/
#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"
// ===== Thermal printer wiring =====
#define TX_PIN 5
#define RX_PIN 6
SoftwareSerial mySerial(RX_PIN, TX_PIN);
Adafruit_Thermal printer(&mySerial);
// ===== Photoresistor =====
#define LDR_PIN A0
int lightValue = 0;
int threshold = 500; // <= 500 = night, > 500 = day
// ===== Buttons =====
#define BUTTON_YELLOW 4
#define BUTTON_BLUE 7
#define SWITCH 8
// ===== State tracking =====
bool storyRunning = false;
int storyStep = 0;
int storyMode = 0; // 1 = day, 2 = night
// ===== Debounce setup =====
unsigned long lastPressYellow = 0;
unsigned long lastPressBlue = 0;
unsigned long lastPressReset = 0;
const unsigned long debounceDelay = 150;
// ===== Debounce functions =====
bool yellowPressed() {
if (digitalRead(BUTTON_YELLOW) == LOW && (millis() - lastPressYellow > debounceDelay)) {
lastPressYellow = millis();
return true;
}
return false;
}
bool bluePressed() {
if (digitalRead(BUTTON_BLUE) == LOW && (millis() - lastPressBlue > debounceDelay)) {
lastPressBlue = millis();
return true;
}
return false;
}
bool resetPressed() {
if (digitalRead(SWITCH) == LOW && (millis() - lastPressReset > debounceDelay)) {
lastPressReset = millis();
return true;
}
return false;
}
// ===== Bitmaps =====
const uint8_t PROGMEM sun_bitmap[] = {
0x07,0xE0, 0x1F,0xF8, 0x3F,0xFC, 0x7F,0xFE,
0x7F,0xFE, 0xFF,0xFF, 0xFF,0xFF, 0xFF,0xFF,
0xFF,0xFF, 0xFF,0xFF, 0x7F,0xFE, 0x7F,0xFE,
0x3F,0xFC, 0x1F,0xF8, 0x07,0xE0, 0x00,0x00
};
const uint8_t PROGMEM moon_bitmap[] = {
0x07,0xE0, 0x1F,0xF8, 0x3C,0x3C, 0x78,0x1E,
0xF0,0x0F, 0xF0,0x0F, 0xF0,0x0F, 0xF0,0x0F,
0xF0,0x0F, 0xF0,0x0F, 0x78,0x1E, 0x3C,0x3C,
0x1F,0xF8, 0x07,0xE0, 0x00,0x00, 0x00,0x00
};
// ===== Setup =====
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
printer.begin();
printer.setDefault();
printer.sleep();
// All buttons use INPUT_PULLUP
pinMode(BUTTON_YELLOW, INPUT_PULLUP);
pinMode(BUTTON_BLUE, INPUT_PULLUP);
pinMode(SWITCH, INPUT_PULLUP);
Serial.println("System ready. Waiting 5 sec for light check...");
delay(5000);
checkLightAndStart();
}
// ===== Main loop =====
void loop() {
if (storyRunning) handleStory();
// Reset button restarts story
if (resetPressed()) {
Serial.println("🔁 Reset pressed — restarting...");
storyRunning = false;
storyMode = 0;
storyStep = 0;
delay(300);
checkLightAndStart();
}
}
// ===== Light detection & story start =====
void checkLightAndStart() {
Serial.println("Checking light...");
delay(5000);
lightValue = analogRead(LDR_PIN);
Serial.print("Light sensor value: ");
Serial.println(lightValue);
if (lightValue > threshold) {
Serial.println("☀️ Detected DAY mode");
startDayStory();
} else {
Serial.println("🌙 Detected NIGHT mode");
startNightStory();
}
}
// ===== Story starters =====
void startDayStory() {
storyRunning = true;
storyMode = 1;
storyStep = 0;
Serial.println("Starting Good Morning Story");
printer.wake();
printer.setDefault();
printer.justify('C');
printer.printBitmap(16, 16, sun_bitmap);
printer.println("Good Morning!");
printer.println("");
printer.println("Do you want coffee?");
printer.println("Yellow=Yes Blue=No");
printer.feed(2);
printer.sleep();
}
void startNightStory() {
storyRunning = true;
storyMode = 2;
storyStep = 0;
Serial.println("Starting Good Night Story");
printer.wake();
printer.setDefault();
printer.justify('C');
printer.printBitmap(16, 16, moon_bitmap);
printer.println("Good Night!");
printer.println("");
printer.println("Do you want a story?");
printer.println("Yellow=Yes Blue=No");
printer.feed(2);
printer.sleep();
}
// ===== Handle button input during story =====
void handleStory() {
if (yellowPressed()) advanceStory(true);
else if (bluePressed()) advanceStory(false);
}
// ===== Story logic =====
void advanceStory(bool yellow) {
printer.wake();
printer.setDefault();
printer.justify('C');
if (storyMode == 1) { // DAY STORY
if (storyStep == 0) {
if (yellow) {
printer.println("You wait in line");
printer.println("an hour.");
printer.println("Your latte has");
printer.println("foam art!");
} else {
printer.println("You save $8.");
printer.println("A pigeon steals");
printer.println("your granola bar.");
}
printer.println("");
printer.println("At your desk.");
printer.println("Emails or snacks?");
printer.println("Yellow=Emails Blue=Snacks");
printer.feed(2);
storyStep++;
}
else if (storyStep == 1) {
if (yellow) {
printer.println("200 emails open!");
printer.println("One is just a");
printer.println("potato picture.");
} else {
printer.println("You eat 37 gummy bears.");
printer.println("They elect you");
printer.println("their leader!");
}
printer.println("");
printer.println("Lunch time.");
printer.println("Pizza or Salad?");
printer.println("Yellow=Pizza Blue=Salad");
printer.feed(2);
storyStep++;
}
else if (storyStep == 2) {
if (yellow) {
printer.println("Pizza slice");
printer.println("bigger than your head!");
} else {
printer.println("Your salad tries");
printer.println("to escape!");
printer.println("Everyone claps.");
}
printer.println("");
printer.println("Afternoon arrives.");
printer.println("Nap or Work?");
printer.println("Yellow=Nap Blue=Work");
printer.feed(2);
storyStep++;
}
else if (storyStep == 3) {
if (yellow) {
printer.println("You nap.");
printer.println("Boss also naps.");
printer.println("Everyone wins!");
} else {
printer.println("You work so hard");
printer.println("your keyboard asks");
printer.println("for a break!");
}
printer.println("");
printer.println("Commute home.");
printer.println("Walk or Bus?");
printer.println("Yellow=Walk Blue=Bus");
printer.feed(2);
storyStep++;
}
else if (storyStep == 4) {
if (yellow) {
printer.println("You walk home.");
printer.println("Meet a dog who");
printer.println("becomes mayor.");
} else {
printer.println("Bus is late.");
printer.println("You invent a new");
printer.println("dance move waiting.");
}
endStory();
}
}
else if (storyMode == 2) { // NIGHT STORY
if (storyStep == 0) {
if (yellow) {
printer.println("The moon gives you");
printer.println("a thumbs up.");
} else {
printer.println("The stars");
printer.println("tell jokes anyway.");
}
printer.println("");
printer.println("Dream time.");
printer.println("Castle or Forest?");
printer.println("Yellow=Castle Blue=Forest");
printer.feed(2);
storyStep++;
}
else if (storyStep == 1) {
if (yellow) {
printer.println("A ghost offers you");
printer.println("a glowing cupcake.");
endStory();
} else {
printer.println("A raccoon DJ appears!");
printer.println("Do you join the dance?");
printer.println("Yellow=Yes Blue=No");
printer.feed(2);
storyStep = 21;
}
}
else if (storyStep == 21) {
if (yellow) {
printer.println("You dance with monkeys.");
printer.println("Raccoons play trumpet!");
} else {
printer.println("You sit out.");
printer.println("The raccoons play");
printer.println("a sad kazoo...");
}
endStory();
}
}
printer.feed(1);
printer.sleep();
}
// ===== End Story =====
void endStory() {
printer.println("=== The End ===");
printer.feed(3);
printer.sleep();
storyRunning = false;
storyMode = 0;
storyStep = 0;
Serial.println("Story ended. Waiting 5 sec for light check...");
delay(5000);
checkLightAndStart();
}