Back to all posts
5 min read

I Built a Tiny Reddit Terminal on ESP32 (Because Why Not?)

ESP32 Reddit Terminal Hardware IoT Go Side Project
I Built a Tiny Reddit Terminal on ESP32 (Because Why Not?)

I Built a Tiny Reddit Terminal on ESP32 (Because Why Not?)

Remember when I got that ESP32 working and managed to display “FINALLY!” on the screen? Well, I got bored of staring at that one word, so I did what any reasonable person would do: I made it show Reddit posts.

Yeah, I know. Could have just used my phone. But where’s the fun in that?

The Idea

So there I was, with a working 1.9-inch LCD screen, thinking “what if I could scroll through r/Morocco on this tiny thing?” And honestly, once that thought hits your brain, you kind of have to do it. It’s the law of side projects.

The concept is simple: ESP32 shows the latest Reddit posts from a subreddit, you press the boot button to read the full post, press again to scroll through it, and when you reach the end, it goes back to showing the next post. Like a Reddit terminal from 1985, but with worse resolution.

The Setup Dance

Here’s the thing about making hardware talk to software: it’s basically a game of telephone between your ESP32, a USB cable, and a Go server running on your computer.

The flow goes like this:

  1. ESP32 wakes up and says “hey, give me a Reddit post”
  2. Go server fetches something from Reddit
  3. Go server sends it through the USB cable
  4. ESP32 displays it on the tiny screen
  5. You press the boot button
  6. ESP32 asks for the full text
  7. Repeat until you’ve wasted enough time

Simple, right? Well, kind of.

The Serial Communication Headache

First problem: how do you send text from your computer to the ESP32? Serial communication, obviously. But here’s where it gets fun.

You can’t just throw paragraphs of text at the ESP32 and hope it works. Newlines break everything. So in the Go server, I had to do this weird thing where I replace every \n with [NL] before sending it. Yeah, I’m literally sending the text “[NL]” instead of actual newlines.

content = strings.ReplaceAll(content, "\n", " [NL] ")

Is it elegant? No. Does it work? Absolutely.

The Go server listens for commands from the ESP32. When it sees “REQUEST_LATEST”, it grabs a Reddit post and sends back something like:

LATEST:Morocco|Cool post title here|username|42

That pipe-separated format? Peak engineering right there. CSV files everywhere are jealous.

Two Display Modes

The ESP32 has two modes because I couldn’t decide which one I liked better, so I just made both.

Mode 1: Latest Posts

This is the default mode. The screen shows you the latest post from your chosen subreddit with the subreddit name in orange at the top (because orange is the Reddit color and I’m committed to authenticity on my 1.9-inch screen). Below that, you get the post title in big white text, then the username and score in smaller gray text. At the bottom, there’s a helpful reminder that says “BOOT: read full text” because I will 100% forget which button does what.

Mode 2: Full Post View

Press the boot button and boom, now you’re reading the full post. The subreddit stays at the top, but everything else is the actual post content in bigger text. Press the boot button again and it scrolls down through the post. The screen shows you a scroll progress indicator so you know how far through you are. When you hit the end and press the button again, it takes you back to mode 1 and shows you the next post from the subreddit.

The Word Wrapping Problem

Here’s something I didn’t think about until it broke: word wrapping. You can’t just dump text onto a tiny screen and hope it figures out where to break lines.

I had to calculate how many characters fit per line based on the screen width and font size, then manually break the text at the right spots. It’s basic math, but when you’re dealing with pixels and trying to account for padding, it feels like you’re doing rocket science.

int maxChars = (screenWidth - 2 * PADDING) / charWidth;

Every time the text needs a new line, the cursor moves down by the line height. When it hits a [NL] marker (remember those?), it also makes a new line. This is how we recreate paragraphs on a screen the size of a postage stamp.

Things That Went Wrong

The Port is Busy Error

This one drove me nuts. You can’t upload code to the ESP32 while the Go server is connected to the same USB port. You also can’t run the Go server while the serial monitor is open. Basically, everything wants exclusive access to that USB port, and they all fight about it.

Solution? Close everything, upload the code, then start the Go server. Every. Single. Time.

Memory Issues

The ESP32 doesn’t have infinite memory (shocking, I know). At first, I tried to render all the text at once and the thing just gave up. Had to switch to using sprites and only rendering what’s actually visible on screen.

Button Debouncing

Turns out buttons are noisy. Press it once, and the ESP32 thinks you pressed it 47 times. Had to add a 50ms delay after each button press to ignore the bouncing. Now it works like a real button should.

The Result

Now I have this weird little device that shows me Reddit posts on a screen smaller than a credit card. Is it practical? Absolutely not. Can I read r/Morocco posts on it while my laptop is right next to me? Yes, and I do.

The whole project is up on GitHub at tiny-reddit-terminal if you want to build your own tiny Reddit reading experience.

What I Learned

Building this taught me more about serial communication than I ever wanted to know. Also, working with hardware makes you appreciate how spoiled we are with regular software development. No segmentation faults in JavaScript, you know?

The ESP32 is honestly amazing for these kinds of projects. You get WiFi, Bluetooth, a bunch of GPIO pins, and enough processing power to do actually useful things. Or in my case, completely useless but entertaining things.

Next up? Maybe connecting it to WiFi so it can fetch Reddit posts directly without needing the Go server. Or maybe I’ll just stare at it scrolling through posts for another week. Both are equally likely.