guidosch / bikecounter

This repository contains the hardware and software components of a PIR based tracking device to monitor the usage of local bike trails. The data is sent over LoRaWAN to TTN and from there to a Google Cloud backend which stores the data and provides api endpoints for the data visualization web UI.
Creative Commons Zero v1.0 Universal
5 stars 0 forks source link

BikeCounter

action status

This repository contains the hardware and software components of a PIR based tracking device to monitor the usage of local bike trails. The data is sent over LoRaWAN to TTN and from there to a Google Cloud backend which stores the data and provides api endpoints for the data visualization web UI (bikeCounterUI).

The repository is divided into two main sections. The first one contains all the data regarding the hardware components and the second one holds the software code.

Hardware

The core component of the device is an Arduino MRKWAN 1310 which sits on the "logic layer" PCB. This PCB connects the micro controller to the sensors, the dip switches and the "power layer" PCB.

To detect the movement a PIR sensor from Seeed Studio is used and to monitor the internal environment of the device a temperature and humidity sensor from Adafruit was chosen.

The "power layer" PCB holds two rechargeable lithium-ion batteries (18650). This allows the device to run up to one year without exchanging the batteries.

The schematics and layout files of the PCBs as well as the BOM of the whole device can be found in the corresponding subfolder.

Software

This Repository contains the code for the tracking device as well as the scripts running on the backend.

Overview

flowchart LR;
  subgraph BikeCounter;
    Biker(Round) -->|infrared radiation| PIR-sensor;
    PIR-sensor -->|DIO| Arduino-MKRWAN-1310;
    Temp&Hum-sensor -->|I2C| Arduino-MKRWAN-1310;
    DIP-switches -->|DIO| Arduino-MKRWAN-1310;
  end; 
  subgraph TTN;   
    Arduino-MKRWAN-1310 -->|LoRaWAN| PayloadFormatter;
  end;  
  subgraph Google Cloud;
    PayloadFormatter -->|webhook| Cloud-function;
    Cloud-function --> firebase;
  end;

BikeCounter

There are two versions of the main BikeCounter software. The light version is a simple and basic implementation of the needed functionality. The pro version has extended features that allow it to take track of time as well as its environnement conditions.

(Due to the fact that the light version is almost obsolete only the pro version will be explained in more detail.)

Overall state machine

stateDiagram-v2
    m1: main loop
    [*] --> Setup
    Setup --> m1
    state m1 {
      state if_motion <<choice>>
      s0: motion detected ?
      s1: store information in variable      
      s2: timer called
      s3: threshold reached ?
      state if_threshold <<choice>>
      s4: send data
      state if_downlink <<choice>>
      s5: downlink received ?
      s6: correct rtc drift

      [*] --> s0
      s0 --> if_motion
      if_motion --> s1: true
      if_motion --> s2: false
      s2 --> s4
      s1 --> s3
      s3 --> if_threshold
      if_threshold --> deepSleep: false
      if_threshold --> s4: true
      s4 --> s5
      s5 --> if_downlink
      if_downlink --> deepSleep: false
      if_downlink --> s6: true
      s6 --> deepSleep
      deepSleep --> [*]
    }

After the main loop finishes the device goes into a deepSleep mode. From there the PIR sensor or the rtc timer can wake it back up and trigger the main loop again.

Data package

The payload size of one single LoRaWAN data package is restricted to 51 bytes. To avoid multi-package messages and to reduce transmission time an optimized information transmission protocol was developed.

The dataPackage class handles all the information conversion and encoding. A detailed documentation of the protocol can be found in the dataPackage.xlsx file.

Payload encoding

address
bits
0-7
[8]
8-11
[4]
12-15
[4]
16-18
[3]
19-23
[5]
24-27
[5]
28-30
[3]
31-54
[24]
55-57
[3]
58-62
[5]
63-408
[6/7/8/9/10]
content count software version hardware version status index battery voltage temperature humidity device time interval index hour of the day offset minutes array

The data type size of the offset array depends on the selected interval.

Time scheduler

During the night as well as the cold seasons of the year the data transmission interval can be adjusted to save energy and transmission time. The timeScheduler class provides all the necessary methods to accomplish such a dynamic behavior.

Device configuration

The configuration information to establish a connection to the TTN (AppEUI and AppKey) is saved to the flash memory of the Arduino MKRWAN 1310. The writeConfigToFlash.ino script saves a new configuration to the memory.

Unit tests

This repository contains serval unit tests for the dataPackage and the timeScheduler class. The tests are written using the Google Test framework. A cMake configuration for local testing is provided as well as an automated CI pipeline for the master branch. The runTestsLocal.sh script executes all the commands needed to run the unit tests locally.

To be aware of

TTN

The message from the device gets over LoRaWAN to the TTN server where a uplink payload formatter parses the data bytes to a human readable JavaScript object. The server then triggers a webhook and passes the data object to the Google Cloud function API endpoint.

The downlink message with the time drift information will also be parsed by the payload formatter defined in TTN.

The up/down-link payload formatter scripts are stored in the TTN subfolder.

Google Cloud

The triggered cloud function evaluates the data object sent from TTN and saves it to the Firebase database. Depending on the difference between the local time of the device and the server time it schedules a downlink message to correct the internal device time.

There are also cloud functions that provide an API endpoint for the web UI (bikeCounterUI) to visualize the stored data.

Setup IDE and compile code

Download and install: arduino-cli which is available for brew or apt-get. Install the arduino extension for VSCode and adjust the arduino.path in the extension settings and point to your arduino-cli installation folder.

Add the following libraries to your installation: arduino-cli lib install [libName]

Copy and adjust the .vscode/c_cpp_properties.json_example for your platform. You have to adjust the place where arduino-cli downloads the libraries as they are needed by the IDE

Compile: arduino-cli compile --fqbn arduino:samd:mkrwan1310 BikeCounterPro.ino

Deploy: arduino-cli upload -p [/dev/yourdevice] --fqbn arduino:samd:mkrwan1310 BikeCounterPro.ino

Hint: arduino-cli board list will show the USB port, where the device is connected

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update the tests as appropriate.

License

This project is licensed under CC0-1.0