Over a two-week vacation, I worked on two projects:
- DIY e-paper reader
- Full-stack Excel-based invoicing app for my dad.
I started thinking I was smart enough to tackle the problems quickly. But every step humbled me from UX design to product thinking, hardware quirks, deadlines and real-world constraints.
These projects weren’t about "building something perfect." They were about the lessons in iteration, discovery and the countless blind spots I never knew existed.
DIY e-Paper Reader
Don’t buy a jet engine for a bicycle
- Hardware Restraint: I stuck to the philosophy of avoiding over-specification. There is no point in sourcing a "jet engine" (expensive, high-power components) for a "bicycle" (a simple e-reader). I chose a hardware stack that matches the actual utility of the project.
Iterative Buying vs. Over-Committing
- The Incremental Build: Instead of buying a massive kit of parts all at once and risking e-waste, I opted for an iterative approach. I built the project in stages, ensuring each component was viable before moving to the next.
Prototype-First Thinking
- Mix and Match: Rather than rushing to a final, permanent assembly, I stayed in the experimentation phase. Keeping the build as a prototype allowed me to swap parts and test different configurations without the commitment of a final enclosure.
The Hardware/Software Handshake
- Driver Hunting: One of the primary friction points was the "handshake" getting the software to communicate with the hardware. It involved a tedious process of finding the exact display drivers that play nice with specific e-paper panels.
Fragile Connectors & High-Stakes Resets
- Real Stakes: Dealing with paper-thin ribbon cables and delicate pins is nerve-wracking. Every hard pin reset requires extreme caution; one wrong move or a short circuit and you’ve "blown up" the hardware.
The ESP32 Memory Ceiling
- Cache Limits: I quickly hit the physical limitations of the ESP32’s 8MB cache. When rendering high-resolution text or complex layouts on e-paper, you hit that memory ceiling much faster than expected.
Creative Workaround: JIT Streaming
- Wireless Data Slicing: To bypass memory constraints, I implemented a Just-In-Time (JIT) approach. Instead of storing entire books on the chip, I stream text data wirelessly from a smartphone. The phone handles the heavy lifting and the reader acts as a lean, wireless display.
Future Ideas
- Dynamic Control: I plan to implement smartphone-controlled font scaling and transform the device into a dedicated "distraction-free" wireless display.
- Hardware V2: I’m looking at embedding a chip with dedicated external storage and adding physical "Next/Previous" buttons for a more tactile, standalone reading experience.
Full-Stack Excel Invoicing App
The Evolution: From WhatsApp to Custom App
- WhatsApp Bots = Bad UX: I initially took inspiration from airline-style WhatsApp bots. It turned out to be a nightmare; the options were too rigid and the user flow was clunky for complex invoicing.
- Google Forms = Data Mess: I tried a "quick and dirty" approach using Google Forms, but it lacked data normalization. It quickly became a graveyard of redundant entries and fragmented data.
The Solution: A Custom SaaS-Lite App
- The Multi-User Problem: Since my father and I both needed access from different devices, a local-only solution was out.
- Spreadsheet Backend: I settled on a SaaS-based architecture that uses Google Sheets as a cloud-hosted database—combining the flexibility of Excel with the accessibility of a custom web app.
Architecture: Sales vs. Collection
-
Defined Logic Flows: I split the application into two distinct user experiences:
- Sales: For generating new invoices.
- Collection: For tracking payments received.
- The Glue: A third logic flow bill generation connects the two. The app generates a sales bill and collections are recorded against that specific bill number to ensure the books balance.
Data Integrity: SSOT & Normalization
- Single Source of Truth (SSOT): To manage consumer data, I utilized a dedicated master sheet to store product and consumer information, ensuring each entry is associated with a single, unique identifier (UID).
- Relational Logic: I implemented auto-generated UIDs to act as foreign keys, linking the Invoice sheet to the Payment Ledger. This ensures data integrity by referencing UIDs rather than duplicating data, effectively eliminating redundancy.
Mobile-First Reality
- Integration Pain: Connecting a custom frontend to a spreadsheet backend without breaking the data structure was a constant battle of trial and error.
- Prioritizing Mobile: While it works on a desktop, I prioritized a responsive, mobile-first UI. In a real-world business environment, the primary use case is generating a bill or checking a collection status on the go.
Reflection
Both projects were messy, exhausting, and imperfect and that’s exactly what made them valuable.
They humbled me, exposed blind spots I didn’t know existed, and taught lessons in problem-solving, iteration and user-focused thinking. Even after "completion", improvement is limitless.
This journal isn’t about showing off what I built it’s about the growth, the mistakes and the mindset of learning through doing.
|
|
|
|
Top comments (0)