diff --git a/lora-gps/README.md b/lora-gps/README.md new file mode 100644 index 0000000..df8d243 --- /dev/null +++ b/lora-gps/README.md @@ -0,0 +1,45 @@ +# lora-gps senseBox + +This is a GPS tracked senseBox measuring particulate matter concentrations, +transmitting its data via LoRaWAN through [TheThingsNetwork] to [openSenseMap]. + +[TheThingsNetwork]: thethingsnetwork.org +[openSenseMap]: opensensemap.org + +It's based on +- Arduino Mega (Arduino Uno should work to, just use SoftwareSerial for the SDS011) +- Dragino LoRa- & GPS-Shield +- SD-card reader (I used the one on the senseBox-Shield. Any other one should work as well, change the `SD_PIN` in `config.h`) +- Novafit SDS011 particulate matter sensor +- HDC1008 temp- & humidity sensor + +For mobile power supply I used an Adafruit LiPo charger + 5.6Ah LiPo. + +## Sketch setup & opsensensemap integration + +- Register a device under + - register a new application first + - register a new device + - note down the following values: Device ID, Application ID, Device EUI, App EUI, App Session Key + - add the HTTP Integration to your application and point it to POST to `https://ttn.opensensemap.org/v1.1` + (no authentication headers are required) +- Register a senseBox at (or use the script `register-osem.sh`!) + - select `mobile` for exposure + - select the location where you plan the first deployment + - select the model `Luftdaten with SDS011 & DHT22` + - enable TheThingsNetwork Integration, and insert your Device ID and AppId, choose profile `lora-serialization`. + Insert the following into Decode Options: + ```json + [{"decoder":"latLng"},{"decoder":"temperature","sensor_title":"Temperatur"},{"decoder":"humidity","sensor_title":"rel. Luftfeuchte"},{"decoder":"temperature","sensor_title":"PM2.5"},{"decoder":"temperature","sensor_title":"PM10"}] + ``` + +- Insert the EUIs & App Session Key you received from TTN in `config.h` + +## Hardware Setup +- Flash the sketch using Arduino IDE +- Stack the senseBox Shield onto the Arduino, then stack the Dragino shield on top. +- Remove the `GPS_TX` and `GPS_RX` jumpers on the Dragino Shield, and wire these + pins instead to the Arduinos `RX3` and `TX3` pins. +- Wire the SDS011: RX & TX go to `RX2` and `TX2` on the Arduino, GND to GND, 5V to 5V ;) +- Connect the LiPo to the LiPo-Charger, and connect the USB Output to the Arduino +- Done! diff --git a/lora-gps/config.h b/lora-gps/config.h index 23dde08..74bc279 100644 --- a/lora-gps/config.h +++ b/lora-gps/config.h @@ -1,5 +1,9 @@ #include // for the key data type u1_t +#define SD_PIN 4 +#define SDS_SERIAL Serial3 +#define GPS_SERIAL Serial2 + // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 40; diff --git a/lora-gps/lora-gps.ino b/lora-gps/lora-gps.ino index 25a53c1..7d47ddc 100644 --- a/lora-gps/lora-gps.ino +++ b/lora-gps/lora-gps.ino @@ -1,7 +1,7 @@ /** lora-gps senseBox with SDS011 particulate matter + HDC1008 temp & humi sensors for Arduino Mega with Dragino LoRa shield. - SDS is on Serial3, GPS on Serial2 + SDS is on SDS_SERIAL, GPS on GPS_SERIAL */ #include "config.h" @@ -19,7 +19,7 @@ TinyGPSPlus gps; //Load sensors -SDS011 my_sds(Serial3); +SDS011 my_sds(SDS_SERIAL); HDC100X HDC(0x43); //measurement variables @@ -40,9 +40,9 @@ void do_send(osjob_t* j) { { // TODO //while (gps.location.isUpdated() && gps.location.isValid()) - while (Serial2.available()) + while (GPS_SERIAL.available()) { - char c = Serial2.read(); + char c = GPS_SERIAL.read(); if (gps.encode(c)) // Did a new valid sentence come in? newData = true; } @@ -104,14 +104,14 @@ void initSensors() { temperature = HDC.getTemp(); // initialize GPS Serial Port - Serial2.begin(9600); - while (!Serial2.available()) { + GPS_SERIAL.begin(9600); + while (!GPS_SERIAL.available()) { Serial.println("detecting GPS device..."); delay(1000); } Serial.println("Wait for GPS..."); while (!gps.location.isValid()) { - gps.encode(Serial2.read()); + gps.encode(GPS_SERIAL.read()); delay(1); } Serial.println("Got GPS fix!"); @@ -119,14 +119,14 @@ void initSensors() { // init SD card Serial.print("Initializing SD card..."); - if (!SD.begin(4)) { + if (!SD.begin(SD_PIN)) { Serial.println("failed!"); return; } Serial.println("done!"); // initalize SDS Serial Port - Serial3.begin(9600); + SDS_SERIAL.begin(9600); } void setup() { diff --git a/lora-gps/register-osem.sh b/lora-gps/register-osem.sh new file mode 100644 index 0000000..0240f3b --- /dev/null +++ b/lora-gps/register-osem.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +# configuration +OSEM_API=https://api.opensensemap.org +OSEM_USER=test@test +OSEM_PASS=asdfasdf +APP_ID=opensensemap-test +DEV_ID=mobile-feinstaub-2 + +# log in +OSEM_TOKEN=$(curl -H "content-type: application/json" $OSEM_API/users/sign-in -d '{"email":"'$OSEM_USER'","password":"'$OSEM_PASS'"}' | jq .token | tr -d '"') + +# create a new box +boxresult=$(curl -H "content-type: application/json" -H "Authorization: Bearer $OSEM_TOKEN" -XPOST $OSEM_API/boxes -d '{"name":"'$DEV_ID'","model":"luftdaten_sds011_dht22","exposure":"mobile","location":[51.9,7.6],"ttn":{"profile":"lora-serialization","app_id":"'$APP_ID'","dev_id":"'$DEV_ID'","decodeOptions":[{"decoder":"latLng"},{"decoder":"temperature","sensor_title":"Temperatur"},{"decoder":"humidity","sensor_title":"rel. Luftfeuchte"},{"decoder":"temperature","sensor_title":"PM2.5"},{"decoder":"temperature","sensor_title":"PM10"}]}}') + +OSEM_BOX=$(echo $boxresult | jq .data._id | tr -d '"') +OSEM_SENSOR=$(echo $boxresult | jq .data.sensors[1]._id | tr -d '"') + +echo "$OSEM_API/boxes/$OSEM_BOX/locations