DEV Community

Srijan Singh
Srijan Singh

Posted on

Two small systems that taught me real-world engineering better than any job ticket

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:
    1. Sales: For generating new invoices.
    2. 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.

e-Paper Reader Display
Sales UI
Collection UI

Top comments (0)