Illya Moskvin

Handing off an RFID nametag printer

Photo of the nametag printer before hand-off

This is a story about handing off a passion project that started to feel like a burden. This is a familiar experience for many creatives, especially in open source communities. The emotions it stirs up are complicated and worth unpacking.

This is also a story about scope creep. When AI lowers the barrier to implementation, knowing what’s worth doing and when to call something done is more important than ever. Burnout is real and “why not” is a trap.

Before we get into it, here’s the code for this project:

https://github.com/IllyaMoskvin/nametag-printer

For about six months in 2025, I volunteered as the Public Relations Officer at Pumping Station: One, our local hackerspace. The role demanded more than I could give: attending events, conducting outreach, making promotional materials, forming a team, creating new systems, and drumming up internal support for them. I burned out fast. I have regrets about not doing more, but the fact that the organization has not attempted to refill the role in seven months feels validating. It’s too much for one person.

One of the projects I started during that time was a nametag printer. The idea was simple: a member taps their RFID badge, we look up their info in the member system, and print a friendly little branded nametag for them to wear. It was meant to promote approachability—important for an organization that’s recently crossed 700 members.

I bought a used Brother QL800 thermal printer, taped a Raspberry Pi 4 Model B (1 GB) and a 125Khz EM4100 USB RFID ID Card Reader on it, and got a prototype working in a weekend:

This was the first project where I used AI to help write code. I remember “vibe coding” the make_image function responsible for generating the nametag image using PIL. I still have the original chat, which began like this:

  1. I need to generate a nametag using the provided name and the PIL library. It has to be 954 by 672. Rotate it 90 degrees before returning.
  2. Selected code contains deprecated functions. Fix it.
  3. AttributeError: ‘FreeTypeFont’ object has no attribute ‘getsize’
  4. this text is tiny. why is it so small? make it like much much bigger
  5. add black bars at the top and bottom of the image, similar to how a nametag would look. at the top, add two lines of text, “Hello” and “my name is” with hello being much larger than my name is but smaller than the name itself

Followed by some pixel pushing and iteration:

  1. the “hello” and “my name is” texts are running into each other. expand the top bar to create space, and give more room between the two texts
  2. refactor text positions and black bar heights into variables up top
  3. dynamically adjust font size of the name to fit really long names
  4. center the name within the white space rather than within the whole nametag
  5. add code here to draw ps-1-logo-clean-white.svg (a small logo) in the top black bar, one small logo in each of the corners, slightly inset

…and so on. I realize this level of detail might seem mundane—like describing how one moved blocks of code around or tightened screws. It feels like table stakes now. But this was my first taste of AI-assisted coding, and at the time, it felt like magic.

Photo of a finished nametag showing my name

It was intoxicating to realize that the code I had expected to take a week of tinkering would be finished in a matter of hours. This created room for scope creep. I added an integrated webserver to print custom nametags, with non-members in mind.

Screenshot of the nametag webform

Then, I started thinking about deployment and security, both in terms of physical and digital. The webserver would have to be open to the internet, so that visitors could just scan a QR code and be taken to the form without having to join PS:1’s WiFi. But what if a bad actor got access to the printer remotely?

Well… I had an idea for how to mitigate that what-if, and with the barrier to implement new code being so low, why not try it, right?

Screenshot of a prompt for appending an access key to the webform URL. Transcript: I need to make this form more secure. I have an idea about how to do it. I want to append a code to the URL, and only have the form show when there is a valid code attached. The code remains valid until it is used to print. After it is used to print, it expires within 15 minutes (unless it is already in the process of expiring). Once a code is used to a print, a new code is generated. There should be some sort of database that keeps track of these codes and their expiration time. Only accept a code if it has not expired yet. Feel free to use sqlite or even a csv file. Whatever makes sense.

We would append a random access key to the URL, and only allow access to the form if the key was valid. We’d expire the key shortly after it was used to print, so that attackers only had a limited time window to abuse the form.

The code the AI generated to do this worked, with minimal iteration.

