<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://cmwang.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://cmwang.dev/" rel="alternate" type="text/html" /><updated>2025-08-03T14:31:39+00:00</updated><id>https://cmwang.dev/feed.xml</id><title type="html">Chieh-Min’s Dev Lab</title><subtitle>Documenting my journey of building projects with AI - where code meets creativity and human ideas merge with artificial intelligence</subtitle><author><name>Chieh-Min Wang</name></author><entry><title type="html">DIY Smart CO2 Monitor Part 6: Custom PCB Design and Manufacturing</title><link href="https://cmwang.dev/2025/08/03/diy-smart-co2-monitor-part-6-custom-pcb/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 6: Custom PCB Design and Manufacturing" /><published>2025-08-03T08:00:00+00:00</published><updated>2025-08-03T08:00:00+00:00</updated><id>https://cmwang.dev/2025/08/03/diy-smart-co2-monitor-part-6-custom-pcb</id><content type="html" xml:base="https://cmwang.dev/2025/08/03/diy-smart-co2-monitor-part-6-custom-pcb/"><![CDATA[<p>After successfully miniaturizing our CO2 monitor with a 3D printed enclosure in <a href="/2025/07/24/diy-smart-co2-monitor-part-5-miniaturization/">Part 5</a>, it was time to tackle the final stage outlined in our original roadmap: <strong>Stage Three - Custom PCB &amp; Cost Optimization for Potential “Mass Production”</strong>. What I discovered during this journey was that custom PCB design and manufacturing is far more accessible and affordable than I ever imagined!</p>

<!--more-->

<h2 id="the-discovery-jlcpcb-and-the-modern-pcb-ecosystem">The Discovery: JLCPCB and the Modern PCB Ecosystem</h2>

<p>When I first outlined this project in <a href="/2025/05/31/diy-smart-co2-air-monitor/">Part 1</a>, I thought custom PCB manufacturing would be expensive and complex. After some research, I discovered <strong>JLCPCB</strong> - a game-changing service that offers:</p>

<ul>
  <li><strong>Custom PCB Manufacturing</strong>: Professional-grade PCBs at incredibly low prices</li>
  <li><strong>Bill of Materials (BOM) Management</strong>: They can source and purchase components</li>
  <li><strong>PCBA (PCB Assembly) Services</strong>: End-to-end assembly for complete prototyping</li>
  <li><strong>EasyEDA Integration</strong>: A free, web-based PCB design tool</li>
</ul>

<p>The combination of affordable manufacturing and accessible design tools has truly democratized hardware development for individual makers like myself.</p>

<h2 id="step-1-schematic-design-with-easyeda">Step 1: Schematic Design with EasyEDA</h2>

<p>The first step was creating a circuit schematic using EasyEDA, JLCPCB’s online PCB design tool. What impressed me most was how comprehensive their component library is - I could easily find all the components I was using:</p>

<ul>
  <li><strong>NodeMCU ESP32 Development Board</strong></li>
  <li><strong>SCD41 CO2/Temperature/Humidity Sensor</strong></li>
  <li><strong>SH1106 OLED Display</strong></li>
  <li><strong>Various connectors and passive components</strong></li>
</ul>

<p>The schematic design process was surprisingly intuitive. EasyEDA’s interface made it easy to:</p>
<ul>
  <li>Search for components in their extensive library</li>
  <li>Connect pins with simple click-and-drag operations</li>
  <li>Validate electrical connections and detect potential issues</li>
  <li>Add labels and annotations for clarity</li>
</ul>

<p><img src="/assets/img/smart_aq_part6/schematic.png" alt="Circuit Schematic Design" /></p>

<p>The schematic captures our refined design from the previous iterations, with all the lessons learned about power distribution, I2C connections, and proper grounding integrated into the layout.</p>

<h2 id="step-2-pcb-layout-and-routing">Step 2: PCB Layout and Routing</h2>

<p>Once the schematic was complete, EasyEDA’s most impressive feature came into play: <strong>automatic schematic-to-PCB conversion</strong>. With a single click, the tool generated an initial PCB layout with all components placed and basic routing suggestions.</p>

<p>While the auto-layout provided an excellent starting point, I still needed to make manual adjustments:</p>

<ul>
  <li><strong>Trace Routing</strong>: Ensuring signal traces don’t run too close to each other to prevent interference</li>
  <li><strong>Component Placement</strong>: Optimizing for both electrical performance and mechanical constraints</li>
  <li><strong>Ground Plane</strong>: Creating proper ground planes for stable operation</li>
  <li><strong>Via Placement</strong>: Connecting different layers efficiently</li>
</ul>

<p>The learning curve was gentle enough for a beginner like me, yet the tool provided professional-grade capabilities.</p>

<p><img src="/assets/img/smart_aq_part6/pcb_front.png" alt="PCB Front View" /></p>

<p><img src="/assets/img/smart_aq_part6/pcb_back.png" alt="PCB Back View" /></p>

<p>The final design achieved our goals of compactness while maintaining proper electrical design practices. The two-layer board keeps costs low while providing sufficient routing flexibility.</p>

<h2 id="step-3-manufacturing---surprisingly-affordable">Step 3: Manufacturing - Surprisingly Affordable!</h2>

<p>After finalizing the PCB design, I submitted it to JLCPCB for manufacturing. The pricing was genuinely shocking - in the best possible way:</p>

<p><img src="/assets/img/smart_aq_part6/pcb_price.png" alt="PCB Manufacturing Price" /></p>

<p><strong>Final Cost Breakdown:</strong></p>
<ul>
  <li>10 pieces of custom PCB</li>
  <li>Professional quality with soldermask and silkscreen</li>
  <li>International shipping included</li>
  <li><strong>Total: ~$4 USD</strong> (with new customer coupon)</li>
</ul>

<p>This price point makes experimentation and iteration incredibly accessible. Even if the first design had issues, the cost of multiple revisions would still be minimal.</p>

<h2 id="manufacturing-progress-and-delivery">Manufacturing Progress and Delivery</h2>

<p>After placing the order, JLCPCB provided regular updates on the manufacturing progress:</p>

<p><img src="/assets/img/smart_aq_part6/manufacturing_progress.png" alt="Manufacturing Progress Updates" /></p>

<p>The entire process from order placement to delivery took just <strong>4 days</strong> - remarkable considering this included:</p>
<ul>
  <li>Design review and validation</li>
  <li>PCB fabrication with multiple layers</li>
  <li>Quality control testing</li>
  <li>International shipping from China</li>
</ul>

<p>When the package arrived, I was impressed by the professional packaging and the quality of the finished PCBs:</p>

<p><img src="/assets/img/smart_aq_part6/received_pcb.png" alt="Received Custom PCBs" /></p>

<p>The manufacturing quality exceeded my expectations. The silkscreen was crisp, the soldermask was uniform, and the dimensional accuracy was perfect.</p>

<h2 id="assembly-and-testing">Assembly and Testing</h2>

<p>With the custom PCBs in hand, it was time for the moment of truth: soldering the components and testing functionality. Thanks to the improved layout and proper pad sizing, the soldering process was much more manageable than my earlier attempts in Part 5.</p>

<p>After carefully soldering each component:</p>
<ul>
  <li>ESP32 development board</li>
  <li>SCD41 sensor module</li>
  <li>SGP40 sensor module</li>
  <li>SH1106 display</li>
</ul>

<p>I flashed the same firmware we developed in previous parts and… <strong>it worked perfectly on the first try!</strong></p>

