ESP32-PaxCounter/README.md

343 lines
18 KiB
Markdown
Raw Normal View History

2018-03-25 20:40:21 +02:00
# ESP32-Paxcounter
2018-05-24 10:43:53 +02:00
**Wifi & Bluetooth driven, LoRaWAN enabled, battery powered mini Paxcounter built on cheap ESP32 LoRa IoT boards**
2018-03-18 19:45:17 +01:00
2018-06-03 16:01:32 +02:00
--> see development branch of this repository for latest alpha version <--
2018-03-25 20:35:56 +02:00
<img src="img/Paxcounter-title.jpg">
2018-07-16 18:51:47 +02:00
<img src="img/Paxcounter-ttgo.jpg">
2018-07-16 18:56:21 +02:00
<img src="img/Paxcounter-lolin.gif">
2018-08-04 14:37:41 +02:00
<img src="img/Paxcounter-Screen.png">
2018-03-18 19:45:17 +01:00
2018-03-22 22:19:21 +01:00
# Use case
2018-03-25 20:39:44 +02:00
Paxcounter is a proof-of-concept device for metering passenger flows in realtime. It counts how many mobile devices are around. This gives an estimation how many people are around. Paxcounter detects Wifi and Bluetooth signals in the air, focusing on mobile devices by filtering vendor OUIs in the MAC adress.
2018-03-22 22:19:21 +01:00
2018-03-25 20:39:44 +02:00
Intention of this project is to do this without intrusion in privacy: You don't need to track people owned devices, if you just want to count them. Therefore, Paxcounter does not persistenly store MAC adresses and does no kind of fingerprinting the scanned devices.
2018-03-22 22:19:21 +01:00
2018-11-04 20:35:41 +01:00
Data is transferred to a server via a LoRaWAN network, and/or a wired SPI slave interface.
2018-03-22 22:19:21 +01:00
2018-03-25 20:39:44 +02:00
You can build this project battery powered and reach a full day uptime with a single 18650 Li-Ion cell.
2018-03-22 22:19:21 +01:00
This can all be done with a single small and cheap ESP32 board for less than $20.
2018-03-18 19:45:17 +01:00
# Hardware
2018-07-15 22:19:05 +02:00
**Supported ESP32 based boards**:
2018-06-18 13:28:39 +02:00
2018-07-15 22:19:05 +02:00
*LoRa & SPI*:
- Heltec: LoRa-32
- TTGO: T3_v1, T3_v2, T3_v2.1, T-Beam
- Pycom: LoPy, LoPy4, FiPy
2018-07-15 22:22:16 +02:00
- WeMos: LoLin32 + [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora),
2018-07-15 22:21:00 +02:00
LoLin32lite + [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-Lora)
2018-10-06 21:40:56 +02:00
- Adafruit ESP32 Feather + LoRa Wing + OLED Wing, #IoT Octopus32 (Octopus + ESP32 Feather)
2018-07-15 22:19:05 +02:00
2018-11-04 20:35:41 +01:00
*SPI only*:
2018-07-15 22:19:05 +02:00
- Pyom: WiPy
- WeMos: LoLin32, LoLin32 Lite, WeMos D32
2018-11-04 20:35:41 +01:00
- Generic ESP32
2018-06-17 22:41:32 +02:00
Depending on board hardware following features are supported:
2018-11-04 20:35:41 +01:00
- LED (power/status)
- OLED Display (detailed status)
- RGB LED (colorized status)
2018-07-15 22:19:05 +02:00
- Button
- Silicon unique ID
- Battery voltage monitoring
- GPS (Generic serial NMEA, or Quectel L76 I2C)
2018-03-18 19:45:17 +01:00
2018-03-20 11:04:11 +01:00
Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).<br>
2018-09-19 16:33:56 +02:00
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.<br>
2018-03-20 11:04:11 +01:00
<b>3D printable cases</b> can be found (and, if wanted so, ordered) on Thingiverse, see
2018-08-11 20:01:07 +02:00
<A HREF="https://www.thingiverse.com/thing:2670713">Heltec</A>, <A HREF="https://www.thingiverse.com/thing:2811127">TTGOv2</A>, <A HREF="https://www.thingiverse.com/thing:3005574">TTGOv2.1</A>, <A HREF="https://www.thingiverse.com/thing:3041339">T-BEAM</A> for example.<br>
2018-03-18 19:45:17 +01:00
2018-10-24 18:52:07 +02:00
<b>Power consumption</b> was metered at around 450 - 1000mW, depending on board and user settings in paxcounter.conf. If you are limited on battery, you may want to save around 30% power by disabling bluetooth (commenting out line *#define BLECOUNTER* in paxcounter.conf).
2018-04-19 21:02:42 +02:00
# Preparing
2018-03-18 19:45:17 +01:00
2018-04-19 21:02:42 +02:00
Before compiling the code,
2018-03-18 19:45:17 +01:00
- **edit src/paxcounter.conf** and tailor settings in this file according to your needs and use case. Please take care of the duty cycle regulations of the LoRaWAN network you're going to use.
- **edit src/lmic_config.h** and tailor settings in this file according to your country and device hardware. Please take care of national regulations when selecting the frequency band for LoRaWAN.
2018-04-19 21:02:42 +02:00
- **create file loraconf.h in your local /src directory** using the template [loraconf.sample.h](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/loraconf.sample.h) and populate it with your personal APPEUI und APPKEY for the LoRaWAN network. If you're using popular <A HREF="https://thethingsnetwork.org">TheThingsNetwork</A> you can copy&paste the keys from TTN console or output of ttnctl.
2018-03-18 19:45:17 +01:00
2018-09-19 16:33:56 +02:00
- **create file ota.conf in your local /src directory** using the template [ota.sample.conf](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/src/ota.sample.conf) and enter your WIFI network&key. These settings are used for downloading updates. If you want to push own OTA updates you need a <A HREF="https://bintray.com/JFrog">Bintray account</A>. Enter your Bintray user account data in ota.conf. If you don't need wireless firmware updates just rename ota.sample.conf to ota.conf.
2018-09-19 13:59:34 +02:00
2018-04-06 10:46:43 +02:00
To join the network only method OTAA is supported, not ABP. The DEVEUI for OTAA will be derived from the device's MAC adress during device startup and is shown as well on the device's display (if it has one) as on the serial console for copying it to your LoRaWAN network server settings.
2018-04-06 10:43:07 +02:00
If your device has a fixed DEVEUI enter this in your local loraconf.h file. During compile time this DEVEUI will be grabbed from loraconf.h and inserted in the code.
If your device has silicon **Unique ID** which is stored in serial EEPROM Microchip 24AA02E64 you don't need to change anything. The Unique ID will be read during startup and DEVEUI will be generated from it, overriding settings in loraconf.h.
2018-04-19 21:02:42 +02:00
# Building
2018-06-10 19:17:28 +02:00
Use <A HREF="https://platformio.org/">PlatformIO</A> with your preferred IDE for development and building this code. Make sure you have latest PlatformIO version.
2018-04-19 21:02:42 +02:00
# Uploading
2018-09-18 18:43:51 +02:00
- **Initially, using USB/UART cable:**
To upload the code via cable to your ESP32 board this needs to be switched from run to bootloader mode. Boards with USB bridge like Heltec and TTGO usually have an onboard logic which allows soft switching by the upload tool. In PlatformIO this happenes automatically.<p>
2018-05-14 18:49:02 +02:00
The LoPy/LoPy4/FiPy board needs to be set manually. See these
2018-04-16 21:27:11 +02:00
<A HREF="https://www.thethingsnetwork.org/labs/story/program-your-lopy-from-the-arduino-ide-using-lmic">instructions</A> how to do it. Don't forget to press on board reset button after switching between run and bootloader mode.<p>
2018-05-14 18:49:02 +02:00
The original Pycom firmware is not needed, so there is no need to update it before flashing Paxcounter. Just flash the compiled paxcounter binary (.elf file) on your LoPy/LoPy4/FiPy. If you later want to go back to the Pycom firmware, download the firmware from Pycom and flash it over.
2018-09-18 18:43:51 +02:00
- **During runtime, using FOTA via WIFI:**
2018-09-19 16:33:56 +02:00
After the ESP32 board is initially flashed and has joined a LoRaWAN network, the firmware can update itself by FOTA. This process is kicked off by sending a remote control command (see below) via LoRaWAN to the board. The board then tries to connect via WIFI to a cloud service (JFrog Bintray), checks for update, and if available downloads the binary and reboots with it. If something goes wrong during this process, the board reboots back to the current version. Prerequisites for FOTA are: 1. You own a Bintray repository, 2. you pushed the update binary to the Bintray repository, 3. internet access via encrypted (WPA2) WIFI is present at the board's site, 4. WIFI credentials were set in ota.conf and initially flashed to the board. Step 2 runs automated, just enter the credentials in ota.conf and set `upload_protocol = custom` in platformio.ini. Then press build and lean back watching platformio doing build and upload.
2018-03-18 19:45:17 +01:00
# Legal note
**Depending on your country's laws it may be illegal to sniff wireless networks for MAC addresses. Please check and respect your country's laws before using this code!**
2018-03-22 14:12:12 +01:00
(e.g. US citizens may want to check [Section 18 U.S. Code § 2511](https://www.law.cornell.edu/uscode/text/18/2511) and [discussion](https://github.com/schollz/howmanypeoplearearound/issues/4) on this)
2018-03-18 19:45:17 +01:00
2018-03-22 14:12:12 +01:00
(e.g. UK citizens may want to check [Data Protection Act 1998](https://ico.org.uk/media/1560691/wi-fi-location-analytics-guidance.pdf) and [GDPR 2018](https://ico.org.uk/for-organisations/guide-to-the-general-data-protection-regulation-gdpr/key-definitions/))
2018-05-19 17:05:13 +02:00
(e.g. Citizens in the the Netherlands may want to read [this article](https://www.ivir.nl/publicaties/download/PrivacyInformatie_2016_6.pdf) and [this article](https://autoriteitpersoonsgegevens.nl/nl/nieuws/europese-privacytoezichthouders-publiceren-opinie-eprivacyverordening))
2018-03-18 19:45:17 +01:00
2018-03-18 21:19:56 +01:00
Note: If you use this software you do this at your own risk. That means that you alone - not the authors of this software - are responsible for the legal compliance of an application using this or build from this software and/or usage of a device created using this software. You should take special care and get prior legal advice if you plan metering passengers in public areas and/or publish data drawn from doing so.
2018-03-18 21:05:42 +01:00
2018-03-31 21:57:33 +02:00
# Privacy disclosure
2018-10-24 18:52:48 +02:00
Paxcounter generates identifiers for sniffed MAC adresses and collects them temporary in the device's RAM for a configurable scan cycle time (default 60 seconds). After each scan cycle the collected identifiers are cleared. Identifiers are generated by salting and hashing MAC adresses. The random salt value changes after each scan cycle. Identifiers and MAC adresses are never transferred to the LoRaWAN network. No persistent storing of MAC adresses, identifiers or timestamps and no other kind of analytics than counting are implemented in this code. Wireless networks are not touched by this code, but MAC adresses from wireless devices as well within as not within wireless networks, regardless if encrypted or unencrypted, are sniffed and processed by this code. If the bluetooth option in the code is enabled, bluetooth MACs are scanned and processed by the included BLE stack, then hashed and counted by this code.
2018-03-18 19:45:17 +01:00
2018-06-18 22:55:39 +02:00
# LED blink pattern
2018-05-20 22:30:13 +02:00
2018-06-18 22:55:39 +02:00
**Mono color LED:**
2018-05-20 22:30:13 +02:00
- Single Flash (50ms): seen a new Wifi or BLE device
- Quick blink (20ms on each 1/5 second): joining LoRaWAN network in progress or pending
- Small blink (10ms on each 1/2 second): LoRaWAN data transmit in progress or pending
- Long blink (200ms on each 2 seconds): LoRaWAN stack error
2018-07-24 23:25:41 +02:00
- Single long flash (2sec): Known beacon detected
2018-05-20 22:30:13 +02:00
2018-06-18 22:55:39 +02:00
**RGB LED:**
2018-05-20 22:30:13 +02:00
- Green each blink: seen a new Wifi device
- Magenta each blink: seen a new BLE device
- Yellow quick blink: joining LoRaWAN network in progress or pending
- Blue blink: LoRaWAN data transmit in progress or pending
- Red long blink: LoRaWAN stack error
- White long blink: Known Beacon detected
2018-05-20 22:30:13 +02:00
2018-06-18 22:55:39 +02:00
# Payload format
2018-03-18 19:45:17 +01:00
2018-08-05 19:39:28 +02:00
You can select different payload formats in [paxcounter.conf](src/paxcounter.conf#L12):
2018-06-17 22:41:32 +02:00
2018-06-18 13:13:13 +02:00
- ***Plain*** uses big endian format and generates json fields, e.g. useful for TTN console
2018-06-18 00:06:43 +02:00
2018-06-18 13:13:13 +02:00
- ***Packed*** uses little endian format and generates json fields
2018-06-18 00:06:43 +02:00
2018-06-18 13:13:13 +02:00
- [***CayenneLPP***](https://mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload-reference-implementation) generates MyDevices Cayenne readable fields
2018-06-17 22:41:32 +02:00
2018-06-18 22:55:39 +02:00
If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) (TTN) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. This way your MQTT application can parse the fields `pax`, `ble` and `wifi`.
2018-06-18 13:22:43 +02:00
2018-06-18 22:55:39 +02:00
To track a paxcounter device with on board GPS and at the same time contribute to TTN coverage mapping, you simply activate the [TTNmapper integration](https://www.thethingsnetwork.org/docs/applications/ttnmapper/) in TTN Console. The formats *plain* and *packed* generate the fields `latitude`, `longitude` and `hdop` required by ttnmapper.
2018-06-18 13:22:43 +02:00
2018-09-18 18:01:56 +02:00
Hereafter described is the default *plain* format, which uses MSB bit numbering. Under /TTN in this repository you find some ready-to-go decoders which you may copy to your TTN console:
[**plain_decoder.js**](src/TTN/plain_decoder.js) |
[**plain_converter.js**](src/TTN/plain_converter.js) |
2018-09-18 18:03:06 +02:00
[**packed_decoder.js**](src/TTN/packed_decoder.js) |
2018-09-18 18:01:56 +02:00
[**packed_converter.js**](src/TTN/packed_converter.js)
2018-06-16 19:50:36 +02:00
2018-07-15 19:08:18 +02:00
**Port #1:** Paxcount data
2018-03-18 19:45:17 +01:00
2018-06-10 16:00:11 +02:00
byte 1-2: Number of unique pax, first seen on Wifi
byte 3-4: Number of unique pax, first seen on Bluetooth [0 if BT disabled]
2018-07-15 19:14:50 +02:00
bytes 5-18: GPS data, format see Port #4 (appended only, if GPS is present and has a fix)
2018-07-15 19:08:18 +02:00
**Port #2:** Device status query result
byte 1-2: Battery or USB Voltage [mV], 0 if no battery probe
byte 3-10: Uptime [seconds]
2018-08-14 22:41:21 +02:00
byte 11: CPU temperature [°C]
bytes 12-15: Free RAM [bytes]
2018-09-17 17:23:02 +02:00
bytes 16-17: Last CPU reset reason [core 0, core 1]
2018-07-15 19:08:18 +02:00
**Port #3:** Device configuration query result
2018-07-15 19:43:16 +02:00
byte 1: Lora SF (7..12) [default 9]
byte 2: Lora TXpower (2..15) [default 15]
byte 3: Lora ADR (1=on, 0=off) [default 1]
byte 4: Screensaver status (1=on, 0=off) [default 0]
byte 5: Display status (1=on, 0=off) [default 0]
byte 6: Counter mode (0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed) [default 0]
bytes 7-8: RSSI limiter threshold value (negative) [default 0]
byte 9: Lora Payload send cycle in seconds/2 (0..255) [default 120]
byte 10: Wifi channel switch interval in seconds/100 (0..255) [default 50]
byte 11: Bluetooth channel switch interval in seconds/100 (0..255) [efault 10]
byte 12: Bluetooth scanner status (1=on, 0=0ff) [default 1]
byte 13: Wifi antenna switch (0=internal, 1=external) [default 0]
byte 14: Vendorfilter mode (0=disabled, 1=enabled) [default 0]
byte 15: RGB LED luminosity (0..100 %) [default 30]
byte 16: GPS send data mode (1=on, 0=ff) [default 1]
2018-07-31 00:06:05 +02:00
byte 17: Beacon proximity alarm mode (1=on, 0=off) [default 0]
bytes 18-28: Software version (ASCII format, terminating with zero)
2018-07-15 19:08:18 +02:00
**Port #4:** GPS query result
2018-07-15 19:15:59 +02:00
bytes 1-4: Latitude
bytes 5-8: Longitude
byte 9: Number of satellites
bytes 10-11: HDOP
bytes 12-13: Altitude [meter]
2018-07-15 19:08:18 +02:00
2018-07-24 19:31:17 +02:00
**Port #5:** Button pressed alarm
2018-07-21 18:25:03 +02:00
byte 1: static value 0x01
2018-07-31 00:06:05 +02:00
**Port #6:** Beacon proximity alarm
2018-07-24 19:31:17 +02:00
byte 1: Beacon RSSI reception level
2018-07-31 09:21:10 +02:00
byte 2: Beacon identifier (0..255)
2018-07-24 19:31:17 +02:00
2018-06-10 19:22:22 +02:00
# Remote control
2018-03-18 19:45:17 +01:00
2018-08-04 18:09:25 +02:00
The device listenes for remote control commands on LoRaWAN Port 2. Multiple commands per downlink are possible by concatenating them.
2018-03-18 19:45:17 +01:00
2018-09-16 17:08:37 +02:00
Note: all settings are stored in NVRAM and will be reloaded when device starts.
2018-03-18 19:45:17 +01:00
2018-04-15 12:12:06 +02:00
0x01 set scan RSSI limit
2018-03-18 19:45:17 +01:00
2018-04-15 12:12:06 +02:00
1 ... 255 used for wifi and bluetooth scan radius (greater values increase scan radius, values 50...110 make sense)
0 = RSSI limiter disabled [default]
2018-04-03 11:20:06 +02:00
2018-03-18 19:45:17 +01:00
0x02 set counter mode
0 = cyclic unconfirmed, mac counter reset after each wifi scan cycle, data is sent only once [default]
1 = cumulative counter, mac counter is never reset
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received
2018-06-10 19:20:22 +02:00
0x03 set GPS data on/off
2018-03-18 19:45:17 +01:00
2018-06-10 19:20:22 +02:00
0 = GPS data off
1 = GPS data on, appends GPS data to payload, if GPS is present and has a fix [default]
2018-03-18 19:45:17 +01:00
0x04 set display on/off
0 = display off
1 = display on [default]
0x05 set LoRa spread factor
7 ... 12 [default: 9]
0x06 set LoRa TXpower
2 ... 15 [default: 15]
0x07 set LoRa Adaptive Data Rate mode
0 = ADR off
2018-03-31 23:42:06 +02:00
1 = ADR on [default]
2018-05-21 20:35:33 +02:00
Note: set ADR to off, if device is moving, set to on, if not.
If ADR is set to on, SF value is shown inverted on display.
2018-03-18 19:45:17 +01:00
0x08 do nothing
useful to clear pending commands from LoRaWAN server quere, or to check RSSI on device
2018-09-16 17:08:37 +02:00
0x09 reset functions (send this command with confirmed ack only to avoid boot loops!)
2018-03-18 19:45:17 +01:00
0 = restart device
1 = reset MAC counter to zero
2 = reset device to factory settings
2018-08-05 12:16:54 +02:00
3 = flush send queues
2018-09-16 17:08:37 +02:00
9 = reboot device to OTA update via Wifi mode
2018-03-18 19:45:17 +01:00
2018-05-19 16:55:18 +02:00
0x0A set LoRaWAN payload send cycle
2018-03-18 19:45:17 +01:00
2018-04-28 13:07:35 +02:00
0 ... 255 payload send cycle in seconds/2
e.g. 120 -> payload is transmitted each 240 seconds [default]
2018-03-18 19:45:17 +01:00
0x0B set Wifi channel switch interval timer
2018-05-20 21:21:47 +02:00
0 ... 255 duration for scanning a wifi channel in seconds/100
e.g. 50 -> each channel is scanned for 500 milliseconds [default]
2018-03-18 19:45:17 +01:00
2018-05-19 16:55:18 +02:00
0x0C set Bluetooth channel switch interval timer
2018-03-18 19:45:17 +01:00
2018-05-20 21:21:47 +02:00
0 ... 255 duration for scanning a bluetooth advertising channel in seconds/100
e.g. 8 -> each channel is scanned for 80 milliseconds [default]
2018-03-18 19:45:17 +01:00
2018-04-15 12:12:06 +02:00
0x0D (NOT YET IMPLEMENTED) set BLE and WIFI vendorfilter mode
0 = disabled (use to count devices, not people)
1 = enabled [default]
2018-05-19 16:55:18 +02:00
0x0E set Bluetooth scanner
2018-03-18 19:45:17 +01:00
2018-04-02 21:29:06 +02:00
0 = disabled
1 = enabled [default]
2018-03-18 19:45:17 +01:00
2018-05-14 18:49:02 +02:00
0x0F set WIFI antenna switch (works on LoPy/LoPy4/FiPy only)
0 = internal antenna [default]
1 = external antenna
2018-05-14 18:49:02 +02:00
0x10 set RGB led luminosity (works on LoPy/LoPy4/FiPy and LoRaNode32 shield only)
2018-03-31 23:42:06 +02:00
2018-04-02 21:38:48 +02:00
0 ... 100 percentage of luminosity (100% = full light)
e.g. 50 -> 50% of luminosity [default]
2018-03-31 23:42:06 +02:00
2018-07-31 00:06:05 +02:00
0x11 set beacon proximity alarm mode on/off
0 = Beacon monitor mode off [default]
1 = Beacon monitor mode on, enables proximity alarm if test beacons are seen
2018-07-31 00:06:05 +02:00
0x12 set or reset a beacon MAC for proximity alarm
2018-07-31 00:00:24 +02:00
2018-07-31 09:21:10 +02:00
byte 1 = beacon ID (0..255)
2018-07-31 00:06:05 +02:00
bytes 2..7 = beacon MAC with 6 digits (e.g. MAC 80:ab:00:01:02:03 -> 0x80ab00010203)
2018-07-31 00:00:24 +02:00
2018-03-18 19:45:17 +01:00
0x80 get device configuration
Device answers with it's current configuration on Port 3.
2018-03-18 19:45:17 +01:00
2018-06-16 19:50:36 +02:00
0x81 get device status
Device answers with it's current status on Port 2.
2018-06-10 16:00:11 +02:00
0x84 get device GPS status
2018-06-08 22:41:37 +02:00
Device answers with it's current status on Port 4.
2018-06-08 22:41:37 +02:00
2018-03-18 19:45:17 +01:00
# License
Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
NOTICE:
Parts of the source files in this repository are made available under different licenses,
2018-03-18 19:47:23 +01:00
see file <A HREF="https://github.com/cyberman54/ESP32-Paxcounter/blob/master/LICENSE">LICENSE.txt</A> in this repository. Refer to each individual source file for more details.
2018-04-02 21:35:03 +02:00
# Credits
2018-06-04 21:26:40 +02:00
Thanks to
2018-06-04 21:29:28 +02:00
- [Oliver Brandmüller](https://github.com/spmrider) for idea and initial setup of this project
2018-06-04 21:26:40 +02:00
- [Charles Hallard](https://github.com/hallard) for major code contributions to this project
- [robbi5](https://github.com/robbi5) for the payload converter
- [terrillmoore](https://github.com/mcci-catena) for maintaining the LMIC for arduino LoRaWAN stack