|
| 1 | +--- |
| 2 | +title: 🟦 lcd marquee |
| 3 | +slug: lcd-marquee |
| 4 | +date: "2026-03-16" |
| 5 | +topic: coding |
| 6 | +tags: ["hardware", "pi"] |
| 7 | +--- |
| 8 | + |
| 9 | +After getting into electronics a few weeks ago, I set out to build my first _real project_. I wanted something that had both a hardware component, as well as a web application to go along with it. I landed on the idea of a real time scrolling LCD message board. |
| 10 | + |
| 11 | +## 📋 project planning |
| 12 | + |
| 13 | +The goal of the project was to have an LCD screen that displayed messages in real time as users sent them to me. There would be a web application with a form that allows users to submit messages. I also wanted the web application to be real time as well, so it should also be able to receive and display the same messages as the LCD. |
| 14 | + |
| 15 | +## ⚡ hardware and microcontroller |
| 16 | + |
| 17 | +Starting with the hardware, I hooked up the [LCD screen][lcd] to my [Raspberry Pi 5][pi]. Even though the LCD had many inputs and outputs, the module I used simplified the connection to only four wires. |
| 18 | + |
| 19 | +![lcd marquee][circuit-diagram] |
| 20 | + |
| 21 | +With just a few [lines of python][scroll-message] I had text scrolling across the screen. If you're interested in the full source code, you can find it in my [lcd-marquee-pi][lcd-marquee-pi] repository. |
| 22 | + |
| 23 | +## ⏱️ realtime |
| 24 | + |
| 25 | +Now came the interesting part, setting up some sort of real time system to accept and deliver messages. Apparently in the IoT world there is a standard for this kind of stuff called [MQTT][mqtt]. Many hosts implement these protocols, so I went with [HiveMQ][hive-mq] to set up the MQTT service. |
| 26 | + |
| 27 | +The setup was super quick from the HiveMQ dashboard. The next step was implementing clients for both the JavaScript web application and the Python running on the microcontroller. Luckily there are libraries in both languages for MQTT that were easy to configure. |
| 28 | + |
| 29 | +![hivemq console][hivemq-console] |
| 30 | + |
| 31 | +I was able to test the server and client setup from the HiveMQ console, making it very easy to confirm that my code was listening to messages properly. |
| 32 | + |
| 33 | +## 🌐 web application |
| 34 | + |
| 35 | +The web application was the part of the project that I was most comfortable working with. I spun up a quick [react-router][react-router] application and hosted it on [Cloudflare][cloudflare]. I wanted it to have a unique look and feel, so I recreated the LCD screen with a [custom font][lcd-dot-matrix] to make it feel real. |
| 36 | + |
| 37 | +![lcd marquee][lcd-marquee] |
| 38 | + |
| 39 | +At its core, the web application is a simple form that submits messages and sends them off to the MQTT server. However, the MQTT client implementation wasn't as straightforward here. Because the web application is running as a [Cloudflare Worker][worker], I had to use a [Durable Object][do] to listen to the MQTT server and send WebSocket messages to the browser. |
| 40 | + |
| 41 | +You can check out the full source code in my [lcd-marquee-web][lcd-marquee-web] repository. |
| 42 | + |
| 43 | +## 🏰 architecture |
| 44 | + |
| 45 | +The overall architecture looks something like this. [HiveMQ][hive-mq] is at the center of it all. The browser acts as a publisher as well as a subscriber. The microcontroller acts only as a subscriber. There is an extra Durable Object in the mix to handle the real time communication between the MQTT server and the browser via WebSockets. |
| 46 | + |
| 47 | +![lcd marquee architecture][lcd-marquee-architecture] |
| 48 | + |
| 49 | +While it may have been simpler to host on a long running [Node][node] server somewhere, I've been really loving the flexibility of deploying to [Cloudflare][cloudflare] lately. |
| 50 | + |
| 51 | +## 📢 message me |
| 52 | + |
| 53 | +This project is fully up and running! Send me a message from this link. |
| 54 | + |
| 55 | +https://lcd.bradgarropy.com |
| 56 | + |
| 57 | +You'll even be able to see what other people are sending me as well! |
| 58 | + |
| 59 | +[lcd]: https://sunfounder.com/products/i2c-lcd1602-module |
| 60 | +[pi]: https://amzn.to/4lRn82t |
| 61 | +[circuit-diagram]: https://res.cloudinary.com/bradgarropy/image/upload/bradgarropy.com/posts/lcd-circuit-diagram.png |
| 62 | +[scroll-message]: https://github.com/bradgarropy/lcd-marquee-pi/blob/main/lcd_marquee.py#L37-L54 |
| 63 | +[mqtt]: https://mqtt.org |
| 64 | +[hive-mq]: https://hivemq.com |
| 65 | +[hivemq-console]: https://res.cloudinary.com/bradgarropy/image/upload/bradgarropy.com/posts/hivemq-console.png |
| 66 | +[react-router]: https://reactrouter.com |
| 67 | +[cloudflare]: https://cloudflare.com |
| 68 | +[lcd-dot-matrix]: https://fontstruct.com/fontstructions/show/142810/lcd_dot_matrix |
| 69 | +[lcd-marquee]: https://res.cloudinary.com/bradgarropy/image/upload/bradgarropy.com/posts/lcd-marquee.png |
| 70 | +[lcd-marquee-architecture]: https://res.cloudinary.com/bradgarropy/image/upload/bradgarropy.com/posts/lcd-marquee-architecture.png |
| 71 | +[lcd-marquee-pi]: https://github.com/bradgarropy/lcd-marquee-pi |
| 72 | +[lcd-marquee-web]: https://github.com/bradgarropy/lcd-marquee-web |
| 73 | +[worker]: https://workers.cloudflare.com |
| 74 | +[do]: https://cloudflare.com/developer-platform/products/durable-objects |
| 75 | +[node]: https://nodejs.org |
0 commit comments