<p><img src="/assets/img/smart_aq_part6/confirmed_pcb_working.png" alt="Confirmed PCB Working" /></p>

<p>All sensors responded correctly, and the display showed proper readings The months of iterative development and testing with breadboards had paid off - the transition to a custom PCB was seamless.</p>

<h2 id="new-3d-printed-enclosure">New 3D Printed Enclosure</h2>

<p>With the custom PCB validated, I designed a new enclosure specifically tailored to its dimensions. Using the same OnShape CAD skills developed in Part 5, I created a much more compact design:</p>

<p><img src="/assets/img/smart_aq_part6/3d_printing_a_new_enclosure.png" alt="3D Printing New Enclosure" /></p>

<p>The new enclosure design benefits from:</p>
<ul>
  <li><strong>Precise Fit</strong>: Designed exactly around the PCB dimensions</li>
  <li><strong>Reduced Volume</strong>: Significantly smaller than the breadboard version</li>
  <li><strong>Improved Aesthetics</strong>: Cleaner lines and professional appearance</li>
</ul>

<h2 id="size-comparison-the-transformation">Size Comparison: The Transformation</h2>

<p>The difference between our original breadboard prototype and the final custom PCB version is dramatic:</p>

<p><img src="/assets/img/smart_aq_part6/compare_with_old_enclosure.png" alt="Old vs New Enclosure Comparison" /></p>

<p>The miniaturization achieved through custom PCB design represents roughly a <strong>60% reduction in volume</strong> while maintaining all functionality. This transformation demonstrates the power of moving from prototype to production-ready design.</p>

<h2 id="modules-vs-ics-understanding-the-trade-offs">Modules vs. ICs: Understanding the Trade-offs</h2>

<p>While this custom PCB represents a significant improvement, there’s still room for further optimization. Currently, I’m using <strong>pre-packaged modules</strong> rather than <strong>bare ICs</strong>:</p>

<h3 id="current-approach---using-modules">Current Approach - Using Modules:</h3>
<ul>
  <li><strong>ESP32 Development Board</strong>: Includes the ESP32-WROOM-32 module plus USB-to-serial conversion, voltage regulation, and breakout pins</li>
  <li><strong>SCD41/SGP40 Sensor Module</strong>: The sensor IC mounted on a small PCB with necessary support components</li>
  <li><strong>SH1106 Display Module</strong>: Display controller with integrated voltage regulation and I2C interface</li>
</ul>

<h3 id="future-approach---using-bare-ics">Future Approach - Using Bare ICs:</h3>
<ul>
  <li><strong>ESP32-WROOM-32 Module</strong>: Integrate directly onto PCB with custom power regulation and USB interface</li>
  <li><strong>SCD41/SGP40 IC</strong>: Mount the bare sensor with custom analog front-end circuitry</li>
  <li><strong>SH1106 Controller</strong>: Integrate with custom display driver circuit</li>
</ul>

<h3 id="why-i-didnt-use-pcba-service-this-time">Why I Didn’t Use PCBA Service This Time:</h3>

<p><strong>Availability</strong>: JLCPCB’s component sourcing partner (LCSC Electronics) has excellent stock of common ICs but limited availability of the specific development modules I was using. The variety of form factors and pinouts for modules makes standardization challenging.</p>

<p><strong>Complexity</strong>: Moving to bare ICs requires designing additional support circuitry - voltage regulators, crystal oscillators, and protection circuits. While this reduces cost and size, it significantly increases design complexity.</p>

<p><strong>Time to Market</strong>: Using modules allowed me to focus on the core functionality rather than getting bogged down in power supply design and RF engineering.</p>

<h2 id="next-steps-toward-true-production-readiness">Next Steps: Toward True Production Readiness</h2>

<p>This custom PCB version represents a major milestone, but the journey toward a truly production-ready design continues:</p>

<ol>
  <li><strong>IC Integration</strong>: Redesign using bare ICs instead of modules for cost and size optimization</li>
  <li><strong>PCBA Services</strong>: Leverage JLCPCB’s assembly services for automated component placement and soldering</li>
  <li><strong>Design for Manufacturing (DFM)</strong>: Optimize the design for high-volume production</li>
</ol>

<h2 id="looking-ahead">Looking Ahead</h2>

<p>As we wrap up this phase of the project, we’ve successfully achieved the core goals outlined in Part 1:</p>

<p>✅ <strong>Accuracy First</strong>: SCD41 NDIR sensor provides reliable CO2 measurements<br />
✅ <strong>Internet Connectivity</strong>: WiFi-enabled with Prometheus metrics endpoint<br />
✅ <strong>Data Logging &amp; Visualization</strong>: Grafana dashboard for historical analysis<br />
✅ <strong>Custom Hardware</strong>: Professional PCB design with 3D printed enclosure</p>

<p>The next phases will focus on smart home integration and scaling the design for potential small-batch production. Whether you’re interested in IoT development, PCB design, or just following along with this maker journey, the adventure continues!</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><category term="PCB Design" /><category term="EasyEDA" /><category term="JLCPCB" /><category term="Manufacturing" /><summary type="html"><![CDATA[After successfully miniaturizing our CO2 monitor with a 3D printed enclosure in Part 5, it was time to tackle the final stage outlined in our original roadmap: Stage Three - Custom PCB &amp; Cost Optimization for Potential “Mass Production”. What I discovered during this journey was that custom PCB design and manufacturing is far more accessible and affordable than I ever imagined!]]></summary></entry><entry><title type="html">DIY Smart CO2 Monitor Part 5: From Breadboard to Miniaturized 3D Printed Enclosure</title><link href="https://cmwang.dev/2025/07/24/diy-smart-co2-monitor-part-5-miniaturization/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 5: From Breadboard to Miniaturized 3D Printed Enclosure" /><published>2025-07-24T06:00:00+00:00</published><updated>2025-07-24T06:00:00+00:00</updated><id>https://cmwang.dev/2025/07/24/diy-smart-co2-monitor-part-5-miniaturization</id><content type="html" xml:base="https://cmwang.dev/2025/07/24/diy-smart-co2-monitor-part-5-miniaturization/"><![CDATA[<p>After successfully integrating the SCD41 sensor in <a href="/2025/06/15/diy-smart-co2-monitor-part-4-scd41/">Part 4</a>, it was time to tackle the next major challenge: miniaturization. The goal was to transform our bulky breadboard prototype into a sleek, compact device that could fit into a custom 3D printed enclosure. This journey introduced me to the world of CAD modeling, 3D printing technique, and opened up an entirely new hobby!</p>

<!--more-->

<h2 id="the-soldering-reality-check">The Soldering Reality Check</h2>

<p>Initially, I planned to solder everything onto a general-purpose PCB board to create a more permanent and compact solution. However, reality quickly set in when I attempted this approach.</p>

<p><img src="/assets/img/bad_solder.jpg" alt="My Terrible Soldering Attempt" /></p>

<p>The challenges were immediate and overwhelming:</p>

<ul>
  <li><strong>Poor Soldering Skills</strong>: Despite watching countless YouTube tutorials, my soldering technique was clearly inadequate for creating reliable connections</li>
  <li><strong>Excessive Fumes</strong>: The soldering process generated far more fumes than expected, making it uncomfortable to work indoors</li>
  <li><strong>Scalability Issues</strong>: Even if I could improve my technique, hand-soldering every device wasn’t practical for making multiple units</li>
  <li><strong>Reliability Concerns</strong>: The messy connections were prone to shorts and intermittent failures</li>
</ul>

