Ambient lighting controlled by Siri

In this post I will walk you through the moving parts required to build an ambient light system. The light will be controlled by any of the following:

  • Siri (via HomeKit) – voice activation and configuration (power state, brightness, colour)
  • HomeKit – software activation and configuration (power state, brightness, colour)
  • Touch sensor – hardware activation and configuration (power state, brightness)

This is not a step-by-step guide but rather a description of the components involved and how the whole thing is put together.


The image bellow describes the overall architecture depicting the MQTT server as the central integration point.

The communication pattern is designed to adhere to the MQTT Smart Home Architecture, described here.

Architecture diagram illustrating the ambient light system

Ambient lights architecture


The Arduino is the controlling unit and uses the ESP8266 chip to achieve wireless connectivity. There will be only one power supply (5v 10a) powering the Arduino, ESP8266 and the LED strip. Therefore, a 3.3v voltage regulator is necessary for the ESP8266 chip, a capacitor should be used together with the regulator to smooth out any ripples.

The WS2812B strip supports addressing every LED individually, however, this functionality was not used and the strip is controlled as a whole. The strip is by far the most power hungry of all components and special care should be taken to pair it with a suitable power supply.  Keep in mind that each LED is actually composed out of 3 coloured LEDs (red, green, blue) that draw up to 60 milliamps at maximum brightness white.

The capacitive touch switch is used to manually turn the strip on or off, or to adjust the brightness level. A short sensor touch will cause the power to be toggled on/off while keeping the sensor touched will cause the brightness to gradually increase.

The Raspberry Pi does not play an active role in the hardware setup. It is used to host various software programs and can easily be replaced by a desktop, laptop or NAS.


Controlling the ambient light system is performed by a suite of software:

  • LEDStripController – runs on the Arduino and is responsible for communicating with the LED strips, publishing and responding to MQTT messages, and responding to the touch sensor inputs.
  • Espduino – firmware and software for the ESP01 chip to avoid working with AT commands.
  • Mosquitto – MQTT server, running on the Raspberry Pi.
  • Homekit2mqtt – HomeKit to MQTT bridge, running on the Raspberry Pi.

If you are going for a similar setup, keep in mind that Espduino is discontinued! I recommend using an ESP12 instead of the Arduino+Esp01 combination.

In case of network loss ESP01 automatically tries to reconnect to the wifi, however there are times when the chip stops responding entirely. To mitigate this issue a “watchdog” was set in place to hard reboot the chip (power cycle) when it stops responding.

In the general usage pattern a burst of messages are sent to the controlling pair (ESP01+Arduino) and processing those messages is prioritised over updating the hardware (actually turning the LED strip on and configuring each LED according to the chosen colour and brightness). This debounce is controlled by the HARDWARE_UPDATE_DEBOUNCE parameter.

Touching the touch sensor for a short period of time triggers a power toggle, while keeping the sensor touched causes it to cycle the brightness in steps. It takes 10 steps to go from the lowest to the highest brightness level.


Here are a few pictures from the assembly process

Assembly process #1

Assembly process #2

Assembly process #3


MQTT on QNAP via Moquette

Message Queuing Telemetry Transport (MQTT) is a lightweight pub/sub messaging protocol designed for minimal bandwidth and device resource requirements. This makes it ideal for IoT projects, where you generally have limited processing power and memory space (read more about MQTT).

There are several MQTT broker/server implementations out there (hopefully exhaustive list), however most of then cannot be ran on my QNAP TS221 Network Attached Storage because it uses a custom version of Linux and it is run by an ARM processor.

On the other hand, Moquette is a MQTT broker written in Java, so I gave it a try.

  1. Install the Java Runtime Environment for ARM – for some reason I could not find it in the App Center, so I had to download the package from here (dead link) and install it via the Install Manually button.
  2. SSH into the QNAP (guide)
  3. Follow the steps listed in the Moquette repo
    1. wget –no-check-certificate
    2. tar xvfz distribution-0.8-bundle-tar.tar.gz
    3. By default Moquette uses port 8080 for WebSocket which is also used by the QNAP administration interface, so I changed the Moquette port to 9090 by navigating to /config and setting websocket_port to 9090 in moquette.conf
    4. navigate to /bin and run
  4. By now you should have a working MQTT broker, you can test it with this online tool.
  5. Optionally you can configure your to be run at startup

Arduino – DHT22 temperature and humidity sensor driver

DHT22/AM2302  is an inexpensive temperature and relative humidity sensor. The sensor, which can be bought on ebay, implements a digital communication protocol by pulling high or low on a data line. The protocol is described here and it has three states:

  1. transmission start – initiated by a host and acknowledged by the sensor
  2. data transfer – binary transmission
  3. transmission end – performed by the sensor


The communication protocol instructs that the data line needs to always be kept high using a pull up resistor (this is because the sensor will pull low on the line to transmit data). However, in this specific implementation, an external pull up resistor is not needed because the driver makes usage of the internal pull up resistor of the Arduino pin.

The cables need to be connected as follows:

  • pin1 = VDD
  • pin2 = data
  • pin3 = not used
  • pin4 = GNDarduino_dht22


  • First you need to download the driver source code from here or you can browse it here.
  • Next, copy the unzipped contents to your Arduino libraries directory in a subdirectory named DHTSensor.
  • Restart your IDE

You are now ready to do a reading

As it can be observed from the example, the temperature of the measurement result can be interpreted in Celsius, Fahrenheit or Kelvin degrees, while the humidity is percentual.

Furthermore, the sensor can also be powered by a digital pin using the following construct

Keep in mind that a sensor measurement will take around a second and during this time the execution is not yielded back (your board will stop processing anything else). The one second is due to how the sensor is engineered to communicate and the non-yielding execution is due to the implementation of the driver.


Implementing the driver was performed as an educational project and it comes with no guarantees. You are free to use and modify it in any way it makes sense for you.