Introduction: Build a Apple HomeKit Temperature Sensor Device Using a ESP8266 and a BME280
In today's instructable, we will be making low cost temperature, humidity and moisture sensor based on either the AOSONG AM2302/DHT22 or BME280 temperature/humidity sensor, YL-69 moisture sensor and the ESP8266/Nodemcu platform. And for displaying the data, we will be using homebridge to integrate to Apple's HomeKit.
This supports multiple devices and device discovery using mDNS, with minimal configuration required in Homebridge.
Parts List
- NodeMCU / New Wireless module NodeMcu Lua WIFI Internet of Things development board based ESP8266 with pcb Antenna and usb port
- These are very cheap on Ali Express, only problem is that shipping takes 4-6 weeks
- Mobile Phone Charger
- Mini USB Cable
- AOSONG AM2302/DHT22 temperature/humidity sensor
Or as an alternative sensor
- Bosch BME280 Temperature, Humidity and Barometric Sensor
- YL-69 Moisture Sensor
- 2N3904 Transistor
- 1K Resistor
- Transistor and Resistor only needed of YL-69 Moisture Sensor
- 5 Pin Female to Female cable set ( 1.5' ) ( DHT )
- 4 Pin Female to Female cable set (1.5') ( BME 280 )
- Heat shrink tubing small
- Container to install NodeMCU
- I used a small plastic food container from dollarama
- 5 small nuts and bolts for mounting NodeMCU
Tools
- Soldering Iron
- Solder
- Wire Cutters
Step 1: Hardware Build - DHT22
Connecting the DHT22
1. Cut the 5 Pin Female to Female cable in half, creating a cable about 9 inches long.
2. On the connecter, pins 2 and 3 are unused and can be removed.
3. Bare about a 1/4" of each wire on the end opposite the connector.
4. With your soldering iron, tin each wire end and the terminals on the DHT22.
5. Cut about 3/4" of heat shrink tubing and push down the wires.
6. Solder the wires to the DHT22 as follows
Connecter Pin --> DHT22 Pin
1 ---> 2 ( Second from left )
4 ---> 1 ( First on the left )
5 ---> 4 ( First on the right )
7. Slide the heat shrink tubing over the DHT22 Pins and shrink the tubing with the soldering iron.
Step 2: Hardware Build - BME280
Connecting the BME280
1. Cut the 4 Pin Female to Female cable in half, creating a cable about 9 inches long.
2. Bare about a 1/4" of each wire on the end opposite the connector.
3. With your soldering iron, tin each wire end.
4. Solder the wires to the BME280 in this order, VCC, GND, SCL, SDA. These need to line up to pins in the connector.
Step 3: Hardware Build - YL-69
Step 4: Build Case
Step 5: Build NodeMCU Firmware
1. Using http://nodemcu-build.com, create a custom firmware containing at least these modules:
adc, ads1115, bit, bme280, dht, file, gpio, i2c, mdns, net, node, tmr, uart, websocket, wifi
2. Please use esptool to install the float firmware onto your nodemcu. There are alot of guides for this, so I won't repeat it here.
Step 6: Connect Sensors
DHT22
1. Position cable connector so that pin 1 connects to D2 on nodemcu, pin 4 with 3v3 and pin 5 with gnu.
BME280
1. Connect the BME280 to the nodeMCO, lining up the pins as follows:
3V3 -> VCC
GND -> GND
D5 -> SCL
D6 -> SDA
Step 7: Install Nodemcu Software
1. Download lua software package from NodeMCU Lua Code
2. Follow the installation instructions in the README located here
https://github.com/NorthernMan54/homebridge-mcuiot/tree/master/lua
Step 8: Testing
1. You can test from the command line with curl or wget, make sure you use the ip address from the Esplorer screen and not mine ;-)
curl 192.168.1.165<br> { "Hostname": "NODE-8689D", "Model": "BME", "Version": "1.2", "Data": {"Temperature": 22.15, "Humidity": 50.453, "Moisture": 8, "Status": 0, "Barometer": 1003.185, "Dew": 11.38 }}
2. In Esplorer you should see the following
GET / HTTP/1.1<br>Host: 192.168.1.165 User-Agent: curl/7.43.0 Accept: */*
Status: 0 Temp: 22.15 Humi: 50.453 Moisture: 8 Baro: 1003.185 Dew: 11.38
3. Using Esplorer install init.lua. The nodemcu portion of the build is now complete.
4. To test mDNS, I use this command on OS X
dns-sd -B _dht22._tcp
And for the 2 devices on the network, I receive the following output:
Browsing for _dht22._tcp DATE: ---Mon 19 Sep 2016--- 21:11:26.737 ...STARTING... Timestamp A/R Flags if Domain Service Type Instance Name 21:11:26.739 Add 3 4 local. _dht22._tcp. NODE-18A6B3 21:11:26.739 Add 2 4 local. _dht22._tcp. NODE-871ED8
Step 9: Homebridge-mcuiot Install
1. Install homebridge using:
npm install -g homebridge
I won't go into a lot of details around the initial install of homebridge and how to configure it to autostart etc. Their are a lot of other guides for this.
2. Install homebridge-mcuiot using:
npm install -g homebridge-mcuiot
3. Update your configuration file, see sample-config.json in this directory.
ie
"bridge": {<br> "name": "Bart", "username": "CC:22:3D:E3:CD:39", "port": 51826, "pin": "031-45-154" },
"description": "HomeBridge",
"platforms": [ { "platform": "mcuiot", "name": "mcuiot" } ],
"accessories": [ ]
}
4. Start homebridge, output should look like this
[10/20/2016, 10:15:20 PM] Loaded plugin: homebridge-mcuiot<br> [10/20/2016, 10:15:20 PM] Registering platform 'homebridge-mcuiot.mcuiot'
[10/20/2016, 10:15:20 PM] ---
[10/20/2016, 10:15:20 PM] Loaded config.json with 0 accessories and 0 platforms.
[10/20/2016, 10:15:20 PM] ---
[10/20/2016, 10:15:20 PM] Loading 0 platforms...
[10/20/2016, 10:15:20 PM] Loading 0 accessories...
Load homebridge-mcuiot.mcuiot
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:
┌────────────┐
│ 031-45-154 │
└────────────┘
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Starting mDNS listener
[10/20/2016, 10:15:20 PM] Homebridge is running on port 51826.
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-871ED8.local.:80/" rel="nofollow"> http://NODE-871ED8.local.:80/>
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-869815.local.:80/" rel="nofollow"> http://NODE-869815.local.:80/>
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-8689D.local.:80/" rel="nofollow"> http://NODE-8689D.local.:80/>
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-8689D BME
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-871ED8 DHT
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-869815 DHT
In my environment I have 3 devices running.
Step 10: Homebridge
On your iPhone/iPad start your favourite homekit client and pair you client to homebridge. You should see all the mcuiot devices.
Adding devices
Devices are auto discovered using mDNS, and will add new devices when they appear on mDNS. In the event that devices are not discovered, restarting homebridge will trigger a reconciliation between the plugin and mDNS, and add missing devices. Missing devices are not removed during startup, see below for how to remove non-existent devices.
Removing devices
Devices are removed using the 'Identify Accessory' function. When you use the function from your app, it checks to see if the device is truly not responding then removes the device.

Participated in the
IoT Builders Contest
41 Comments
Question 4 years ago
Hi! Could somebody explain to me how and where to configure HomeBridge? Do I need a Raspberry Pi or what? I am completely confused...
Question 4 years ago
Is it possible to load a sketch via Arduino IDE instead of flashing with esptool and can you provide the sketch‘s code?
Reply 4 years ago
I'm sorry but I wrote this in LUA and not c, which is used by Arduino and it is not possible to convert.
Reply 4 years ago
Thanks for reply.
Btw the link to the Lua GitHub Repo is dead...
Question 5 years ago
Hi!
I successfully made a wireless temperature sensor using your instructions and I powered it with USB battery pack that I usually use for charging my phone.
Is there a way to read a voltage input on ESP from the battery so that I know when the battery needs to be recharged and not to always be "surprised" when the sensor dies? :)
Reply 5 years ago
This should be feasible, but for the discussion can you open an issue on the GitHub site?
https://github.com/NorthernMan54/homebridge-mcuiot/issues
Reply 5 years ago
OK, will do so. Thanks!
5 years ago
Hi, I have a problem connecting WIFI, it says:
Heap Available: -start 17968
> Error finding AP
My passwords.lua is uploaded and configured (masked last digits of my wifi key):
-- Rename this to passwords.lua, and add your WIFI SSID and Password
local module = {}
module.SSID = {}
module.SSID["SSID1"] = { ssid="Knut", pwd = "1787269548654xxx" }
module.SSID["SSID2"] = { ssid="Flocke", pwd = "1787269548654xxx" }
return module
Do yo have any idea for me?
Maybe hard code only the first net?
Regards
Yannic
Edit:
print(key) gives me:
FRITZ!Box 7560 HV
Telekom_FON
Knut
FRITZ!Box 6490 Cable
WLAN-99D753
Flocke
devolo-f4068d7fb9a5
WLAN-651220
FRITZ!Box 7490
Nachti
Vodafone Homespot
FRITZ!Box WLAN 3370
Reply 5 years ago
Try this, both SSID's need to be replaced
local module = {}
module.SSID = {}
module.SSID["Knut"] = { ssid="Knut", pwd = "1787269548654xxx" }
module.SSID["Flocke"] = { ssid="Flocke", pwd = "1787269548654xxx" }
return module
Reply 5 years ago
Thanks, this helped a lot. Unfortunately, I have another problem with the homebridge-mcuiot plugin when installing on Raspberry pi (zero W and 3B+). On my mac, it installs without errors, but the pi says:
pi@raspberrypi:~ $ sudo npm install -g homebridge-mcuiot
> mdns@2.4.0 install /usr/lib/node_modules/homebridge-mcuiot/node_modules/mdns
> node-gyp rebuild
gypERR!clean error
gypERR!stack Error: EACCES: permission denied, rmdir 'build'
gypERR!System Linux 4.14.34-v7+
gypERR!command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gypERR!cwd /usr/lib/node_modules/homebridge-mcuiot/node_modules/mdns
gypERR!node -v v8.11.3
gypERR!node-gyp -v v3.6.2
gypERR!not ok
npmERR!code ELIFECYCLE
npmERR!errno 1
npmERR! mdns@2.4.0 install: `node-gyp rebuild`
npmERR! Exit status 1
npmERR!
npmERR! Failed at the mdns@2.4.0 install script.
npmERR! This is probably not a problem with npm. There is likely additional logging output above.
npmERR! A complete log of this run can be found in:
npmERR! /root/.npm/_logs/2018-06-13T15_11_36_107Z-debug.log
please help me :(
node -v:
v8.11.3
npm -v:
v5.6.0
Reply 5 years ago
This looks like a problem with installing the MDNS module, and I can think of a couple of things that may work. Try this
sudo su -
sudo npm install -g --unsafe-perm homebridge-mcuiot
Reply 5 years ago
Thank you, this helped. Is there any way to avoid this error without the --unsafe flag?
Reply 5 years ago
Unfortunately not
Question 5 years ago
As i found out, bme280.init is deprecated. Is there a change that you revise the bme.lua file?
source that bme280.init is deprecated: https://github.com/nodemcu/nodemcu-firmware/issues/1994
Answer 5 years ago
I just updated bme.lua to support the latest firmware. Please note that I needed to add a couple of new nodemcu modules in step 5 as well.
You should be good to go.
5 years ago
Hi there, i have another problem when using only the bme280 Sensor. By running the test.lua script everything seems to work. WLAN is connecting and Webserver is starting. But if i try to get some Values using CURL everything brakes together. Here is some Output from ESPlorer:
> dofile("test.lua")
Heap Available: -c 37656
Heap Available: -l 33776
Heap Available: -b 32400
Heap Available: -m 27112
Heap Available: -setup 22440
Booting...
Heap Available: -boot 22744
Setting Init Timer
Configuring Wifi ...
Heap Available: -start 22744
> Connecting to wlan ...
IP unavailable, Waiting...
====================================
Name is: NODE-XXXDC
ESP8266 mode is: 1
MAC address is: XX:XX:XX:XX:XX:XX
IP is: 192.168.1.xxx
====================================
Registering service dht22 with mDNS
Web Server Started
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; de-DE) WindowsPowerShell/5.1.17134.1
Host: 192.168.1.128
Connection: Keep-Alive
PANIC: unprotected error in call to Lua API (bme.lua:6: attempt to call field 'init' (a nil value))
So can anyone give me a Hint what is wrong?
Reply 5 years ago
I think i found sometthing, if i use the bmetest.lua file i get the same error. But, if i change:
____
bme280.init(config.bme280sda,config.bme280scl)
____
to:
____
i2c.setup(0, 6, 5, i2c.SLOW)
bme280.setup()
____
instead it works!
So i think the bme280.init thing is the problem. Im no programmer and what i found was in the bme280 Documentation of the NodeMCU Firmware and i did some fiddling with copy&paste. But how do i get this together in the bme.lua file which is needed for init.lua or test.lua?
5 years ago
Hello! I really hope you can help me with my problems trying this out. First i had problems using your scripts, as you have added "garagedooropener" script, which needed something i did not have. But i solved this by removing those scripts from "test.lua" so id did not try to call them. But now i keep getting errors as it is trying to call "config.lua" and i think maybe i have problems in adding my wifi said and password too, as it is not exactly as your guide anymore, i think. I hope you can follow my problems, and here is my last try at starting the server.
> file.remove("test.lua");file.open("test.lua","w+");
> w = file.writelinew([[]]);w([[config = require("config")]]);w([[print("Heap Available: -c " .. node.heap())]]);w([[led = require("led")]]);w([[print("Heap Available: -l " .. node.heap())]]);w([[bme = require("bme")]]);w([[print("Heap Available: -b " .. node.heap())]]);w([[app = require("main")]]);
> w([[print("Heap Available: -m " .. node.heap())]]);w([[setup = require("setup")]]);w([[print("Heap Available: -setup " .. node.heap())]]);w([[led.boot()]]);w([[print("Heap Available: -boot " .. node.heap())]]);w([[setup.start()]]);w([[print("Heap Available: -start " .. node.heap())]]);w([[-- Never gets here]]);file.close();dofile("test.lua");
Heap Available: -c 23912
Heap Available: -l 24928
Heap Available: -b 24928
Heap Available: -m 24928
Heap Available: -setup 24928
Booting...
Heap Available: -boot 24984
Setting Init Timer
Configuring Wifi ...
Heap Available: -start 24688
> PANIC: unprotected error in call to Lua API (setup.lua:37: bad argument #1 to 'config' (config table not found!))
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x40100000, len 26772, room 16
tail 4
chksum 0x74
load 0x3ffe8000, len 2192, room 4
tail 12
chksum 0x91
ho 0 tail 12 room 4
load 0x3ffe8890, len 136, room 12
tail 12
chksum 0x75
csum 0x75
����o�r��g|�dldl b��|{�l�o��o�l ��{�l�l�d`��;�d�d�$`��s�l���$l {$��sl���c��cp<cx���x���c��n�ng�l$��lDŽd��d����l�{sd�g����b$l��#���cl�crd;
NodeMCU custom build by frightanic.com
branch: master
commit: 2e67ff5a639a13260fd4fb3c3b627ccdc2845616
SSL: false
modules: adc,bit,bme280,dht,file,gpio,mdns,net,node,tmr,uart,wifi
build built on: 2017-10-07 11:12
powered by Lua 5.1.4 on SDK 2.1.0(116b762)
Reply 5 years ago
That error at setup.lua is definitely caused the wifi passwords section not being correct. I would suggest that you try to reformat the config.lua line again. It should look like this
module.SSID["Network Name"] = { ssid="Network Name", pwd = "password" }
If your SSID was linksys and the password was computer, it would look like this.
module.SSID["linksys"] = { ssid="linksys", pwd = "computer" }
Also to remove the Garage door sensor, comment out the gd= line in init.lua and you don't need to install ads1115.lua.
PS In github I have made some minor tweaks, that externalize the wifi password to a separate file and other changes. I also just tested with a new nodemcu and BME280. You don't need to update to this version.
Reply 5 years ago
And with that, all my problems were solved! I had to upgrade to your latest scripts, and even then is still said error in calling "config", but i just tried to boot it up a couple of times, and suddenly it worked. Now to make af custom case for it. I'm, thinking some form of Cement enclosure, polished and then treated with some clear coating. Thanks a lot for the help!