<p>After this humbling experience, I realized that a different approach was needed.</p>

<h2 id="switching-to-mini-breadboards">Switching to Mini Breadboards</h2>

<p>Instead of fighting with traditional PCB soldering, I decided to embrace a more modular approach using small breadboards. This solution offered several advantages:</p>

<ul>
  <li><strong>No Soldering Required</strong>: All connections use jumper wires and breadboard pins</li>
  <li><strong>Easy Modifications</strong>: Changes to the circuit can be made quickly without desoldering</li>
  <li><strong>Reliable Connections</strong>: Breadboard connections, while temporary, are actually quite reliable for prototyping</li>
  <li><strong>Compact Form Factor</strong>: Mini breadboards are much smaller than full-size ones while still accommodating our components</li>
</ul>

<p>The trade-off was a slightly larger final size compared to a custom PCB, but the benefits far outweighed this limitation for a DIY project.</p>

<p><img src="/assets/img/mini_breadboard.png" alt="Mini BreadBoard" /></p>

<h2 id="learning-cad-design-with-onshape">Learning CAD Design with OnShape</h2>

<p>To create a proper enclosure, I needed to learn 3D modeling. After researching various options, I chose OnShape for several reasons:</p>

<ul>
  <li><strong>Cloud-Based</strong>: No software installation required, works on any computer</li>
  <li><strong>Free for Personal Use</strong>: Full professional features available at no cost</li>
  <li><strong>Excellent Tutorials</strong>: Comprehensive learning resources available</li>
  <li><strong>Browser-Based</strong>: Works seamlessly across different operating systems</li>
</ul>

<h2 id="enter-the-bambu-lab-a1-mini">Enter the Bambu Lab A1 Mini</h2>

<p>To bring my digital designs into the physical world, I invested in a Bambu Lab A1 Mini 3D printer. This compact, budget-friendly printer turned out to be a game-changer:</p>

<p><strong>Key Features:</strong></p>
<ul>
  <li><strong>Automatic Calibration</strong>: Minimal setup required for consistent prints</li>
  <li><strong>Quiet Operation</strong>: Can run overnight without disturbing anyone</li>
  <li><strong>Reliable Performance</strong>: Consistent quality across multiple prints</li>
  <li><strong>Compact Size</strong>: Fits perfectly on a desk without taking up too much space</li>
</ul>

<p><img src="/assets/img/a1_mini.jpg" alt="Bambu Lab A1 Mini Printing Enclosure" /></p>

<h2 id="the-3d-printing-rabbit-hole">The 3D Printing Rabbit Hole</h2>

<p>What started as a simple need for an enclosure quickly spiraled into a full-blown 3D printing obsession! Once I had the printer set up and working reliably, I found myself designing and printing all sorts of items:</p>

<ul>
  <li>Custom cable organizers for my desk</li>
  <li>Replacement parts for broken household items</li>
  <li>Tool holders for my workshop</li>
  <li>Decorative items and gifts for family</li>
  <li>Prototypes for completely unrelated project ideas</li>
</ul>

<p><img src="/assets/img/3d_printed_stuff.png" alt="Various 3D Printed Items" /></p>

<p>The ability to go from idea to physical object in just a few hours is incredibly addictive. I now understand why 3D printing enthusiasts are so passionate about their hobby!</p>

<h2 id="designing-the-perfect-enclosure">Designing the Perfect Enclosure</h2>

<p>After getting comfortable with both OnShape and 3D printing, I focused on creating the ideal enclosure for our CO2 monitor. The design requirements were:</p>

<p><strong>Functional Requirements:</strong></p>
<ul>
  <li>Accommodate the mini breadboard and all components</li>
  <li>Provide access to the display screen</li>
  <li>Allow for ventilation (critical for CO2 sensing)</li>
  <li>Easy assembly without tools</li>
  <li>Accessible USB port for programming and power</li>
</ul>

<p><strong>Aesthetic Goals:</strong></p>
<ul>
  <li>Clean, modern appearance</li>
  <li>Compact footprint</li>
  <li>Professional finish</li>
</ul>

<p><img src="/assets/img/aq_box_all.png" alt="CAD Design Screenshots" />
<img src="/assets/img/aq_box_body.png" alt="CAD Design Screenshots" />
<img src="/assets/img/aq_box_lid.png" alt="CAD Design Screenshots" />
<img src="/assets/img/bambu_slice.png" alt="Bambu Slicer" /></p>

<h2 id="printing-and-assembly">Printing and Assembly</h2>

<p>The printing process took about 1.5 hours for both pieces, using PLA filament for its ease of use and good surface finish. The snap-fit design worked perfectly on the first try – a testament to the precision achievable with modern 3D printing.</p>

<p>Assembly was straightforward:</p>
<ol>
  <li>Mount the mini breadboard in the bottom enclosure</li>
  <li>Route the display and sensor wires through the designated channels</li>
  <li>Snap the top piece into place</li>
  <li>Connect the USB cable for power</li>
</ol>

<h2 id="the-final-result">The Final Result</h2>

<p>While the transition from breadboard prototype to a finalized product has considerable room for improvement, it’s nonetheless an interesting development.</p>

<p><img src="/assets/img/3d_box_no_lid.jpg" alt="Final Result No Lid" /></p>

<p><img src="/assets/img/3d_box.jpg" alt="Final Result No Lid" /></p>

<p>A black version of the enclosure:</p>

<p><img src="/assets/img/3d_box_black.png" alt="Final Result No Lid" /></p>

<h2 id="next-steps-toward-a-production-ready-design">Next Steps: Toward a Production-Ready Design</h2>

<p>With our 3D printed enclosure complete, the next major milestones are designing a custom PCB to reduce size and manual work to connect the wires and implementing smart home integration. The final stage will bring Google Home integration, automated HVAC triggers, and multi-room monitoring capabilities as originally envisioned in <a href="/2025/05/31/diy-smart-co2-air-monitor/">Part 1</a>.</p>

<h2 id="reflections-on-the-journey">Reflections on the Journey</h2>

<p>This project has evolved from a simple air quality monitoring need into a comprehensive learning experience spanning:</p>

<ul>
  <li><strong>Electronics Design</strong>: From basic breadboard prototyping to planning custom PCBs</li>
  <li><strong>Software Development</strong>: ESP-IDF programming, data visualization, and IoT protocols</li>
  <li><strong>Mechanical Design</strong>: CAD modeling and 3D printing techniques</li>
  <li><strong>Manufacturing</strong>: Understanding the path from prototype to producible design</li>
</ul>

<p>The most rewarding aspect has been the hands-on learning across multiple disciplines. Each challenge – from poor soldering skills to CAD modeling – has opened up new areas of knowledge and capability.</p>

