It's been a while since I deployed the air quality monitor on my balcony. If you're reading this, chances are you have seen the first article where I described the lengthy process of getting it to work with the ESP32-based WiPy board, optimizing battery usage, visualizing the data and putting everything in a box. Over 2 months later I'm after several iterations of improving it, fixing issues and trying out new solutions.

To recap, the first release version had the following features:

  1. Measured values:
    • PM2.5 and PM10 concentration via a PMS5003 air quality sensor,
    • temperature and relative humidity via a SHT10 sensor,
    • battery voltage using the Pycom expansion board's built-in voltage divider and ESP32 analogue-to-digital converter,
    • total measurement duration.

Battery wars continued

The 700mAh battery that I tested while publishing the previous article eventually lasted just over 5 days and nights, around 130 hours. I'd call it quite an impressive result, given that for every measurement the particulate matter sensor had to run for ~11 seconds, draining up to 200mA current alone. So the device stopped working because the battery couldn't supply it with a decent voltage anymore, and unfortunately, I found that the battery was completely dead and showing zero voltage.

PCM my ass

This is unexpected and somewhat disappointing, because the battery had the Protection Circuit Module (PCM) and yes, it was mounted there as I could see it, yet it apparently didn't do the job of protecting the cell from over-discharging. Also, judging from the battery voltage graph, definitely something went wrong in the last couple of hours, but I wouldn't say such weird behaviour can occur around 3.7V:

[caption id="attachment_486" align="alignnone" width="2836"]700mAh-dead Other graphs attached as a proof that the system worked fine all the time during the heavy battery drain...[/caption]

The dead battery shows 0V on a voltmeter, and that's because the PCM is now apparently active and prevents it from powering the load. The voltage measured on the PCM module input showed 2.85V, which is far below a healthy 3.7-3.6V and even below the (deadly for Li-Po cells) 3.0V level.

The Big Boy


[caption id="attachment_media-40" align="alignnone" width="2856"]2400mAh-dead.png On the bright side, this means >2 weeks of uninterrupted uptime, yay![/caption]

At first, I was like "oh ok, the Raspberry Pi Grafana server went offline". But no, it didn't. The battery was dead again. With the same symptoms (0V and <3V at the PCM input). This was enough of a motivation to revisit the battery voltage measurement code.



Ok, fair enough, but why the script didn't fail at battery voltage measurement function since ADC.ATTN_3DB changed to ADC.ATTN_2_5DB?


# good
apin =, pin='P16')

# baaaad!
apin =, pin='P16')

In previous firmware the 1 used to mean 3dB, and now it became 2.5dB. It wasn't my code after all, as I copied the code from elsewhere, but still, I didn't bother to carefully read it through and try to understand what's going on there and this is purely my fault. This is the great example of how not paying enough attention to your code can sometimes cost you real money.







Running short of GPIOs

Both LoPy4 and WiPy (and all the other Pycom development boards)  have the same amount of pins, but some of them are reserved, especially on more sophisticated boards. In case of LoPy4 (and the first version of LoPy), there are three pins reserved for communication with the LoRa chip. This way they can't be used by the developer. Add to that 6 input-only pins, 2 programming pins, a Wi-Fi antenna-switch pin and overall 9 pins taken by my device's sensors, it's getting pretty tight. If I were to add another peripheral, I might have a hard time finding a place for it.

Firmware and RTC issues


The other thing I noticed in the LoPy4 was that the real-time clock didn't persist its state in deep sleep while on battery power. It worked perfectly fine (for an ESP32 RTC ;)) when powered via USB. This was something I heavily relied on, as the script's workflow looked like this:

  • sync RTC with NTP server on first boot,
  • take 6 measurements every 10 minutes,
  • repeat from step 2.


I found the DS3231 module relatively cheap and somewhat nicely fitting the expansion board. I'd prefer male pins, but eventually, I sorted it out in some way:

[caption id="attachment_490" align="alignnone" width="1024"]IMG_3373 "Any two interfaces can be connected using a finite number of adapters".[/caption]


RTC lagging


I solved the issue by pulling up the Vin pin of the RTC to LoPy's 3V3 output. It's not straightforward to do so on the expansion board, but this solution is good enough for a proof of concept:

[caption id="attachment_492" align="alignnone" width="2560"]resistor Surprise resistor![/caption]


...And then I managed to connect the board via LoRaWAN to The Things Network. It was an interesting experience, took me almost a whole weekend but now it seems to work reliably for a week already. I'll better write about it in a separate blog post though because otherwise, no-one would ever finish reading this one.

Custom PCB

[caption id="attachment_493" align="alignnone" width="1024"]boxed Getting tight...[/caption]





[caption id="attachment_495" align="alignnone" width="4032"]IMG_3385 2 Sorry for the ugly silicone sealing![/caption]

It works great, with the exception of battery voltage measurement. Yes, I completely forgot about the voltage divider – with this board I'd need to monitor it manually with a voltmeter every couple of days...

Final PCB project


[caption id="attachment_497" align="alignnone" width="1356"]charger Battery charger circuit[/caption]

The battery charger circuit includes:

  • the MAX1811 charger module itself,
  • the micro USB port,
  • the LED diode that indicates charging,
  • the circuit that cuts off the battery from the load during charging, and connects the USB voltage instead. It's very cool – check out how it works over here.

This adds some significant complexity to the device and especially to the PCB layout, but I'm fine with it as I admire working with a PCB designer. As an Integrated Circuits Design graduate, I can recall a little bit the good old times of working long hours with Cadence Virtuoso, which still, compared to KiCad Pcbnew, is like building with Lego Technics vs Duplo.

Screen Shot 2018-01-26 at 00.04.57

The above project got sent to the factory, and while writing this, I'm still waiting for the delivery. I'll keep you posted as the PCBs arrive, hope I'll manage to solder the micro USB port correctly :)
