Erlang application with an embedded Cowboy webserver for reading values from sensors and publishing to a Adafruit.io IoT-Dashboard. The program uses Erlang ALE module to read an analog sensor through the SPI-interface and a C driver program to read the DHT11-sensor. Being more low level, the C program reads more accurate values and outputs them as JSON. Erlang executes the C program and extracts the values using the JSX library.
- Prerequisites - Hardware
- Prerequisites - Software
- Wiring the Raspberry and the sensors
- Building
- Starting the server
- Automatic timer to continuously publish sensor values to Adafruit.io
- Testing the sensors from the Erlang Shell
- Accessing the sensors throught the embedded webserver
- Raspberry 3B/2B
- Full size breadboard, Buy from Adafruit
- Adafruit T-Cobbler Plus GPIO Breakout, Buy from Adafruit
- MCP3008 Analog to Digital Converter, Buy from Adafruit
- Keyes DHT11 Digital temperature and humidity sensor, Amazon
- Keyes Photo Resistor (analog light level sensor), Amazon
You must download and install Erlang in order to build and run this project.
For Raspberry Pi, you can download Erlang Mini (without gui packages) which is good for small embedded devices. Go to the download page, select "Raspbian" and follow the installation instructions.
To read values from sensors with Erlang, this project uses the Erlang ALE module. I highly recommend you to follow the directions in the modules repository to test it in a local repo before integrating it in your own project.
The software tries to publish values to Adafruit IoT Dashboard, so you will need an account and a dashboard. You can read Jeremy Morgans great blog post here on how to do that.
Wiring the Raspberry and the sensors ----- Start by connecting the Cobbler to the breadboard and then to the Raspberry PI
- Wire the Analog-to-Digital Converter (ADC) according to Adafruit's excellent guide. On a Raspberry 3, you can wire the ADC directly to the hardware SPI interface (see a separat section in the guide for that).
- Connect the Photo Resistor to channel 0 on the ADC.
- Connect the DHT11 to GPIO #4
- Git clone this repo and then build the code as described below.
$ make distclean
$ make
To start the release in the console:
$ chmod u+x run.sh
$ ./run.sh
or
$ ./_rel/webserver/bin/webserver console
By starting a timer, you can let Erlang read and publish sensor values continuously to Adafruit.io.
(webserver@127.0.0.1)1> iottimer:start(5000).
In this example, Erlang will read and publish new values every 5 seconds. To stop the timer, call the stop function:
(webserver@127.0.0.1)2> iottimer:stop().
After you have startet the server with one of the terminal commands above, you will be able to execute commands directly in the Erlang Shell:
pi@raspberrypi3:~/erlang_raspberrypi_temperature_sensor $ ./run.sh
....
/home/pi/erlang_raspberrypi_temperature_sensor/_rel/webserver
Erlang/OTP 18 [erts-7.3] [source] [smp:4:4] [async-threads:10] [kernel-poll:false]
Eshell V7.3 (abort with ^G)
(webserver@127.0.0.1)1>
Try running "mcp3008:readSPI(0)." to read a value from the light-level sensor connected to channel 0 on the ADC:
(webserver@127.0.0.1)1> mcp3008:readSPI(0).
{
"id": 649281259,
"value": "116",
"position": null,
"lat": null,
"lon": null,
"ele": null,
"feed_id": 592856,
"group_id": null,
"expiration": null,
"completed_at": null,
"created_at": "2016-06-12T11:57:21.688Z",
"updated_at": "2016-06-12T11:57:21.688Z",
"created_epoch": 1465732641.68893
}
Try running "dht11:read()." to read and publish humidity and temperature values:
(webserver@127.0.0.1)2> dht11:read().
{
"id": 649260154,
"value": "32.0",
"position": null,
"lat": null,
"lon": null,
"ele": null,
"feed_id": 592854,
"group_id": null,
"expiration": null,
"completed_at": null,
"created_at": "2016-06-12T11:51:11.719Z",
"updated_at": "2016-06-12T11:51:11.719Z",
"created_epoch": 1465732271.71952
}{
"id": 649260167,
"value": "26.0",
"position": null,
"lat": null,
"lon": null,
"ele": null,
"feed_id": 592855,
"group_id": null,
"expiration": null,
"completed_at": null,
"created_at": "2016-06-12T11:51:11.935Z",
"updated_at": "2016-06-12T11:51:11.935Z",
"created_epoch": 1465732271.93519
}