What I wanted to learn, and why it interested me: I wanted to learn how to use a thermal printer as a physical data logging device. I was interested in this because it creates a real-world record of sensor data. The printed paper tape is a permanent log you can hold and annotate.
Final outcome: I used a potentiometer as an analog input, with one button to start/stop the logging and another to stamp a manual marker on the tape at any moment. The thermal printer printed the raw sensor value, and calculated voltage once per second on a continuous paper tape. One button toggled the logging on and off, while the other stamped a manual marker line on the tape, allowing me to annotate specific moments when I adjusted the potentiometer.
Images of final creative/exploratory output
Pressing the start button triggers the thermal printer to log real-time potentiometer readings onto a paper tape every second. The second button stamps a manual marker at any moment, and pressing stop ends the session — leaving a permanent physical record of the data.
A printed paper tape showing real-time potentiometer readings logged every second
Process images from development towards creative/exploratory output
The full hardware setup
testing the printer connection with a "Hello World" output before building out the data logging functionality.
Process and reflection:
I started by wiring up the thermal printer to the Arduino and uploading a simple "Hello World" sketch to confirm everything was working. The baud rate had an issue, my printer needed to be set to 9600 (not 19200), which I only figured out through trial and error. This taught me that even when following official documentation, hardware can behave differently and you have to be willing to experiment with the settings. I also learned how to use a DC barrel jack adapter to connect the 9V power supply cleanly to the printer, which made the whole setup more stable. Once everything was running, I added the potentiometer and two buttons — one to start/stop logging and one to stamp a manual marker on the tape. Turning the potentiometer and watching the voltage sweep from 0.00V to 5.00V print out in real time was satisfying. The biggest takeaway was that hardware rarely works exactly as documented, and debugging is just part of the process.
Technical details
Electrical schematic: a 10kΩ potentiometer connected to A0 for analog input, two buttons on pins 4 and 5 with pull-up resistors, and the thermal printer connected via SoftwareSerial (pins 2 and 3) powered by a separate 9V supply with shared ground.
/*
60-223 Intro to Physical Computing, spring 2026
Domain-specific Skill Building exercise: Thermal Paper Data Logger
This sketch uses a thermal printer as a real-time data logger.
A 10k ohm potentiometer connected to A0 serves as the analog input source.
Button A (pin 4) toggles logging on and off, causing the printer to output
a timestamp, raw sensor value, and calculated voltage once per second.
Button B (pin 5) prints a manual marker line on the tape at any moment.
The printer is driven via SoftwareSerial on pins 2 and 3, powered by a
separate 9V supply.
Pin mapping:
Arduino pin | role | details
--------------------------------
2 output SoftwareSerial RX (to printer TX)
3 output SoftwareSerial TX (to printer RX)
4 input momentary button A (start/stop logging)
5 input momentary button B (manual mark)
A0 input potentiometer (analog sensor)
Released to the public domain by the author, Feb 2026
Coral Zhu,xiangcuz@andrew.cmu.edu
*/
#include "Adafruit_Thermal.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
Adafruit_Thermal printer(&mySerial);
const int btnA = 4; // start/stop logging
const int btnB = 5; // manual mark
const int potPin = A0; // potentiometer
bool logging = false;
unsigned long lastPrintTime = 0;
const unsigned long interval = 1000;
bool lastBtnAState = HIGH;
bool lastBtnBState = HIGH;
void setup() {
mySerial.begin(9600);
printer.begin();
pinMode(btnA, INPUT_PULLUP);
pinMode(btnB, INPUT_PULLUP);
printer.println("== Logger Ready ==");
printer.println("Press A to start.");
printer.feed(1);
}
void loop() {
bool btnAState = digitalRead(btnA);
bool btnBState = digitalRead(btnB);
// button A: toggle logging on/off
if (btnAState == LOW && lastBtnAState == HIGH) {
delay(50); // debounce
logging = !logging;
if (logging) {
printer.println("-- LOG START --");
printer.print("Time(ms) | Sensor");
printer.println(" | Voltage(V)");
} else {
printer.println("-- LOG STOP --");
printer.feed(2);
}
}
// button B: print a manual marker line
if (btnBState == LOW && lastBtnBState == HIGH) {
delay(50); // debounce
printer.print("*** MARK at ");
printer.print(millis());
printer.println(" ms ***");
}
// print data once per interval
if (logging && millis() - lastPrintTime >= interval) {
int raw = analogRead(potPin);
float voltage = raw * (5.0 / 1023.0);
printer.print(millis());
printer.print(" | ");
printer.print(raw);
printer.print(" | ");
printer.print(voltage, 2);
printer.println(" V");
lastPrintTime = millis();
}
lastBtnAState = btnAState;
lastBtnBState = btnBState;
}