<p>Most importantly, this project demonstrates that with modern tools and a willingness to learn, individual makers can create sophisticated devices that compete with commercial products. The combination of affordable development boards, accessible CAD software, desktop 3D printing, and AI-assisted programming has democratized hardware development in unprecedented ways.</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><category term="CAD Design" /><category term="OnShape" /><category term="Bambu Lab" /><summary type="html"><![CDATA[After successfully integrating the SCD41 sensor in Part 4, it was time to tackle the next major challenge: miniaturization. The goal was to transform our bulky breadboard prototype into a sleek, compact device that could fit into a custom 3D printed enclosure. This journey introduced me to the world of CAD modeling, 3D printing technique, and opened up an entirely new hobby!]]></summary></entry><entry><title type="html">DIY Smart CO2 Monitor Part 4: Cost Optimization and SCD41 Integration</title><link href="https://cmwang.dev/2025/06/15/diy-smart-co2-monitor-part-4-scd41/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 4: Cost Optimization and SCD41 Integration" /><published>2025-06-15T10:00:00+00:00</published><updated>2025-06-15T10:00:00+00:00</updated><id>https://cmwang.dev/2025/06/15/diy-smart-co2-monitor-part-4-scd41</id><content type="html" xml:base="https://cmwang.dev/2025/06/15/diy-smart-co2-monitor-part-4-scd41/"><![CDATA[<p>The components I ordered for the next iteration of our DIY Smart CO2 Monitor have finally arrived! In this part, we’ll be focusing on cost optimization by switching to more affordable hardware while significantly improving accuracy with the Sensirion SCD41 sensor. This upgrade brings us closer to a production-ready design while maintaining the core functionality we built in <a href="/2025/06/14/diy-smart-co2-monitor-part-3-wifi-prometheus-grafana/">Part 3</a>.</p>

<!--more-->

<h2 id="hardware-cost-optimization">Hardware Cost Optimization</h2>

<p>For this iteration, I made strategic component choices to reduce costs while improving functionality:</p>

<h3 id="nodemcu-esp32-vs-esp32-s3-devkit">NodeMCU ESP32 vs ESP32-S3 DevKit</h3>

<p>I switched from the ESP32-S3 DevKit to a NodeMCU ESP32 development board, reducing the microcontroller cost from around $12 to just $3. While we lose some of the advanced features of the S3, the standard ESP32 provides all the capabilities we need for this project.</p>

<p><img src="/assets/img/esp32_vs_esp32s3.jpg" alt="NodeMCU ESP32 vs ESP32-S3 Comparison" /></p>

<h3 id="display-change-sh1106-to-ssd1306">Display Change: SH1106 to SSD1306</h3>

<p>I also switched from the SH1106 OLED display to an SSD1306 display, reducing the display cost from $4 to $2. The SSD1306 is smaller (0.96” vs 1.3”) but offers the same 128x64 resolution and is more widely supported in libraries.</p>

<p><img src="/assets/img/sh1106_vs_ssd1306.jpg" alt="SH1106 vs SSD1306 Display Comparison" /></p>

<p>While the smaller screen real estate requires more careful UI design, the cost savings make it worthwhile for a production design.</p>

<h2 id="the-scd41-a-game-changing-sensor">The SCD41: A Game-Changing Sensor</h2>

<p>The star of this upgrade is the Sensirion SCD41 sensor ($20). Unlike the SGP30 which estimates CO2 based on volatile organic compounds, the SCD41 uses NDIR (Non-Dispersive Infrared) technology to directly measure CO2 concentration, providing much more accurate readings.</p>

<h3 id="soldering-challenge-and-ai-assistant">Soldering Challenge and AI Assistant</h3>

<p>The SCD41 I received came without pre-soldered header pins. I turned to Gemini for soldering guidance and managed to get it connected, though admittedly not with the most beautiful results!</p>

<p><img src="/assets/img/scd41_ask_gemini_solder.png" alt="Gemini Soldering Conversation" /></p>

<p><img src="/assets/img/scd41_ask_gemini_solder_answer.png" alt="Gemini Soldering Conversation" /></p>

<p><img src="/assets/img/scd41_soldered.jpg" alt="SCD41 Soldered" /></p>

<h2 id="code-development-with-copilot-pro-and-claude-sonnet-4">Code Development with Copilot Pro and Claude Sonnet 4</h2>

<p>For this iteration, I upgraded to Copilot Pro and started using Claude Sonnet 4 (Preview) for more complex code generation tasks. The difference in capability is remarkable.</p>

<h3 id="creating-the-scd41-driver">Creating the SCD41 Driver</h3>

<p>The most impressive part of this development was that the SCD41 driver wasn’t available in the ESP-IDF component registry. I asked the AI to help, and it:</p>

<ol>
  <li><strong>Found the datasheet</strong>: Automatically located the SCD41 datasheet online</li>
  <li><strong>Generated a complete driver</strong>: Created a full I2C driver implementation from scratch</li>
  <li><strong>Worked on first run</strong>: The generated code compiled and functioned perfectly immediately</li>
</ol>

<p>The magic of modern AI development tools continues to amaze me. The driver worked so well that I decided to package it as a reusable component and published it to the ESP-IDF Component Registry: <a href="https://components.espressif.com/components/chiehmin/scd41">https://components.espressif.com/components/chiehmin/scd41</a></p>

<h2 id="side-by-side-comparison-sgp30-vs-scd41">Side-by-Side Comparison: SGP30 vs SCD41</h2>

<p>With both sensors running simultaneously, the accuracy difference is striking:</p>

<p><img src="/assets/img/sgp30_vs_scd41_breadboard.jpg" alt="SGP30 vs SCD41 Breadboard Setup" /></p>

<h3 id="detection-method-comparison">Detection Method Comparison</h3>

<p>The fundamental difference in detection methods explains the accuracy gap:</p>

<p><strong>SGP30 (MOX - Metal Oxide Semiconductor):</strong></p>
<ul>
  <li>Estimates CO2 based on TVOC measurements</li>
  <li>Highly temperature-dependent</li>
  <li>Requires calibration and warm-up time</li>
  <li>Good for relative changes, poor absolute accuracy</li>
</ul>

<p><strong>SCD41 (NDIR - Non-Dispersive Infrared):</strong></p>
<ul>
  <li>Directly measures CO2 absorption at specific infrared wavelengths</li>
  <li>Temperature-compensated internally</li>
  <li>Provides absolute CO2 measurements</li>
  <li>Industry-standard accuracy (±40 ppm + 5% of reading)</li>
</ul>

<h3 id="real-world-testing-results">Real-World Testing Results</h3>

<p>Through manual testing, the differences are clear:</p>

<ul>
  <li><strong>Temperature Independence</strong>: The SCD41 maintains consistent readings regardless of ambient temperature, while the SGP30 shows significant drift with temperature changes</li>
  <li><strong>Response Time</strong>: Both sensors respond to window opening/closing, but the SCD41 shows more predictable and linear changes</li>
  <li><strong>Absolute Values</strong>: The SCD41 readings align much better with expected indoor CO2 levels (400-1000 ppm), while SGP30 values seemed arbitrary</li>
</ul>

<p><img src="/assets/img/co2_trend_compare.png" alt="SGP30 vs SCD41 CO2 Trend" /></p>

<p>The SCD41 also provides temperature and humidity readings as bonus features, eliminating the need for the separate DHT11 sensor and simplifying our design.</p>

<h2 id="next-steps-moving-toward-production">Next Steps: Moving Toward Production</h2>

<p>With the sensor upgrade complete and cost optimization achieved, the next phase involves:</p>

<ol>
  <li><strong>PCB Design</strong>: Moving from breadboard to a custom PCB for better reliability and compact form factor</li>
  <li><strong>3D Printed Enclosure</strong>: Designing and printing a protective case for the final assembly</li>
  <li><strong>Power Optimization</strong>: Implementing deep sleep modes for battery operation</li>
  <li><strong>Final Testing</strong>: Long-term accuracy validation and environmental testing</li>
</ol>

<p>The total component cost for this iteration:</p>
<ul>
  <li>NodeMCU ESP32: $3</li>
  <li>SSD1306 Display: $2</li>
  <li>SCD41 Sensor: $20</li>
  <li><strong>Total: $25</strong>
    <ul>
      <li>The price for this version is similar to the previous one, but incorporates a more accurate sensor.</li>
    </ul>
  </li>
