Skip to content

Commit

Permalink
Protocol Buffer (nanopb) integration (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolasdejean authored and FokkeZB committed Nov 3, 2016
1 parent 7714097 commit 921e603
Show file tree
Hide file tree
Showing 20 changed files with 3,310 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -9,7 +9,8 @@ cache:
- "~/.platformio"

env:
- PLATFORMIO_CI_SRC=test
- PLATFORMIO_CI_SRC=test/TheThingsNetwork.ino
- PLATFORMIO_CI_SRC=test/TheThingsMessage.ino

install:
- pip install -U platformio
Expand Down
6 changes: 6 additions & 0 deletions Makefile
@@ -0,0 +1,6 @@
PROTOC = $(NANOPB)/generator-bin/protoc --proto_path=src/api --nanopb_out="-v:src"

.PHONY: proto

proto:
$(PROTOC) src/api/*.proto
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -13,7 +13,9 @@ This is an [Arduino Library](https://www.arduino.cc/en/Guide/Libraries) for Ardu
## Documentation

* [The Things Network Documentation / Arduino](https://www.thethingsnetwork.org/docs/arduino/)
* [API Reference](API.md)
* API References:
* [TheThingsNetwork](docs/TheThingsNetwork.md)
* [TheThingsMessage](docs/TheThingsMessage.md)

## Examples

Expand Down
61 changes: 61 additions & 0 deletions docs/TheThingsMessage.md
@@ -0,0 +1,61 @@
# API Reference
The `TheThingsMessage` class provides structs for sensor and application data you can encode and decode as bytes.

## Class: TheThingsMessage

```c
#include <TheThingsMessage.h>
```

## Type: sensordata_t

Create a struct of this type using `api_SensorData_init_default` as defaults.

```c
sensordata_t data = api_SensorData_init_default;
```

Then in your `setup()` function select what fields of the struct should be included when encoding it as bytes:

```c
data.has_motion = true;
data.has_water = false;
data.has_temperature_celcius = true;
data.has_temperature_fahrenheit = true;
data.has_humidity = true;
```

In your `loop()` function read your sensors and set the fields of the struct:

```c
data.motion = true;
data.water = 682;
data.temperature_celcius = 30
data.temperature_fahrenheit = 86;
data.humidity = 97;
```

### Additional analog readings

You can also add other analog readings.

> **TODO:** Document how this works and include in example.
## Method: encodeSensorData
Encode the message you want to send.

```c
static void encodeSensorData(sensordata_t *data, byte **buffer, size_t *size);
```
- `sensordata_t *data`: Structure containing all the message we can send.
- `const byte **buffer`: Bytes received.
- `size_t *size`: The number of bytes.
Usage:
```c
byte *buffer;
size_t size;
TheThingsMessage::encodeSensorData(&data, &buffer, &size);
```
File renamed without changes.
54 changes: 54 additions & 0 deletions examples/Message/Send/Send.ino
@@ -0,0 +1,54 @@
#include <TheThingsNetwork.h>
#include <TheThingsMessage.h>

// Set your AppEUI and AppKey
const char *appEui = "0000000000000000";
const char *appKey = "00000000000000000000000000000000";

#define loraSerial Serial1
#define debugSerial Serial

TheThingsNetwork ttn(loraSerial, debugSerial, /* TTN_FP_EU868 or TTN_FP_US915 */);

sensordata_t data = api_SensorData_init_default;

void setup() {
loraSerial.begin(57600);
debugSerial.begin(9600);

// Wait a maximum of 10s for Serial Monitor
while (!debugSerial && millis() < 10000);

debugSerial.println("-- STATUS");
ttn.showStatus();

debugSerial.println("-- JOIN");
ttn.join(appEui, appKey);

// Select what fields to include in the encoded message
data.has_motion = true;
data.has_water = false;
data.has_temperature_celcius = true;
data.has_temperature_fahrenheit = true;
data.has_humidity = true;
}

void loop() {
debugSerial.println("-- LOOP");

// Read the sensors
data.motion = true;
data.water = 682;
data.temperature_celcius = 30;
data.temperature_fahrenheit = 86;
data.humidity = 97;

// Encode the selected fields of the struct as bytes
byte *buffer;
size_t size;
TheThingsMessage::encodeSensorData(&data, &buffer, &size);

ttn.sendBytes(buffer, size);

delay(10000);
}
3 changes: 3 additions & 0 deletions keywords.txt
Expand Up @@ -7,6 +7,7 @@
#######################################

TheThingsNetwork KEYWORD1
TheThingsMessage KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
Expand All @@ -20,6 +21,8 @@ personalize KEYWORD2
sendBytes KEYWORD2
poll KEYWORD2

encodeSensorData KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
Expand Down
9 changes: 9 additions & 0 deletions src/TheThingsMessage.cpp
@@ -0,0 +1,9 @@
#include <TheThingsMessage.h>

void TheThingsMessage::encodeSensorData(sensordata_t *data, byte **buffer, size_t *size) {
byte message[51];
pb_ostream_t sendStream = pb_ostream_from_buffer(message, sizeof(message));
pb_encode(&sendStream, api_SensorData_fields, data);
*buffer = message;
*size = sendStream.bytes_written;
}
18 changes: 18 additions & 0 deletions src/TheThingsMessage.h
@@ -0,0 +1,18 @@
#ifndef _THETHINGSMESSAGE_H_
#define _THETHINGSMESSAGE_H_

#include <TheThingsNetwork.h>
#include <pb.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "sensorData.pb.h"

typedef api_SensorData sensordata_t;

class TheThingsMessage
{
public:
static void encodeSensorData(sensordata_t *data, byte **buffer, size_t *size);
};

#endif
13 changes: 13 additions & 0 deletions src/api/sensorData.proto
@@ -0,0 +1,13 @@
syntax = "proto2";

package api;

message SensorData {
optional bool motion = 1;
optional uint32 water = 2;
optional float temperature_celcius = 3;
optional float temperature_fahrenheit = 4;
optional float humidity = 5;

repeated uint32 analog_readings = 110;
}

0 comments on commit 921e603

Please sign in to comment.