Active Pet-Projects

Air quality sensor


At some point in autumn/winter 2018, I have realized that I have some allergic symptoms in our bedroom. One way to figure it out was to try air filtering. To this end, I have borrowed a unit built by a renowned manufacturer and found that it, in fact, has improved our sleep quality. This made me curious about the air quality measurement - so I got one of the Plantower sensors to compare its numbers with the sensor built into the commercial purifier.


Not much time, I have built and implemented an air quality sensor. I have used a cheap, low power USB charger (5V) with a voltage regulator to power ESP01 . The Arduino implementation is straightforward:

  • it waits to get a poll message through an MQTT channel

  • switches on the sensor and lets it warm up for 30 seconds

  • takes a measure and pushes it back over another MQTT channel

The results can be read out through the NodeRed Dashboard


It seems that the numbers I got form my sensor perfectly matched numbers from the purifier, so I decided to proceed with the next step.

Air purifier


A commercial purifier cost goes in hundreds CHF, and it seemed to me that it comprises no more than a filter, a fan, and an air sensor. As most of the vendors sell affordable replacement filters and I already had a sensor, I decided that to take the challenge and build the remaining part.


I have based my design on principles similar to the commercial purifier: it should suck air from the side and blow it up. The airflow was to be provided by a three-channel array of fans to pull the air through the filter and one additional set of fans to pull the air out of the box. For air quality monitoring, I’ve built in an array of five colorful LEDs, and for the manual operation, I have added a digital encoder dial (KY-040).

A dual power supply is used to feed the logic with 5v and 12v for powering fans. PWM modulation for fan power is driven through integrated PWM i2c drivers (PCA9685). Given the fact that the driver has 16 independent channels, I was hoping to be able to feed through it both fans and LEDs. Unfortunately, it seems that the PWM frequency required by the fans is way different than the one suitable for LEDs, so I ended up using two PWM drivers. As drivers themselves are not ideal for high-current drains, I have used TIP-31c (TO-220) for fans and n2222 (TO-92) for LEDs.

I was caught by surprise by the hum induced in fans by the PWM frequency. To mitigate that, I needed to add massive capacitors (XXX uF) behind power transistors to smoothen the pulsed power delivery. As a side-effect of placing capacitors there, I have noticed power transistors heating up significantly more than before. I guess that this is caused by the high peak currents when charging capacitors. Given enough research and oscilloscope at hand, I’m quite sure that it would be possible to smoothen the PWM shape after the driver and before power transistors, but I still don’t have one at hand. Eventually, to support silent overnight operation, I have optimized the capacitor size to limit hum at about 1/4 of fan throughput.


A boilerplate of Arduino implementation is similar to my other automation projects. I have used an off-the-shelf SPI PWM control library and my implementation of rotary encoder read-out.

To Be Done

Component wiring visible in the gallery above is prototype-grade. Still, it has proven to be reliable enough to improve our sleep quality during the autumn-to-spring season when leaving the open window overnight is not an option.

I also need to improve covers for the electronics compartment (now covered with tape) and come up with some good ways to protect top fans from the curious hands of my son.

Dining room ambient light

Following the success of the bedroom ambient light, I have installed a plain-white LED-strip in our living room. Thanks to the fact that the ESP32 module has an integrated PWM generator, with use only one TIP-31c, I was able to modulate the brightness quickly. As our primary source of light in the dining room is the spot-lamp over the table, we enjoy the extra ambient light, in particular during the winter mornings, when we have breakfast before the sunrise.

443 MHz to MQTT bridge


There are plenty of useful sensors, buttons, and actuators that operate using digital code exchange at 443 MHz band. I found buttons and door/window opening sensors particularly helpful in triggering events for our home-automation.


I have used cheap, low-grade 5v off-the-shelf charger to and 3.3v voltage regulator to feed the ESP-01 module. Most importantly, I have used the SRX882 receiver to feed the microcontroller with the demodulated signal. I found this particular receiver to have far superior reception over any other alternatives. On the market, one can see the whole range of wireless sensors, such as IR, door/window and flooding. For human-based interaction, I have found wireless panel buttons to be particularly useful.


The Arduino-based code to feed received codes to MQTT is trivial and, over the years of operation has proven to be super reliable. I have found node-red to be the most convenient way to implement the logic behind the actions triggered by sensors and buttons.

Tomato observatory


My Ph.D. course allowed me to enjoy the Mediterranean climate of Lugano. It has also triggered my green thumb and resulted in a number of flora world representatives inhabiting balconies at my apartment. The main problem for me was that my academic schedule sometimes required me to travel for extended periods (2 weeks+), and I could not count on my flatmates to water my plants.


A home-grown irrigation system was to come for help. Following the advice of my flatmate Matteo I have taken into consideration using Arduino, lack of WiFi, and good experience with RPi I have decided to use autonomous RPi for it. The prototype was quite simple…