</ul>

<p>Stay tuned for next parts, where we’ll create a soldered PCB and 3D printed case for our smart CO2 monitor!</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><summary type="html"><![CDATA[The components I ordered for the next iteration of our DIY Smart CO2 Monitor have finally arrived! In this part, we’ll be focusing on cost optimization by switching to more affordable hardware while significantly improving accuracy with the Sensirion SCD41 sensor. This upgrade brings us closer to a production-ready design while maintaining the core functionality we built in Part 3.]]></summary></entry><entry><title type="html">DIY Smart CO2 Monitor Part 3: WiFi, Prometheus, and Grafana</title><link href="https://cmwang.dev/2025/06/14/diy-smart-co2-monitor-part-3-wifi-prometheus-grafana/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 3: WiFi, Prometheus, and Grafana" /><published>2025-06-14T14:00:00+00:00</published><updated>2025-06-14T14:00:00+00:00</updated><id>https://cmwang.dev/2025/06/14/diy-smart-co2-monitor-part-3-wifi-prometheus-grafana</id><content type="html" xml:base="https://cmwang.dev/2025/06/14/diy-smart-co2-monitor-part-3-wifi-prometheus-grafana/"><![CDATA[<p>In <a href="/2025/06/01/diy-smart-co2-monitor-part-2-poc/">Part 2</a> of our DIY Smart CO2 Monitor project, we successfully built a proof-of-concept (PoC) using an ESP32-S3, an SH1106 OLED display, a DHT11 sensor for temperature and humidity, and an SGP30 sensor for CO2 and TVOC levels. We also got our first taste of coding with GitHub Copilot. Now, in Part 3, we’ll take a significant leap forward by connecting our ESP32 to WiFi, exposing the collected air quality data in Prometheus format, and setting up Prometheus and Grafana with Docker Compose for long-term data storage and visualization.</p>

<!--more-->

<h2 id="wifi-station-mode-and-http-server-implementation">WiFi Station Mode and HTTP Server Implementation</h2>

<p>Getting our ESP32 online involves several key components working together. Let’s break down the implementation based on our actual code:</p>

<h3 id="wifi-initialization-and-connection">WiFi Initialization and Connection</h3>

<p>The ESP32 connects to WiFi in station mode (<code class="language-plaintext highlighter-rouge">WIFI_MODE_STA</code>) using the ESP-IDF framework. Our implementation includes:</p>

<ol>
  <li><strong>NVS Flash Initialization</strong>: Required for storing WiFi configuration data</li>
  <li><strong>Network Interface Setup</strong>: Initialize TCP/IP adapter and create default WiFi station interface</li>
  <li><strong>Event Handler Registration</strong>: Handle WiFi events like connection success, disconnection, and IP assignment</li>
  <li><strong>WiFi Configuration</strong>: Set SSID, password, and security mode (WPA2-PSK)</li>
</ol>

<h3 id="event-driven-wifi-management">Event-Driven WiFi Management</h3>

<p>Our WiFi event handler manages the connection lifecycle and provides user feedback through the OLED display:</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">WIFI_EVENT_STA_START</code></strong>: Automatically attempts connection when WiFi starts</li>
  <li><strong><code class="language-plaintext highlighter-rouge">WIFI_EVENT_STA_DISCONNECTED</code></strong>: Handles reconnection attempts on connection failure</li>
  <li><strong><code class="language-plaintext highlighter-rouge">IP_EVENT_STA_GOT_IP</code></strong>: Displays the assigned IP address on the OLED screen</li>
</ul>

<p>This event-driven approach ensures robust connectivity with automatic reconnection.</p>

<h3 id="http-server-with-prometheus-endpoint">HTTP Server with Prometheus Endpoint</h3>

<p>Once connected to WiFi, we start an HTTP server using ESP-IDF’s <code class="language-plaintext highlighter-rouge">esp_http_server</code> component. The server runs on the default port 80 and registers a single endpoint at <code class="language-plaintext highlighter-rouge">/metrics</code> that serves our sensor data in Prometheus format.</p>

<h3 id="thread-safe-sensor-data-access">Thread-Safe Sensor Data Access</h3>

<p>To ensure data consistency between the sensor reading loop and HTTP requests, we use a FreeRTOS mutex (<code class="language-plaintext highlighter-rouge">sensor_mutex</code>) to protect access to the shared sensor data structure. This prevents race conditions when the web server is serving metrics while sensors are being read.</p>

<h2 id="exposing-metrics-in-prometheus-format">Exposing Metrics in Prometheus Format</h2>

<p>Prometheus is a popular open-source monitoring and alerting toolkit. It scrapes metrics from instrumented jobs, either directly or via an intermediary push gateway for short-lived jobs. For our ESP32, we’ll create an HTTP endpoint that Prometheus can scrape.</p>

