This show has been flagged as Clean by the host.
Hello, again. This is Trey.
Welcome to part 8 in my Cheap Yellow Display (CYD) Project series.
If you wish to catch up on earlier episodes, you can find them on my HPR profile page https://www.hackerpublicradio.org/correspondents/0394.html
It is hard to believe that I started this project and the HPR series to document it more than a year ago. Time flies. Life happens. I spent the last 8 months so focused on work related activities that I had to set the project aside. And once I set it aside, it was difficult to get back to again. The one time I tried, I found that my son's old Windows laptop, which I had commandeered to use for the project, was once and truly dead.
We live in a different world now than we did when I began this project. Today, everything is about AI – how it is changing our world, increasing efficiencies, and even displacing certain types of jobs. "Vibe coding" is transforming the way we make software, and now everyone is a developer.
Within my organization, we are all being strongly encouraged to learn more about AI and apply it in our daily work. We are blessed to have access to a wide range of training and to powerful tools which support the process. Several colleagues within my organization and outside my organization have recommended Claude Code -- for development, for organization, for brainstorming, and for much more. My role is not that of a developer, and I have had no need for Claude Code at work. There are plenty of other tools for me to use.
But at home, I thought... I could install Claude Code at home to experiment with and to learn. And then it hit me. I wonder if I could use Claude Code to help me with my stalled CYD project.
"Hello, my name is Trey, and I am a fraud."
OK. I don't think I am a fraud, but having never used such a powerful tool to help me code, I feel a little bit like a fraud, with Claude doing the work for me. Let's talk through what we did.
As I mentioned, I was unable to use the laptop on which I created the original GUI code. But no worries, because It was all on GitHub, right?
So, I began by trying to install Claude Code on one of my Ubuntu machines. That failed miserably, and all the instructions I found online recommended running it on Windows. So I transitioned to installing Claude Code on a freshly built Windows 10 system using some old hardware which will not support Windows 11. Surprisingly, It seems that Claude wants to run within Ubuntu on Windows Subsystem for Linux (WSL).
Once I went through all the hoops for installing and setting up my basic subscription, I got to work. I created a new directory to use for all my project files, and another one for Claude to write all its output files to.
Everything I have read and heard about using Claude Code for a project like this recommended beginning by using Claude to create the project plan. So my first prompt was as follows:
"I am building a project using an ESP32 cheap yellow display. The final goal is to have a device with a graphical user interface which will allow me store several text messages, each assigned to their own specific button. Then, when one of the buttons is pressed, the message will be converted into morse code, and the message will be sent by blinking an onboard LED. I already have the initial design for the GUI coded in my github repository. Please construct a detailed step by step plan for building this application"
I wanted to keep it simple at the beginning, so even though I plan to use an opto-isolated relay for the output, I am starting out using the built in LED.
Claude asked me for the URL for my Github repository, and I provided it. After thinking for a bit, it produced a project plan.
CYD Morse Sender — Step-by-Step Build Plan
What You Already Have
- 3 fully designed LVGL screens (Send, Config, Keyboard)
- 7 send buttons with green styling on the Send Screen
- Speed slider (5–30 WPM) and program slot dropdown on Config Screen
- Text area + LVGL keyboard widget on Keyboard Screen
- Display driver and touchscreen hardware initialized (but touch read was stubbed out)
---
Phase 1: Fix Touchscreen Input
Initialize the XPT2046 on VSPI, replace the hardcoded touched = false with real touch data, calibrate raw ADC coordinates to screen pixels, and verify all three nav buttons transition screens correctly.
Phase 2: Persistent Message Storage
Use Preferences.h / NVS to store 7 messages ("msg0" – "msg6") that survive power cycles. Load on boot and populate send button labels.
Phase 3: Config Screen — Slot Selection & Speed
Wire the Program dropdown to g_selectedSlot, wire the Speed slider to g_wpm with a live WPM label, and wire the Set button to clear the text area and navigate to the Keyboard Screen.
Phase 4: Keyboard Screen — Capture and Save Text
On keyboard OK (LV_EVENT_READY): read the text area, save to NVS, update the send button label, navigate back. On Cancel: navigate back without saving.
Phase 5: Morse Code Engine
Build morse.h with the full A–Z / 0–9 lookup table, a textToMorse() converter, and Paris-standard timing (unit_ms = 1200 / wpm).
Phase 6: Non-Blocking LED Transmission
State machine (IDLE / LED_ON / LED_OFF) driven by millis() in a morseUpdate() function called every loop — no delay(). LED on GPIO 17 (blue).
Phase 7: Wire the Send Buttons
Each button calls startMorse(getMessage(slot)) if not already transmitting. Disable all send buttons during TX; re-enable when the state machine reaches the end.
Phase 8: Integration & Polish
Stop button, WPM persistence, empty-slot guard, serial debug output, final touch calibration, end-to-end test checklist.
---
Recommended order: Phase 1 → 2 → 7 (partial) → 5 → 6 → 7 (full) → 3 → 4 → 8
This was wild! Claude determined exactly how far along I was in the project, and also alerted me to the fact that the "touch read was stubbed out". Ugh. This means that the files I had uploaded to GitHub were my original GUI files (Episode 05 – HPR4532 - https://hackerpublicradio.org/eps/hpr4532/index.html ) and not the ones that I finally got working properly (Episode 07 – HPR4624 - https://hackerpublicradio.org/eps/hpr4624/index.html ). That was my own fault. Did I mention that I don't get Git? I REALLY need to learn to properly use Git!
But, we have a plan, broken down by eight numbered phases. And they seem to address all the functionality I wanted with a few additional things I had not thought about. Interestingly, even though these phases are sequentially numbered, Claud recommended that we approach them in a bizarre order: Phase 1 → 2 → 7 (partial) → 5 → 6 → 7 (full) → 3 → 4 → 8 .
Alright. Let's see what we can do. The first phase is to fix the touchscreen input.
Claude took me through it step-by-step, asking as it needed to read specific project files.
Finally, it wrote a new ui.ino code file to my speficied output directory for me to test. I copied it into the correct file location, said a quick prayer, compiled in Arduino IDE, and downloaded to the CYD.
Well, that is... interesting. The display looked nothing like it was supposed to. There were vertical green bars with smaller dashed green vertical stripes in them. I will include a picture in the show notes so that you can see what it looked like and why it was so difficult to describe.
I spent the next hour or so trying to explain what I was seeing to a chat bot. Claude recommended potential fixes which either did nothing or made the situation worse. I began questioning whether this was a good idea, how people actually gained efficiencies talking to a bot, and even several life choices.
Then I had a thought. I prompted Claude:
If I were to take a picture of the screen on the cheap yellow display and copy it into the output folder, would you be able to analyze it to better determine what is wrong and how to fix it?
Shockingly, Claude answered in the affirmative, and told me to copy the picture to the output folder and let it know when to proceed. It analyzed the picture and more of the supporting files it had copied from my GitHub, asking each time if it could access that file. It determined that my original code was written for a flavor of LVGL version 8 and I was now using LVGL 9.5.
It recommended changes, and then asked permission to make those changes, file by file. .h files & .c files, Finally, I just gave it permission to edit the files in the project folder without asking for permission for each file each time. Claude was still explaining each change, showing me exactly what would be changed, and asking for permission, so that I could review all of the changes. But now it was not asking additional permission to write to each of the impacted files.
Next, Code compiled and downloaded. Different screen, but not right. Again, I took a picture and gave it to Claude to analyze. So, Claude paused and altered the code to generate a specific test pattern overtop of the GUI.
The test pattern was supposed to cover the entire rectangular screen. But parts of the pattern were in a square on the screen and parts were not. Another photograph and analysis, told Claude that there were some rotation/screensize issues.
We repeated this several times. Some resulted in improvement, and others did not.
This is the point where I noticed something interesting. Not about Claude, specifically, or about the app. But I noticed something interesting about myself and about the process.
Previously, when I was working through some of these challenges without Claud, I found myself becoming more and more stressed, frustrated, and angry, until I found a solution. Then another problem would repeat the cycle. Success in the end was great, but the emotional extremes during the process were not always pleasant.
Now, I was effectively managing the project, and relaying information to the resource responsible for fixing the problems -- a very different experience.
But I also ran into another issue. Claude became absolutely certain that the problem revolved around the device not accurately knowing where the 4 corners of the screen were. But in reality, the output of the test pattern was rotated 90 degrees from the actual screen. It took several iterations of me insisting that the problem had to do with screen orientation and not corner coordinates. It was interesting to experience the tool doubling down on an obvious mistake, but we finally resolved that.
Again, while it was frustrating, it was much less stressful.
We proceeded to Phase 2: Persistent Message Storage where we ensured that the button labels on the send screen were stored in the devices persistent storage, so that, when they are edited to contain the message they should send, that information would survive a reboot.
Next, we combined elements of Phase 5: Morse Code Engine , Phase 6: Non-Blocking LED Transmission , and Phase 7: Wire the Send Buttons together. Building the morse code engine was an area I had been thinking about for a while. I already had working parts of something similar in the Arduino practice oscillator I have referenced a few times in this series. The code for the practice oscillator may be found on my GitHub, but it was all based on original code from jmharvey1, with my only contribution being making pin assignments variables so that the code could easily be ported to different devices.
So, I was happy that we were building the morse code engine directly. The code for it may be found in morse.h, which uses a constant character lookup table to define each character. Without any specific direction from me, Claude used the PARIS timing methods I have already described within Episode 6 of this series. It defines timing for DOT, DASH, LETTER_GAP, and WORD_GAP, and all are based on a simple calculation of 1200 ms / the number of words per minute (WPM) we wish to transmit.
Along the way, we discovered that, if we tried to use the delay() function, it would crash the program due to a conflict with the LVGL timer used for touchscreen inputs. Claude altered all the delays accordingly.
Then, Phase 3: Config Screen — Slot Selection & Speed allowed us to configure the WPM we wished to use in addition to selecting a specific Send button to reconfigure. This forced us to work on Phase 4: Keyboard Screen — Capture and Save Text which is used to type the entries for each Send button. At this point, I also decided that we would want to also use the Keyboard Screen to send ad hoc morse as we typed it.
During this phase we discovered several bugs which seemed to cause random freezes. Careful troubleshooting with messages output to the Arduino IDE's serial console helped us narrow down the causes and remedy them.
Finally all the tests worked and I am able to merrily pre-configure macro buttons with custom messages and use the CYD to send the morse code for those messages to the on-board LED at whichever rate I specify.
I have noticed in my presentation of this narrative that I repeatedly slip into the first person plural terms "we" and "us" instead of the first person singular terms "I" and "me". I have unconsciously personified Claud and recognized it as an integral part of my (formerly one person) development team.
I finally configured Claude to connect to my GitHub repo and upload all the files and documentation. We additionally created a CYD-Narrative.md file which describes in more detail all the work which was done on the project. I still do not 100% get git, but we are successfully using it.
You can find all these files in my GitHub repo ( https://github.com/jttrey3/CYD_MorseSender ) where they are shared under a GPL 3.0 license.
There are still several additional steps I plan to complete in the next few months.
1. I will be integrating an opto-isolated relay which will allow me to plug the device into the straight key input on any amateur radio. This will require a battery power source, charge controller, and more hardware.
If you can think of any additional features you would like to see integrated, please drop me an email using the address in my HPR profile.
I may also work with a friend to attempt to 3d print a case for the entire contraption, and I will be sure to record additional episodes sharing the process.
I have learned so much throughout this project, about the CYD, ESP32, GUIs, Claude Code, GitHub, and most of all, about myself.
Does using AI to develop this code make me a fraud? It still feels like it in some ways.
Does it make me more productive? ABSOLUTELY! I made consistent forward progress when I only had 30-60 minutes each day to work on it, and everything discussed in this episode was completed in less than a week. If I had been able to work on it for a few hours uninterrupted, it may have only taken me 3-5 hours.
Does it empower and inspire me to do more projects like this? 100% I feel like I had support working with me the whole way. I was less stressed overall, and it had less of an impact on the amount of and quality of time I spent with my family.
I will be wrapping up this series soon, without any more 6 month gaps, I hope.
Until next time...
Unless otherwise stated, our shows are released under a Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license.
The HPR Website Design is released to the Public Domain.