But now, I had to figure out a way to show a dynamic QR code. I couldn’t just print it. That sounded like a great opportunity for more tinkering! So I generated more code to generate the QR code. I bought a Waveshare 4.2" e-ink display module and generated code to draw the QR code to it. I figured out the cable routing. I designed a complex laser-cut mount for all the printer parts.

Then, I burned out on this and everything else related to PS:1.

Collage of CAD model, draft poster design, RPi wiring, and e-ink display. In the bottom-left corner, there’s a dove emoji next to some text, which reads “In Loving Memory Of: Features No One Asked For; April 3, 2025 – Nov 22, 2025”

A few months later, someone I respected at PS:1 reached out and asked if I’d be down to share any work relating to the printer. I said, sure, it’s like 80-90% done, but it’ll take me a few days to get it to a hand-off-able place. They said, hey, if I just want to zip up what I have it’s cool. No reason to do more work just for them. I said, no worries, and did that work anyway.

It felt good to have a deadline. It enabled me to accept that the dynamic QR code and complex mount design were out-of-scope. It forced me to prioritize the code and deployment workflow, rather than the physical build. It made me realize how much work was left on the software side that I’d neglected—even with AI assistance, it took four evenings to finish the project. It also made me appreciate how much I learned in the intervening six months. I won’t dive into the software details here, but the repo has everything if you’re interested.

Regarding the physical build, I decided to mount the printer to a wooden backboard. My primary concern was to stabilize the connector end of the extension cord. I designed a connection enclosure box to solve the issue.

Model of the connection enclosure

I had plenty of spare wood and wipe-on poly. With the connection box printed (first try), it only took an evening to do the build.

Photos showing assembly of the new build

I delivered it as a complete unit, mounted and ready to deploy. The software was polished and documented, complete with an Ansible-based deployment workflow and some developer niceties.

Why couldn’t I just hand off what I had before? Part of it was professional pride: I’m a software developer, and delivering unfinished work feels unprofessional, even for a volunteer project. I’ve been on the receiving end of rough handoffs before. I also know that if someone handed me a half-working side-project, especially on the software side, I’d be tempted to start from scratch—and knowing myself, it might never get finished. Given how much thought I’d already sunk into this, I wanted to lower the barrier to deployment as much as possible.

I had preconceived notions about where the printer would live. One of my PR initiatives was beautifying the community Lounge, which served as the gathering place for weekly tours. I thought it might be good to have more projects showcased there for prospective members to explore while waiting. I designed the printer to be a self-contained, hackery-looking project—something folks could poke at and maybe find inspiring.

Photo of the lounge after major clean up

The person I handed it off to had other ideas. Their priority for it was to let members learn the names of other members, and not just have everyone be a stranger. They wanted it mounted near the entrance, so it’s one of the first things people see. They also planned to put it in an alcove. I wasn’t aware of this until after I’d finished the mount.

One day in early February, I walked into PS:1, and there it was:

Photo of the printer in context near the entrance

When I finally saw it deployed, I had mixed feelings: happy that it was in a prominent position, skeptical that it was below eye level, impressed that the wall cut-out plan worked, appreciative of all the new informational signage. “Please post bills” is a great trick to discourage people from stacking stuff in walkways, noted. I loved that they kept my silly “plz no hak uwu” sticker on it, too.

Later that evening, I found the discarded base of the printer upstairs, tucked away in a corner by the restroom.

Photo of the discarded base

Two weeks later, I got the notification:

Screenshot of a notification showing that I’ve been removed from the Pumping Station: One NFP organization on GitHub

Well, that’s a wrap. What else is there to say?

I felt foolish for spending so much time thinking about the physical arrangement. A little dismissed that the hardware aspect was discarded so easily. Peeved that I was no longer needed? Relieved to have one less obligation.

Photo of the deployed printer close up

But mostly, I was thrilled. I tapped my RFID badge, and out came my nametag. My project was disassembled, but in the process, it became part of the space. This was the first time I’d handed off a passion project and other people actually built on it—because they wanted to, not because they were paid to.

I wish I’d communicated with others interested in the printer sooner to establish needs. I want to get better at prioritization for non-work projects. I want to hand off more projects. Because the more projects I can hand off, the more projects I get to do.