<p>The Prometheus exposition format is text-based. Each metric has a help string (<code class="language-plaintext highlighter-rouge"># HELP</code>), a type string (<code class="language-plaintext highlighter-rouge"># TYPE</code>), and then the metric name with its value. Here’s an example of what our <code class="language-plaintext highlighter-rouge">/metrics</code> endpoint will output:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># HELP air_quality_co2_ppm CO2 concentration in parts per million
# TYPE air_quality_co2_ppm gauge
air_quality_co2_ppm 400
# HELP air_quality_tvoc_ppb Total Volatile Organic Compounds in parts per billion
# TYPE air_quality_tvoc_ppb gauge
air_quality_tvoc_ppb 142
# HELP air_quality_temperature_celsius Temperature in degrees Celsius
# TYPE air_quality_temperature_celsius gauge
air_quality_temperature_celsius 25.0
# HELP air_quality_humidity_percent Relative humidity percentage
# TYPE air_quality_humidity_percent gauge
air_quality_humidity_percent 38.0
# HELP air_quality_last_update_timestamp Unix timestamp of last sensor update
# TYPE air_quality_last_update_timestamp gauge
air_quality_last_update_timestamp 80732
</code></pre></div></div>

<p>When a request comes to <code class="language-plaintext highlighter-rouge">http://&lt;esp32_ip_address&gt;/metrics</code>, our ESP32 will read the latest sensor values, format them as shown above, and send them back as the HTTP response.</p>

<h2 id="docker-compose-for-prometheus-and-grafana">Docker Compose for Prometheus and Grafana</h2>

<p>To collect, store, and visualize this data, we’ll use Prometheus and Grafana. Docker Compose is an excellent tool for defining and running multi-container Docker applications. Here’s a simplified <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> to get Prometheus and Grafana running:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">3.8'</span>

<span class="na">services</span><span class="pi">:</span>
  <span class="na">prometheus</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">prom/prometheus:latest</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">prometheus</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">9090:9090"</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">./prometheus:/etc/prometheus/</span>
      <span class="pi">-</span> <span class="s">prometheus_data:/prometheus</span>
    <span class="na">command</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s1">'</span><span class="s">--config.file=/etc/prometheus/prometheus.yml'</span>
      <span class="pi">-</span> <span class="s1">'</span><span class="s">--storage.tsdb.path=/prometheus'</span>
      <span class="pi">-</span> <span class="s1">'</span><span class="s">--web.console.libraries=/usr/share/prometheus/console_libraries'</span>
      <span class="pi">-</span> <span class="s1">'</span><span class="s">--web.console.templates=/usr/share/prometheus/consoles'</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>

  <span class="na">grafana</span><span class="pi">:</span>
    <span class="na">image</span><span class="pi">:</span> <span class="s">grafana/grafana:latest</span>
    <span class="na">container_name</span><span class="pi">:</span> <span class="s">grafana</span>
    <span class="na">ports</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s2">"</span><span class="s">3000:3000"</span>
    <span class="na">volumes</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">grafana_data:/var/lib/grafana</span>
    <span class="na">depends_on</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">prometheus</span>
    <span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>

<span class="na">volumes</span><span class="pi">:</span>
  <span class="na">prometheus_data</span><span class="pi">:</span> <span class="pi">{}</span>
  <span class="na">grafana_data</span><span class="pi">:</span> <span class="pi">{}</span>
</code></pre></div></div>

<p>You’ll also need a <code class="language-plaintext highlighter-rouge">prometheus.yml</code> configuration file (in a <code class="language-plaintext highlighter-rouge">prometheus</code> directory next to your <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>) to tell Prometheus where to scrape metrics from. It would include a job definition for our ESP32:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">global</span><span class="pi">:</span>
  <span class="na">scrape_interval</span><span class="pi">:</span> <span class="s">15s</span> <span class="c1"># By default, scrape targets every 15 seconds.</span>

<span class="na">scrape_configs</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">job_name</span><span class="pi">:</span> <span class="s1">'</span><span class="s">esp32-air-quality'</span>
    <span class="na">static_configs</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">targets</span><span class="pi">:</span> <span class="pi">[</span><span class="s1">'</span><span class="s">&lt;esp32_ip_address&gt;:80'</span><span class="pi">]</span> <span class="c1"># Replace &lt;esp32_ip_address&gt; with the actual IP</span>
</code></pre></div></div>

<p>I run these Docker containers on my home NAS (Synology DS920+), which is a great way to have an always-on system for data collection and long-term storage. GitHub Copilot was a great help in drafting the initial ESP32 web server code and the Docker Compose configuration.</p>

<h2 id="visualizing-the-data">Visualizing the Data</h2>

<p>Once Prometheus is scraping data from the ESP32, and Grafana is connected to Prometheus as a data source, you can create dashboards to visualize the air quality metrics over time.</p>

<p>Here’s a conceptual image of what the CO2 data might look like in Grafana:</p>

<p><img src="/assets/img/grafana_co2.png" alt="CO2 Data Visualization Placeholder" /></p>

<p>The data shows interesting trends. For example, when CO2 and TVOC values spike, opening a window causes the levels to drop significantly. Closing the window leads to the values rising again. This demonstrates that the relative changes are being captured effectively.</p>

<h2 id="next-steps-improving-accuracy">Next Steps: Improving Accuracy</h2>

<p>While the relative values from the SGP30 are insightful, its absolute accuracy, especially for CO2, can be limited. For more precise measurements, the next step in this project will be to integrate a more accurate sensor. I plan to use the Sensirion SCD41, which uses an NDIR (Non-Dispersive Infrared) sensor to detect CO2, known for better accuracy.</p>

<p>Additionally, I’ll migrate the project to a more cost-effective ESP32 board for the final PoC before considering a “Stage 2” development, which might involve a custom PCB or a more refined enclosure.</p>

<p>Stay tuned for Part 4, where we’ll dive into integrating the SCD41 sensor and refining our hardware setup!</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><category term="Prometheus" /><category term="Grafana" /><category term="docker-compose" /><summary type="html"><![CDATA[In Part 2 of our DIY Smart CO2 Monitor project, we successfully built a proof-of-concept (PoC) using an ESP32-S3, an SH1106 OLED display, a DHT11 sensor for temperature and humidity, and an SGP30 sensor for CO2 and TVOC levels. We also got our first taste of coding with GitHub Copilot. Now, in Part 3, we’ll take a significant leap forward by connecting our ESP32 to WiFi, exposing the collected air quality data in Prometheus format, and setting up Prometheus and Grafana with Docker Compose for long-term data storage and visualization.]]></summary></entry><entry><title type="html">DIY Smart CO2 Monitor Part 2: Proof of Concept with ESP32-S3</title><link href="https://cmwang.dev/2025/06/01/diy-smart-co2-monitor-part-2-poc/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 2: Proof of Concept with ESP32-S3" /><published>2025-06-01T04:00:00+00:00</published><updated>2025-06-01T04:00:00+00:00</updated><id>https://cmwang.dev/2025/06/01/diy-smart-co2-monitor-part-2-poc</id><content type="html" xml:base="https://cmwang.dev/2025/06/01/diy-smart-co2-monitor-part-2-poc/"><![CDATA[<p>Welcome back to the DIY Smart CO2 Monitor series! In <a href="/2025/05/31/diy-smart-co2-air-monitor/">Part 1: The Plan &amp; Goals</a>, I outlined my motivation and the overall roadmap for building a custom, smart CO2 monitor. Now, it’s time to dive into the first practical stage: the Proof of Concept (PoC).</p>

<p>For this PoC, I assembled the core components on a breadboard to test functionality and get a feel for the sensors and the ESP32 platform.</p>

<!--more-->

<h2 id="hardware-lineup-for-the-poc">Hardware Lineup for the PoC</h2>

<p>Here’s a quick rundown of the components I used for this initial build:</p>

<ul>
  <li><strong>Microcontroller: ESP32-S3 Dev Board</strong> (approx. $10 USD)
    <ul>
      <li>I opted for a higher-end ESP32-S3 for this PoC. While it’s a bit more powerful (and slightly more expensive) than strictly necessary for just a CO2 monitor, I chose it with future projects in mind that might demand more computational power or specific S3 features like AI acceleration capabilities or more I/O.</li>
      <li>The ESP32 family is quite diverse:
        <ul>
          <li><strong>Original ESP32:</strong> Still a workhorse, great for many IoT projects, very cost-effective.</li>
          <li><strong>ESP32-S2:</strong> Single-core, focused on low power and security.</li>
          <li><strong>ESP32-S3:</strong> Dual-core, adds AI instructions, more I/O, and Bluetooth 5 LE.</li>
          <li><strong>ESP32-C series (C3, C5, C6 etc.):</strong> RISC-V based, often targeting specific cost points or connectivity needs (like Wi-Fi 6 in the C6).</li>
        </ul>
      </li>
      <li>For later stages, especially if aiming for cost optimization in Stage Three (custom PCB), I’ll likely evaluate using a more basic ESP32 or an ESP32-C series chip to bring down the unit cost.</li>
    </ul>
  </li>
  <li><strong>Display: SH1106 OLED Display (1.3 inch)</strong> (approx. $4 USD)
    <ul>
      <li>A crisp monochrome display to show CO2 levels, temperature, and humidity directly on the device.</li>
    </ul>
  </li>
  <li><strong>Temperature &amp; Humidity Sensor: DHT11</strong> (approx. $1 USD)
    <ul>
      <li>A basic but widely available sensor to get ambient temperature and humidity readings. While not the most accurate, it’s sufficient for a PoC.</li>
    </ul>
  </li>
  <li><strong>CO2 &amp; TVOC Sensor: Sensirion SGP30</strong> (approx. $10 USD)
    <ul>
      <li>This sensor provides CO2 equivalent (eCO2) and Total Volatile Organic Compound (TVOC) readings. It’s a good starting point for air quality sensing.</li>
    </ul>
  </li>
</ul>

<p>All these components were wired up on a standard breadboard for easy iteration.</p>

<h2 id="development-environment-esp-idf-all-the-way">Development Environment: ESP-IDF All the Way</h2>

<p>Instead of using the Arduino extension for ESP32, I decided to set up and use the <strong>ESP-IDF (Espressif IoT Development Framework)</strong> directly.</p>

<ul>
  <li><strong>Pros of ESP-IDF:</strong>
    <ul>
      <li><strong>Direct Control:</strong> It provides much more direct access to the ESP32’s hardware features, FreeRTOS (the underlying real-time operating system), and low-level libraries.</li>
      <li><strong>Latest Features:</strong> You often get access to the newest features and bug fixes from Espressif sooner.</li>
      <li><strong>Optimization:</strong> More opportunities for fine-grained optimization of performance and memory usage.</li>
      <li><strong>Official Framework:</strong> It’s the official development framework from Espressif.</li>
    </ul>
  </li>
  <li><strong>Cons of ESP-IDF:</strong>
    <ul>
      <li><strong>Steeper Learning Curve:</strong> Compared to Arduino’s simplified API, ESP-IDF can be more complex to get started with.</li>
      <li><strong>More Boilerplate:</strong> Setting up projects and managing components can involve more configuration.</li>
    </ul>
  </li>
</ul>

<p>For a project where I want to understand the nuts and bolts and potentially build custom drivers, the control and flexibility offered by ESP-IDF felt like the right choice.</p>

<h2 id="peripheral-choices--i2c-simplicity">Peripheral Choices &amp; I2C Simplicity</h2>

<p>To practice working with the ESP32 and its peripherals, I selected the SH1106, DHT11, and SGP30. A key decision here was to primarily use sensors with an <strong>I2C interface</strong>.</p>

<ul>
  <li><strong>I2C (Inter-Integrated Circuit):</strong>
    <ul>
      <li>Uses only two wires (SDA for data, SCL for clock) plus power and ground.</li>
      <li>Simpler wiring compared to SPI, especially when connecting multiple devices (as they can share the same bus, each with a unique address).</li>
      <li>Sufficient speed for many common sensors.</li>
    </ul>
  </li>
  <li><strong>SPI (Serial Peripheral Interface):</strong>
    <ul>
      <li>Generally faster than I2C.</li>
      <li>Requires more wires (MOSI, MISO, SCLK, and a Chip Select for each device).</li>
    </ul>
  </li>
</ul>

<p>For this PoC, the simplicity and reduced wire clutter of I2C were ideal.</p>

<h2 id="coding-with-an-ai-assistant-github-copilot--sonnet-35">Coding with an AI Assistant: GitHub Copilot &amp; Sonnet 3.5</h2>

<p>A significant part of this PoC was leveraging AI for code generation. I used <strong>GitHub Copilot, powered by the Sonnet 3.5 model</strong>, extensively.</p>

<p>My experience was overwhelmingly positive:</p>

<ul>
  <li><strong>Rapid Prototyping:</strong> Copilot was excellent at generating initial boilerplate code for sensor initialization, reading data, and displaying it on the OLED.</li>
  <li><strong>Iterative Refinement:</strong> While the first code suggestion wasn’t always perfect, the key was effective communication. By providing Copilot (running in an agent-like chat interface) with specific context, such as:
    <ul>
      <li>Datasheets for the sensors (especially for communication protocols and register maps).</li>
      <li>Information about existing third-party device drivers in the ESP-IDF component registry.</li>
      <li>Clear descriptions of the desired logic.
…I was able to guide it to produce working code after several iterations.</li>
    </ul>
  </li>
  <li><strong>Driver Generation from Scratch:</strong> One of the most impressive feats was generating a device driver for the SGP30 sensor from scratch. At the time, I couldn’t find a readily available ESP-IDF component for it in the Espressif Component Registry that fit my needs perfectly. So, armed with the SGP30 datasheet, I worked with Copilot to generate the I2C communication logic, data processing, and the necessary C code structure for an ESP-IDF component.</li>
  <li><strong>Contributing Back:</strong> I was so pleased with the generated SGP30 driver that I packaged it as a proper ESP-IDF component and published it to the Espressif Component Registry! You can find it here: <a href="https://components.espressif.com/components/chiehmin/sgp30/versions/1.0.0">chiehmin/sgp30</a>.</li>
</ul>

<h2 id="the-poc-in-action">The PoC in Action!</h2>

<p>After some tinkering and coding iterations, the breadboard setup came to life! The ESP32-S3 successfully read data from the DHT11 and SGP30, displaying CO2 (eCO2), TVOC, temperature, and humidity on the SH1106 OLED screen.</p>

<p>Here’s a picture of the final PoC setup:</p>

<p><img src="/assets/img/esp32s3_aq_v1.jpg" alt="My ESP32-S3 CO2 Monitor PoC on a Breadboard" title="ESP32-S3 CO2 Monitor PoC on Breadboard" /></p>

<h2 id="next-steps">Next Steps</h2>

<p>This Proof of Concept (PoC) phase was a fantastic learning experience, especially in leveraging ESP-IDF and AI for development. The next step involves connecting the ESP32 to the internet and exposing its metrics, allowing other services to store historical data and generate graphs.</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><category term="SH1106" /><category term="DHT11" /><category term="SGP30" /><category term="I2C" /><category term="GitHub Copilot" /><summary type="html"><![CDATA[Welcome back to the DIY Smart CO2 Monitor series! In Part 1: The Plan &amp; Goals, I outlined my motivation and the overall roadmap for building a custom, smart CO2 monitor. Now, it’s time to dive into the first practical stage: the Proof of Concept (PoC). For this PoC, I assembled the core components on a breadboard to test functionality and get a feel for the sensors and the ESP32 platform.]]></summary></entry><entry><title type="html">DIY Smart CO2 Monitor Part 1: The Plan &amp;amp; Goals</title><link href="https://cmwang.dev/2025/05/31/diy-smart-co2-air-monitor/" rel="alternate" type="text/html" title="DIY Smart CO2 Monitor Part 1: The Plan &amp;amp; Goals" /><published>2025-05-31T09:00:00+00:00</published><updated>2025-05-31T09:00:00+00:00</updated><id>https://cmwang.dev/2025/05/31/diy-smart-co2-air-monitor</id><content type="html" xml:base="https://cmwang.dev/2025/05/31/diy-smart-co2-air-monitor/"><![CDATA[<h2 id="the-quest-for-accurate--affordable-co2-monitoring">The Quest for Accurate &amp; Affordable CO2 Monitoring</h2>

<p>For a while now, I’ve been looking to get a reliable CO2 monitor for my home and workspace. We all know good air quality is crucial for concentration, health, and overall well-being, especially when spending many hours indoors. However, my journey into the world of commercial CO2 monitors has been a bit of a letdown.</p>

<!--more-->

<p>It seems you’re often caught between two extremes:</p>

<ol>
  <li><strong>The “Too Inaccurate” Bunch:</strong> Many lower-priced CO2 monitors, like some of the generic models you might find on Amazon or other online marketplaces, often use less reliable sensing technologies. You’ll frequently see user reviews complaining about inconsistent readings, slow response times, or values that just don’t seem to reflect the actual environment. It’s hard to trust data when it’s all over the place!</li>
</ol>

<p><img src="/assets/img/low_cost_co2_monitor.png" alt="Cheap CO2 sensor" title="lower-priced CO2 monitors" /></p>

<ol>
  <li><strong>The “Too Expensive” Crew:</strong> On the other end of the spectrum, monitors that use high-quality NDIR (Non-Dispersive Infrared) sensors and offer good accuracy, can be quite an investment (often around $200-$250), especially if you want multiple units.</li>
</ol>

<p><img src="/assets/img/high_cost_co2_monitor.png" alt="Expensive CO2 sensor" title="high-priced CO2 monitors" /></p>

<p>This gap in the market – affordable yet accurate and <em>smart</em> – is what sparked my latest project idea.</p>

<h2 id="my-diy-solution-a-smart-connected-and-customizable-co2-monitor">My DIY Solution: A Smart, Connected, and Customizable CO2 Monitor</h2>

<p>Why not build one myself? This way, I can ensure the accuracy I want, add the features I need, and have full control over the data.</p>

<p>Here are the primary goals for my DIY CO2 monitor:</p>

<ul>
  <li><strong>Accuracy First:</strong> Utilize a reliable NDIR CO2 sensor for trustworthy measurements.</li>
  <li><strong>Internet Connectivity:</strong> Expose the CO2 (and potentially temperature/humidity) metrics over my local network and, eventually, the internet.</li>
  <li><strong>Data Logging &amp; Visualization:</strong> I want to record historical CO2 data to identify patterns and plot graphs. This will help me understand how CO2 levels change in different rooms and under various conditions (e.g., number of people, ventilation).</li>
  <li><strong>Smart Home Integration:</strong> The ultimate goal is to integrate this with my Google Home ecosystem. Imagine the possibilities: automatically triggering an air circulation system or a smart fan when CO2 levels exceed a predefined threshold!</li>
</ul>

<h2 id="the-brains-of-the-operation-esp32">The Brains of the Operation: ESP32</h2>

<p>After doing some initial research and considering various microcontrollers, I’ve decided to go with the <strong>ESP32 series</strong>. It’s a powerhouse for IoT projects like this because:</p>

<ul>
  <li><strong>Integrated Wi-Fi &amp; Bluetooth:</strong> Essential for network connectivity.</li>
  <li><strong>Sufficient Processing Power:</strong> Easily handles sensor data, network communication, and potentially a small web interface.</li>
  <li><strong>Rich Peripheral Set:</strong> Plenty of I/O for sensors and other components.</li>
  <li><strong>Strong Community &amp; Ecosystem:</strong> Abundant libraries, tutorials, and community support make development much smoother.</li>
  <li><strong>Cost-Effective:</strong> ESP32 development boards are very affordable.</li>
</ul>

<h2 id="the-development-roadmap-a-phased-approach">The Development Roadmap: A Phased Approach</h2>

<p>I’m planning to develop this project in three main stages:</p>

<h3 id="stage-one-proof-of-concept-poc-on-a-breadboard">Stage One: Proof of Concept (PoC) on a Breadboard</h3>
<p>This is where the rubber meets the road (or rather, the components meet the breadboard!).</p>
<ul>
  <li>Connect a chosen NDIR CO2 sensor (e.g., Senseair S8, Winsen MH-Z19, or Sensirion SCD30/SCD4x) to an ESP32 development board.</li>
  <li>Write the initial firmware to read CO2, temperature, and humidity.</li>
  <li>Possibly add a small OLED display for local readings.</li>
  <li>Implement a basic web server on the ESP32 to serve the data on my local network.</li>
</ul>

<h3 id="stage-two-from-breadboard-to-bespoke-enclosure">Stage Two: From Breadboard to Bespoke Enclosure</h3>
<p>Once the PoC is validated and working reliably, the next step is to make it more permanent and presentable.</p>
<ul>
  <li>Solder the ESP32 module, sensor, and any other necessary components (like power regulation) onto a general-purpose PCB (perfboard or stripboard).</li>
  <li>Design and 3D print a custom case for the monitor. This will give it a more polished, product-like feel.</li>
</ul>

<h3 id="stage-three-custom-pcb--cost-optimization-for-potential-mass-production">Stage Three: Custom PCB &amp; Cost Optimization for Potential “Mass Production”</h3>
<p>This is the most advanced stage, aiming for a highly refined and potentially replicable design.</p>
<ul>
  <li>Design a custom Printed Circuit Board (PCB) specifically tailored for this CO2 monitor. This will result in a much more compact, robust, and professional-looking device.</li>
  <li>Instead of using a full ESP32 development board, integrate the ESP32 IC (the chip itself, e.g., ESP32-WROOM-32 module or even the bare chip if feeling adventurous) directly onto the custom PCB. This significantly reduces the bill of materials (BOM) cost and physical footprint, unlocking the potential for easier replication or even small-scale “mass production” for friends or the local community.</li>
</ul>

<h2 id="whats-next">What’s Next?</h2>

<p>I’m incredibly excited to embark on this project! I’ll be sharing my progress, challenges, code snippets, design files, and any interesting discoveries right here on this blog. Expect deep dives into sensor comparisons, ESP32 programming hurdles, PCB design learnings, and the joys (and frustrations) of 3D printing.</p>

<p>If you’re interested in air quality, IoT, ESP32 projects, or just love a good DIY challenge, stay tuned!</p>]]></content><author><name>Chieh-Min Wang</name></author><category term="DIY" /><category term="Electronics" /><category term="IoT" /><category term="ESP-IDF" /><category term="ESP32" /><category term="CO2 Monitor" /><category term="Smart Home" /><category term="Air Quality" /><summary type="html"><![CDATA[The Quest for Accurate &amp; Affordable CO2 Monitoring For a while now, I’ve been looking to get a reliable CO2 monitor for my home and workspace. We all know good air quality is crucial for concentration, health, and overall well-being, especially when spending many hours indoors. However, my journey into the world of commercial CO2 monitors has been a bit of a letdown.]]></summary></entry><entry><title type="html">Welcome to My AI-Driven Development Journey!</title><link href="https://cmwang.dev/2025/05/24/welcome-to-my-blog/" rel="alternate" type="text/html" title="Welcome to My AI-Driven Development Journey!" /><published>2025-05-24T02:00:00+00:00</published><updated>2025-05-24T02:00:00+00:00</updated><id>https://cmwang.dev/2025/05/24/welcome-to-my-blog</id><content type="html" xml:base="https://cmwang.dev/2025/05/24/welcome-to-my-blog/"><![CDATA[<p>Welcome to my AI-driven development journey! I’m Chieh-Min Wang, a software engineer passionate about low-level programming and system optimization. This blog represents a fascinating experiment where years of software engineering expertise meets the cutting edge of AI assistance.</p>

<!--more-->

<h2 id="why-this-blog-exists">Why This Blog Exists</h2>

<p>After years developing and optimizing low-level device drivers and frameworks, I’ve witnessed firsthand how development paradigms evolve. Now, I’m exploring how AI can revolutionize software engineering - and this blog documents that journey in real-time.</p>

<h2 id="the-journey-begins">The Journey Begins</h2>

<p>This is the beginning of documenting how software development is evolving in the age of AI. Every post here represents a real experiment combining technical expertise with AI collaboration.</p>

<p>Join me as we explore this exciting frontier where engineering meets artificial intelligence!</p>

<hr />

<p><em>Note: This blog represents a collaboration between software engineering expertise and AI assistance. Full transparency about our development process is core to this journey.</em></p>]]></content><author><name>Chieh-Min Wang</name></author><category term="Introduction" /><category term="ai-development" /><category term="introduction" /><summary type="html"><![CDATA[Welcome to my AI-driven development journey! I’m Chieh-Min Wang, a software engineer passionate about low-level programming and system optimization. This blog represents a fascinating experiment where years of software engineering expertise meets the cutting edge of AI assistance.]]></summary></entry></feed>