Post

E-Paper Calendar V2: Directing AI to Assemble the Puzzle

E-Paper Calendar V2: Directing AI to Assemble the Puzzle

This article is migrated from Medium and translated by Gemini pro 2.5.


(The following article was generated by Gemini 2.5 Pro, with some human intervention and adjustment, of course.)

It’s been a while since my last update. This was partly due to some health issues, and… well, I have to admit, partly due to laziness. So, the e-paper calendar project was put on hold for a bit.

But this “rest” period wasn’t without its silver linings. During this time, great new tools have been released, especially the gemini-cli command-line tool. For me, it’s a developer’s godsend. It has massively boosted my productivity, allowing me to focus more on high-level thinking like “What do I want to build?” (product design, flow planning) and hand off many of the tedious “How to implement it” details to Gemini for assistance.

A New Strategy: Leveraging Playgrounds and Modularity

To make the development process more organized, I’ve adopted a multi-project Workspace structure. In this workspace, the final product project, the playground (for testing individual functions), and the third_party libraries are all placed at the same level, each independent.

My workspace folder structure looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
- E-Paper-Calendar-Workspace/
  |
  |-- epaper_main_project/      <-- Final integrated product code
  |   |-- main/
  |   `-- components/
  |
  |-- playground/               <-- Isolated test projects for each feature
  |   |-- 01_epaper_driver_test/
  |   |-- 02_wifi_manager_test/
  |   `-- 03_ds3231_deepsleep_test/
  |
  `-- third_party/              <-- For external libraries
      `-- some_awesome_library/

I prioritize tackling the parts with the “highest risk” or “most uncertainty” first. I create a separate ESP-IDF project for them in the playground to develop and validate. For example, driving a specific e-paper model or handling a complex network protocol. By cracking these tough nuts first, I have more confidence in the final integration.

This approach has several obvious benefits:

  • Reduced Complexity: In a standalone playground project, I only need to focus on the one problem I’m currently solving, without worrying about its interaction with other modules. The environment is much simpler.
  • More Efficient Debugging: When a small feature fails in an isolated environment, the scope of the problem is tiny. Debugging is fast and precise.
  • Improved Code Reusability: Each component is a module with high cohesion and low coupling. In the future, it can be easily transplanted into other projects.

The Unexpected Spark: Modularity and AI Collaboration

And this development strategy, after introducing gemini-cli, has produced an unexpected chemical reaction. It perfectly solves the biggest pain point of collaborating with AI today: AI’s context memory limitation.

We all know that AI can’t remember all the details of a massive project. If you throw the entire project’s codebase at it and ask it to modify one small part, it will likely generate code that’s incompatible with other parts, or it will have completely “forgotten” your overall architecture.

My “modular development” approach solves this problem perfectly:

  • Provides Focused Context: When I’m working on a component in the playground, the context I provide to Gemini is only that isolated, complete module. For example, when I ask it to “help me write an alarm-wakeup function for the DS3231,” I only need to give it the relevant I2C and Deep Sleep code. It can then produce a highly accurate and high-quality implementation.
  • Massively Improves AI Output Accuracy: Because the context is clean and the goal is specific, the AI isn’t confused by other unrelated code in the project, which greatly increases the correctness of its output.
  • Establishes “Breakpoints” for Problem-Solving: This method is like setting several “breakpoints” in the entire development flow. I can ensure that each individual component (puzzle piece) is functional. When it’s finally time to “assemble” all the pieces, if I encounter a problem, I can confidently check the “interface” between the modules, rather than doubting the functionality of the modules themselves.
  • AI as the Best Assembler: After all the components are verified, I can even ask Gemini to reference these independent modules and “help me write a main.c to connect the Wi-Fi, RTC time reading, and ICS parsing functions.” AI performs exceptionally well at this kind of “assembly” task.

Wild Ideas for Future AI Collaboration

This experience also gave me some crazier ideas about future development models.

Since modularity allows me to work efficiently with one AI assistant, what if I plan the project even better, defining the input, output, and interface for each component? Could I then, like a project manager, “assign” several Gemini colleagues to develop different components simultaneously?

For example, one AI focuses on the e-paper driver and LVGL rendering, another specializes in networking and ICS parsing, and a third concentrates on low-power and RTC wakeup.

In this model, my role shifts from an engineer buried in code to that of a manager and architect. My main tasks become: defining requirements, drawing module boundaries, and providing key guidance and troubleshooting when one of the AI colleagues gets “stuck.”

Thinking even further, maybe in the future there will even be a high-level “AI Project Manager” or “AI CTO.” It would be responsible for understanding my final product goal, then automatically breaking down and assigning tasks to the “AI engineers” under it, and overseeing the integration progress.

When the development process evolves to this point, I suddenly start to wonder: “…what’s left for me to do?”

Perhaps, by then, the core value of human developers will be only those most original, most ambiguous, and least quantifiable things: creativity, taste, an intuition for user experience, and the passion to just “build cool stuff.”

The Puzzle Pieces Are Ready: Core Functions Verified

As I mentioned, I’ve used this strategy to successfully complete the independent verification of most of V2’s core functions in the playground. These important “puzzle pieces” include:

  • E-Paper Driver: Successfully driving the Waveshare 7.5-inch monochrome e-paper display.
  • LVGL Mandarin Font Test: Verified that using the LVGL graphics library with a custom Mandarin (Chinese) font file to display text is feasible.
  • Wi-Fi Setup: Completed the SoftAP provisioning function, allowing users to configure Wi-Fi via a webpage.
  • RTC and Deep Sleep: Integrated the DS3231 high-precision real-time clock and successfully implemented waking the ESP32 from Deep Sleep via an alarm interrupt.

With these verified puzzle pieces, we can finally start assembling them to complete the first usable version of V2!

As I write this, my workflow is the best embodiment of this new model. I’m looking at one terminal window, letting gemini-cli follow my instructions to “assemble” the independent Wi-Fi, RTC, and ICS parsing modules into the main project, while I handle the final compilation and integration problems.

In another window, I’m interacting with the Gemini chat interface, asking it to help me organize these development logs and thoughts into the blog post you’re reading right now.

And behind these two tasks, my brain isn’t idle either—it’s planning the product’s next steps and the feature roadmap for after these modules are integrated. This is a new, multi-tasking development experience. Productivity is way up, and it feels pretty good.

This post is licensed under CC BY 4.0 by the author.