But they have quickly evolved into observation and watering stations. Because RPi doesn’t have analog inputs, I have built an RC-charging circuit with a photo-resistor. Flipping directionality of a GPIO pin would discharge the capacitor. Afterward, it would slowly charge through the photo-resistor, reaching the TTL level at some point in time. The time it took to charge the capacitor is inversely correlated with the intensity of light. I used a simple python script to measure it. Later on, I have added additional soil humidity sensors but had no luck with getting reasonable measurements, Most likely because sensor surface corrosion having a much more significant influence than soil humidity itself.

Finally, I have noticed that the water flow is actually entirely dependent on the throughput of nozzles, and not-so-much on the time that the pump is running. To take water throughput into account, I have installed a small, rotation-encoder based flow-meter.

The logical view of the system follows:

Live webcam snapshots and current weather conditions are available online under:


The tomato observatory project in 2013 has resulted in pretty decent fruit yield and a time-lapse video:

Currently, the project (and tomatoes) have relocated to Zurich Enge, and it is broadcasting live from this location:, and collecting material for the new time-lapse.

The current set-up at our balcony looks like this:

To be done

  • Recently I have bought a water-level sensor and I’m planning to use it for issuing an early warning before the water runs out in the container.

  • the quality, and in particular reliability of the USB webcam connected to the Pi leaves a lot to be desired. It is going to be soon replaced with either the outdoor WiFi camera or a GoPro shooting through the window.

  • the system is not yet coupled to the home-automation MQTT bus running on our home RPi. It should be operated and calibrated with a web-app providing cross-platform (mobile & desktop) compatibility.

Wake-up light


Waking up early ain’t easy. Waking up before sunrise is even harder. If there is no natural light to wake up to, maybe at least an artificial would do. Inspired by the availability of the LED stripes, I decided to give it a try and got myself a 5v rated, 5m long, 150 led strip from here.


With a little experimentation, I have tapped the led stripe into the power supply together with the reliable ESP32s and Adafruit NeoPixel library. It can draw quite some current (3-5A in my case), so make sure that you have enough power at hand.


At first, everything seemed to run smoothly, but as soon as I wanted to connect it to home MQTT automation, I started having trouble with the reliable programming of the LED stripe. Specifically, what I was getting were utterly random colors. I have narrowed it down to the interference between WiFi and NeoPixel library. The reason for the interference was that the led programming (electric) handshake is extremely time-sensitive and interrupts generated by the WiFi and MQTT were disrupting it. I found no good way of solving this issue by switching off interrupt handling so I decided to give a try to an alternative LED library - FastLED. Initially, I had no luck with it either, but eventually, I found that there is a way to instruct it to disallow interrupts. It did the trick.

To be done

For now, the wake-up light is adjusted manually with the use of the wireless remote numeric-pad that I use to control the curtain mover. This is undoubtedly sub-optimal, and the ultimate plan is to connect it to the Actions on Google API, to be able to schedule and adjust the light with the use of an android phone.



  • most likely due to the noise generated by the power supply with little or no load, the LED strip would occasionally get the wrong color for few (one, two) LEDs. This, in turn, would make a bright flash in the middle of the night. Adding a sizeable stabilizing capacitor at the power supply should help with it.

  • due to the same power-line issue, I needed to use a separate power supply for the ESP32s. Luckily they are happy to share ground connectors, and it was no problem for the LED stripe control line.


  • for some reason building code that references FastLED in Platform.IO fails due to the multiple inclusions of libstdc++. I didn’t find the right solution for it. Luckily building with the original Arduino environment works just fine.

Past Pet-Projects

Bedroom curtains


It is quite simple - sliding bedroom curtains open and closed. Closed in the evening, open before the sunrise.


An ESP32s coupled with a 4-way relay switch. Powered by the two-voltage (12v and 5v) power supply and a resistor gives a four-speed, two-speed mover. Additionally, to estimate curtain move I have installed a rotation encoder together with an edge state detection switch.


Controlling curtains is done via wireless USB Numpad connected to our home network computer (RPi 2) that hosts Mosquitto MQTT broker. A simple python script collects keystrokes and transmits them over MQTT to the curtain controller.

The complete code repository for the project can be found here.


Status / To Be Done

As of now, the position of the curtains is not persisted, hence move has to be triggered and stopped manually. The mid-term plan is to implement document-based state persistence (MongoDB) and build a simple web-app (nodeJS & React) to control and calibrate curtains moves.

Decommissioned as of now - because of my son, we have settled for manually operated shutters. Stepping motor controls for it is a song of the future.

Bedroom alarm-clock radio (decommissioned in 2015)


The owl schedule all-so-typical for academics made it difficult for me to get myself out of bed. I found it quite enjoyable to be woken up with old-good-rock radio. Given a rather poor offer of local radio in Ticino, I grew fond of Virgin Radio Italy.


I have built a small RPi with a USB audio DAC and USB WiFi adapter and installed MPD on it. It served for years for a cron-scheduled wake-up radio. Later on, I have installed on it ShairPort and used it quite a bit with AirAudio. Finally, after a few relocations, the project was decommissioned and replaced with a Spotify compatible dongle (Audiocast) connected to my old, reliable stereo.