Internet Of Things starts in general with sensors and micro-controllers.
This repository lists information to help setting up and hooking up Atmega (Arduino, Arduino Nano, Arduino Pro Mini), ESP8266 or ESP32.
Sorry if references are ommited.
Resources are also gathered from external sites, sometimes with more details.
1. Docker image
The docker image kalemena/arduino contains pre-installed Arduino IDE.
The image is setup with many libraries, plus subset of Arduino-compatible boards, including ESP8266 and ESP32.
2. Boards layout
There are tons of boards, and this repo lists only few layouts.
2.1. Arduino
2.2. ESP 8266
2.3. ESP 32
3. Guides
For all flavors of Atmega, just download Arduino IDE.
3.1. Setup Arduino IDE for ESP8266
Follow this guide to setup ESP8266 board in Arduino IDE
Documentation is here
3.1.1. Procedure
-
Import ESP Board into Arduino IDE
Add https://arduino.esp8266.com/stable/package_esp8266com_index.json to libraries.
-
Load the Libraries for ESP8266
-
Load sample hello app into NodeMCU
In Arduino IDE, select proper board, example:
- Tools/Cards/NodeMCU 1.0 board
- CPU 160 MHz
- <correct USB device>
Create sketch such as the ESP8266 LED
void setup() {
// initialize digital pin 2 as an output.
pinMode(2, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
LED should blink as shown below:
-
Control a Wifi LED
-
Upload sketch found at ESP8266 LED WIFI with changing Wifi network settings
-
Open Serial Consoleon Arduino IDE
-
Ensure from logs that NodeMCU connected to local Wifi
-
Browse to IP address logged out
-
Click on button to switch led On and Off
3.1.2. File System
3.2. Setup Arduino IDE for ESP32
This is very similar to ESP8266 setup.
3.2.1. Hardware
These work good:
-
Lolin 32S
-
Wemos 32 (clone of Wemos D1 Mini but with ESP32 instead of ESP8266)
Board details -
TTGO (the one which has a camera)
3.2.2. Procedure
-
Import ESP32 Board into Arduino IDE by adding URL into Settings:
https://dl.espressif.com/dl/package_esp32_index.json
-
Load the Libraries for ESP32 from panel Board Manager.
-
Load sample hello app into NodeMCU-32S
In Arduino IDE, select proper board, example:
- Tools/Cards/NodeMCU 32S board
- <correct USB device>
Create sketch such as the ESP8266 LED
void setup() {
// initialize digital pin 2 as an output.
pinMode(2, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
LED should blink as shown below:
3.2.3. Resources
3.3. Softwares
3.3.1. Fritzing
Super easy for integration of boards with sensors and few basic components.
Allows to layout breadboard, with colored wires, that one can understand and follow, prior to create schematic and PCB for printing.
3.3.2. Kicad
KiCad is advanced, although not as complex to catch as professional tools.
3.3.3. Arduino IDE
Arduino IDE setup is described at Setup Arduino IDE
3.4. Tips - Low-power
3.4.1. Info
On Deek-Robot board:
-
Cut the power led
-
!!! Do not cut the regulator !!! On deek-robot board, need to unsolder the regulator Vout instead
Links:
3.4.2. Measures
Below are measures for:
-
cheap e-Bay arduino 3.3v clone (deek-robot)
-
radio RFM69 wired
-
using Jeelab libs. Enhanced sleep.
-
various sensors
What? | Measure | Diff | Comments |
---|---|---|---|
Arduino + RFM69 |
5.1 uA |
NA |
Deek Robot with cuting led and regulator |
+ DHT22 |
17.2 uA |
+12uA |
|
+ HTU21D |
12.8 uA |
+8uA |
|
+ DS12B20 |
21.9 uA |
+17uA |
|
+ LDR |
26 uA |
+21uA |
Using 200k as pull-down |
+ TSL2561 |
17.4 uA |
+12uA |
|
+ Soil |
5.2 uA |
+0.1uA |
Soil 2 - simple probes with 10k resistor pull-up |
+ Toggle |
5.2 uA |
+0.1uA |
Toggle with 10M pull-up resistor! |
3.5. Radio - Bluetooth
3.6. Radio - CAN bus
3.6.1. Code
#include <SPI.h>
#include "mcp_can.h"
INT32U canId = 0x000;
unsigned char len = 0;
unsigned char buf[8];
char str[20];
void setup()
{
Serial.begin(38400);
START_INIT:
if(CAN_OK == CAN.begin(CAN_125KBPS))
{
Serial.println("Initialized successfully");
}
else
{
Serial.println("Initializing is failed");
Serial.println("Reloading...");
delay(100);
goto START_INIT;
}
}
void loop()
{
if(CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
canId = CAN.getCanId();
Serial.print("<");Serial.print(canId);Serial.print(",");
for(int i = 0; i<len; i++)
{
Serial.print(buf[i]);Serial.print(",");
}
Serial.print(">");
Serial.println();
}
}
3.7. Radio - I2C Connections
This is common pattern for communications between micro-controllers.
3.7.1. Links
3.7.2. ESP8266 to Arduino Nano
This works similarly between other 5v components:
-
Arduino Pro Mini
-
Arduino Nano
-
Wemos D1 mini (ESP8266)
-
NodeMCU 32S (ESP32)
Note: ESP8266 and ESP32 boards such as Wemos or NodeMCU seem to be using 5v level.
Basic Sketch can be found at I2C Master and Slave
Usage is simply:
-
to upload the master to ESP32 or ESP8266 and slave to Arduino
-
open 2 consoles and run on correct ports cat /dev/ttyUSBx for each master and slave.
-
One console should show Sending=XXX, while the other should be Received=XXX with obviously same XXX
3.8. Radio - RFM12/RFM69CW
Below uses RFM12B and RFM69CW layouts which are compatible pins and at 868MHz. |
3.8.1. Wiring
Antenna length: 433 1/4 wave = 164.7mm 868 1/4 wave = 82.2mm |
3.8.2. Sketch and Console
Setup emitter and receiver as seen at:
Console example result:
3.8.3. Links
Using Jeelib, enable RFM69/12 "compat" mode when using RFM69CW. |
Unresolved directive in readme.adoc - include::categories/devices/servo/readme.adoc[Devices - Servo Motor]
3.9. Sensors - Current
Multiple sensor exists:
-
INA219
3.9.1. Code
3.9.2. Links
3.10. Distance sensors
3.10.1. JSN-SR04T
JSN-SR04T |
Arduino |
5 V |
5 V |
Trig |
Pin 2 |
Echo |
Pin 3 |
GND |
GND |
3.11. Sensors - Light
3.11.1. LDR
-
60k < resistor < 400k (the higher the less power consumption, but less precise too)
-
then callibrate to have an output between 0 and 256
int LDR_Pin = A0; //analog pin 0
void setup(){
Serial.begin(9600);
}
void loop()
{
int32_t LDRReading = analogRead(LDR_Pin);
int32_t LDRfinal = map(LDRReading, 200, 1024, 0, 100);
Serial.println(LDRfinal);
delay(250);
}
3.11.2. TSL2561
This is standard i2c wiring.
-
For arduino: SCL=A5 and SDA=A4
-
For ESP12: SCL=D1 and SDA=D2
Links:
3.11.3. AS7262 6-Channel Visible Light / Color Sensor
Example:
Links:
3.12. Sensors - OnOff Switch
-
4,7M resistor
int TOGGLE_1_PORT = 7;
void setup(){
Serial.begin(9600);
pinMode(TOGGLE_1_PORT, INPUT);
}
void loop(){
int toggleState = digitalRead(TOGGLE_1_PORT);
Serial.println(toggleState);
delay(250);
}
3.13. Sensors - Soil
3.13.1. Soil Moisture
Schema #1 - Adafruit
Schema #2 - simple probes (no components)
Resistor can be 10k pull-up.
Sketch
int soil=0;
void setup() {
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int sensorValue = analogRead(A0);
sensorValue = constrain(sensorValue, 600, 1022);
soil = map(sensorValue, 600, 1022, 100, 0);
Serial.print(soil);
Serial.println("%");
delay(1000);
}
3.14. Sensors - Teleinfo
3.14.1. Summary
In France, few components can be used to extract Main Home power consumption.
It is especially useful to have information such as consumption by time periods where periods can be high or low cost hours.
3.14.2. Hardware
Central board:
-
Micro-Controller
-
Arduino Nano 5v
-
or ESP8266
-
or ESP32
-
-
Optocoupler: SFH6206
-
4.7k resistor
3.14.3. Sketch
#include <SoftwareSerial.h>
SoftwareSerial cptSerial(2, 3);
void setup() {
Serial.begin(1200); // opens serial port, sets data rate to 1200 bps
cptSerial.begin(1200);
}
void loop() {
if (cptSerial.available())
Serial.write(cptSerial.read() & 0x7F);
}
Examples:
3.14.4. Installation
Once wired to computer, find correct USB tty number (dmesg | grep tty), then execute commands:
$ stty -F /dev/ttyUSB0 1200 sane evenp parenb cs7 -crtscts
$ cat /dev/ttyUSB0
Then other library can be used to parse and digest the teleinfo data that looks like below:
ADCO 02092xxxxxx @
OPTARIF HC.. <
ISOUSC 45 ?
HCHC 010956910 %
HCHP 016779643 >
PTEC HP..
IINST 021 Z
IMAX 047 J
PAPP 04860 3
HHPHC A ,
MOTDETAT 000000 B
3.15. Sensors - Temperature
3.15.1. DS18B20
Temperature sensor.
Resources:
OneWire and Dallas libraries required to read DS18B20 sensor.
This is possible to wire several sensors together (not explained here).
Sketches to try this in example from libraries to install:
3.15.2. DHT22
Temperature and humidity sensor.
Resources:
For some reasons, the jeelib driver library didn’t work using above wiring. |
Sketches to try this in example from libraries to install:
3.15.3. SHT11
Temperature and humidity sensor.
Usage of Jeelib as driver.
3.15.4. BMP85
Temperature and pressure sensor.
HTU21D
Temperature and humidity sensor.
This is standard i2c wiring.
Board | SCL | SDA |
---|---|---|
Arduino |
A5 |
A4 |
ESP12 |
D1 |
D2 |
ESP32 |
D22 |
D21 |
3.16. Sensors - Wind
3.16.1. Links
3.18. Gateways - CurrentCost
The Current Cost allows to monitor main power home usage live and historical.
Every 2 hours, historical reports can be submitted to home computer using USB adapter.
Additional plugable sensor can be used to monitor more devices.
3.18.1. Schema
3.18.2. How-To
$ lsusb
$ dmesg
$ sudo stty -F /dev/ttyUSB0 57600
$ sudo chmod 777 /dev/ttyUSB0
$ cat /dev/ttyUSB0
3.18.3. Test
$ npm install serialport
$ npm install eyes
$ npm install xml2js
$ npm install mqtt
$ node pub-current-cost.js
3.19. Gateways - ESPHome
3.19.1. Hacks
Xiaomi Temp sensors
These are bluetooth TH sensors which can be flashed and centralized through ESPHome gateways:
3.19.2. Links
3.20. Gateways - Lego
3.20.1. ESP32 programming
The only thing to do is import Legoino lib from ArduinoIDE.
Then setup your ESP32 board and port, and upload example.
Example at Lego Boost
3.20.2. Python programming
This is few resources to get started with python for Lego Boost
the only pre-requisite is to get a BLED112 Bluetooth dongle. |
$ sudo pip3 install pygatt
$ sudo pip3 install -U pylgbst
from pylgbst.hub import MoveHub
import time
hub = MoveHub()
for device in hub.peripherals:
print(device)
hub.motor_A.timed(0.5, 0.8)
hub.motor_A.timed(0.5, -0.8)
hub.motor_B.angled(90, 0.8)
hub.motor_B.angled(-90, 0.8)
hub.motor_AB.timed(1.5, 0.8, -0.8)
hub.motor_AB.angled(90, 0.8, -0.8)
hub.motor_external.start_speed(0.2)
time.sleep(2)
hub.motor_external.stop()
3.21. Gateways - Somfy
Two models:
-
RTS
-
IOHomeControl
RTS has many open projects. Not IOHomeControl. |
There are Tahoma or other proprietary gateways.
However there seem to be simple-enough RF433-based alternatives.
3.21.1. References
3.22. Gateways - RfxTrx 433
RFXtrx433 is used to monitor and act on various proprietary systems such as:
-
Weather Station
-
Home Central Alarm
Listens on RfxTrx433 using nodejs and publishes to MQTT (mosquitto).
3.22.1. Hardware
3.22.2. Hardware
$ lsusb
$ dmesg
$ sudo stty -F /dev/ttyUSB1 38400 cs8
$ sudo chmod 777 /dev/ttyUSB1
-
Edit test script to point to USB devices or point Node-Red to correct USB device.
3.22.3. Software
Below is sample which listens on USB plugged RfxTrx433 and then publishes temperature/humidity/rain over MQTT.
#!/usr/bin/env node
var rfxcom = require("rfxcom"),
eyes = require('eyes'),
mqtt = require('mqtt');
var rfxtrx = new rfxcom.RfxCom("/dev/ttyUSB0", {debug: false} );
var client = mqtt.createClient('1883', 'localhost');
client.on('connect', function() {
console.log('Connected for publications...');
});
// Start RFXCom activity
rfxtrx.on("th2", function (evt) {
client.publish('sensors/' + parseInt(evt.id,16) + '/entries/1/events/temperature', '' + evt.temperature);
client.publish('sensors/' + parseInt(evt.id,16) + '/entries/1/events/humidity', '' + evt.humidity);
});
rfxtrx.on("temp2", function (evt) {
client.publish('sensors/' + parseInt(evt.id,16) + '/entries/1/events/temperature', '' + evt.temperature);
});
rfxtrx.on("rain2", function (evt) {
var value = { rainrate: evt.rainrate, raintotal: evt.raintotal };
client.publish('sensors/' + parseInt(evt.id,16) + '/entries/1/events/rain', JSON.stringify(value));
});
rfxtrx.initialise(function () {
console.log("Device initialized");
});
3.23. Gateways - ZigBee
3.23.1. Products
3.23.2. Software
3.23.3. Firmware
-
-
Unplug the ConBee II
-
Start the command (with -t parameter)
-
Plugin the ConBee II again
-
$ ls -l /dev/serial/by-id
...
usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2213620-if00 -> ../../ttyACM1
Notes:
- previous OK firmware: 0x26580700
- currently used: 0x266b0700
$ docker run -it --rm --entrypoint "/bin/bash" --privileged --cap-add=ALL -v $(pwd):/firmware -v /dev:/dev -v /lib/modules:/lib/modules -v /sys:/sys marthoc/deconz
root@69a522554758:/# /usr/bin/GCFFlasher_internal -d /dev/ttyACM0 -t 60 -R 10 -f /firmware/deCONZ_ConBeeII_0x266b0700.bin.GCF
GCFFlasher V3_17 (c) dresden elektronik ingenieurtechnik gmbh
Reboot device /dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2213620-if00 (ConBee II)
deCONZ firmware version 26580700
R21B18 Bootloader
Vers: 2.07
build: Jun 17 2019
flashing 164377 bytes: |==============================|
verify: .
SUCCESS
Wait 10 seconds until application starts
3.23.4. Usage
Running deCONZ as docker
$ sudo usermod -a -G dialout $USER
$ docker run -d \
--name=deconz \
-p 8080:8080 \
-p 8443:8443 \
--restart=always \
-v /etc/localtime:/etc/localtime:ro \
-v /opt/deconz:/root/.local/share/dresden-elektronik/deCONZ \
-e DECONZ_WEB_PORT=8080 \
-e DECONZ_WS_PORT=8443 \
-e DECONZ_DEVICE=/dev/ttyZigbee \
--device=/dev/ttyZigbee \
marthoc/deconz
version: "2"
services:
deconz:
image: marthoc/deconz
ports:
- 7080:7080
- 7443:7443
- 7900:5900
volumes:
- /etc/localtime:/etc/localtime:ro
- ./etc/deconz:/root/.local/share/dresden-elektronik/deCONZ
- /run/udev:/run/udev:ro # so that serial number vendor/product ids are known
device_cgroup_rules:
- 'c 166:* rmw' # allow creation of /dev/ttyACMx nodes via mknod
- 'c 188:* rmw' # allow creation of /dev/ttyUSBx nodes via mknod
devices:
- /dev/bus/usb
environment:
- DECONZ_WEB_PORT=7080
- DECONZ_WS_PORT=7443
- DECONZ_VNC_MODE=1
- DECONZ_VNC_PORT=5900
- DECONZ_VNC_PASSWORD=${ZIGBEE_DECONZ_VNC_PASSWORD:-password}
- DEBUG_INFO=1
- DEBUG_APS=0
- DEBUG_ZCL=0
- DEBUG_ZDP=0
- DEBUG_OTAU=0
Running as native
delight/delight
Tips
Browse to Configuration ⇒ Gateway, then Click on Advanced with pressing Shift+Alt
3.23.5. Deconz API
$ curl -d '{ "devicetype": "Node-RED"}' -H "Content-Type: application/json" -X POST http://deconz-server:40450/api
...
# Token is returned
$ curl -H "Content-Type: application/json" http://deconz-server:40450/api/XXAAXX/sensors | jq .
...
$ curl -H "Content-Type: application/json" -X POST http://deconz-server:40450/api/9598E1143E/touchlink/scan
3.23.6. Deconz WebSocket API
$ curl -H "Content-Type: application/json" http://deconz-server:40450/api/XXAAXX/config | jq .
{
"UTC": "2020-08-23T18:31:17",
"apiversion": "1.16.0",
"backup": {
"errorcode": 0,
"status": "idle"
},
"bridgeid": "XOXOXOXOXO",
"datastoreversion": "93",
"devicename": "RaspBee",
"dhcp": true,
...
"uuid": "606b08d1-5f14-4032-86cc-xxxxxx",
"websocketnotifyall": true,
"websocketport": 40460,
"whitelist": {
"XOXOXOXOXO": {
"create date": "2020-08-22T18:40:34",
"last use date": "2020-08-22T18:40:34",
"name": "Node-RED"
},
...
},
"zigbeechannel": 15
}
const WebSocket = require('ws');
const host = 'deconz-server';
const port = 40460;
const ws = new WebSocket('ws://' + host + ':' + port);
ws.onmessage = function(msg) {
console.log(JSON.parse(msg.data));
}
3.23.7. References
To put the ZigBee device in detect mode and assign from ConBee II web UI:
-
Magic Cube
Hold reset for 3s -
Temp/Humi/Pressure device
Hold reset until led light and blink -
Door sensor
Hold reset for about 5s
-
Lidl 220v plug
Hold button for 5s until power light blinks -
Livarno Color Light Bulb
When light up, shutdown, 3s, light up, 3s … 3x time and keep up the last round, light should blink slowly
-
Tradfri Light bulb:
Reset and re-assign controller by light-on, then 6x light-off/on and stay on the 6th time. Bulb blinks. -
Tradfri Dimmer switch
Click 4x times on reset button + light blinks -
Tradfri Remote ON/OFF switch
Open device (screw), Click 4x times on reset button + light blinks -
Tradfri outlet
Hold paper clip for 5s to enter registration mode.
-
3 Gang Portable Remote:
Open the remote, click 5s on reset button -
4 Gang Wall Remote:
Hold the Button 1 (bottom left) for 10s until blink -
Curtain Gang:
Touch 5s the pause button to put in register. Calibration tips
- First ensure you curtain is fully closed.
- Set the calibration to "start" and click Write. Now you are in Calibration mode.
- Above, click on the Exec button in the function Up / Open. In the calibration mode the 30 secondes duration is disable.
- Once your curtain is fully open click on the "Exec" button in the function "Stop"
- Click on the Exec button in the function Down / Close
- Once your curtain is fully closed click on the "Exec" button in the function "Stop"
- Set the calibration to "end" and click Write
3.24. Gateways - Z-Wave
3.24.1. Products
Procedures
Here are procedures to setup Z-Wave network:
-
Z-Stick gen5 click 1s → blue slow blink continuously
-
Click "sync" on GreenWave plug → Stick shows blue long, then blue slow blink continuously
-
done
-
Z-Stick gen5 click 3s → orange fast blink continuously
-
Click "sync" on GreenWave plug → Stick shows blue long, then orange fast blink continuously
-
done
3.24.2. Libraries
Python
$ sudo apt-get install --force-yes -y make libudev-dev g++ libyaml-dev
$ pip3 install python_openzwave
$ pip3 install urwid
# Check
$ pyozw_check -i -d /dev/ttyACM0
$ pyozw_check -l -d /dev/ttyACM0 -t 60
# Browse and set Switch
$ pyozw_shell -d /dev/ttyACM0
$$ cd nodes
$$ cd 5
$$ cd User
$$ set Switch to True
Control Panel
$ docker run --rm -it -p 8090:8090 --device=/dev/ttyACM0 ruimarinho/openzwave
Browse to http://localhost:8090 and switch on/off things from UI.
Node JS - open-zwave
$ git clone https://github.com/OpenZWave/node-openzwave-shared.git
$ cd node-openzwave-shared
$ sudo apt-get install openzwave
$ npm install libopenzwave-share
$ vi test2.js
# edit to ensure usage below
>> var ZWave = require('openzwave-shared');
$ node
> .load test2.js
# the 1st node is the USB controller stick
> console.log(nodes[1])
{ manufacturer: 'Aeotec',
manufacturerid: '0x0086',
product: 'Z-Stick Gen5',
producttype: '0x0001',
productid: '0x005a',
type: 'Static PC Controller',
name: '',
loc: '',
classes: { '32': { '0': [Object] } },
ready: true }
# if Zwave Node #3 is a binary switch, to turn it on and off, use command class 37
> zwave.setValue(6, 37, 1, 0, true); // node 3: turn on
Tuning
$ sudo apt-get install cu
$ echo -e '\x01\x08\x00\xF2\x51\x01\x00\x05\x01\x51'|cu -l /dev/ttyZWave -s 115200