-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
41 changed files
with
12,946 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
# API Reference | ||
|
||
The `TTN_esp32` class enables ESP32 devices with supported LoRaWAN modules to communicate via The Things Network. This library is a wrapper for MCCI-Catena/arduino-lmic library. the pre-integrated boards are the same as mcci-catena library plus : | ||
|
||
- HELTEC Wifi Lora 32 (V1 & V2) | ||
- HELTEC Wireless Stick | ||
# Configuration | ||
Like MCCI-Catena/arduino-lmic library the configuration is setup by editing `project_config/lmic_project_config.h`. See https://github.com/mcci-catena/arduino-lmic#configuration for more informations | ||
|
||
## Class: `TTN_esp32` | ||
|
||
Include and instantiate the TTN_esp32 class. The constructor initialize the library with the Streams it should communicate with. | ||
|
||
```c | ||
#include <TTN_esp32.h> | ||
|
||
TTN_esp32 ttn; | ||
``` | ||
## Method: `begin` | ||
|
||
Start the LMIC stack with Pre-integrated boards (see https://github.com/mcci-catena/arduino-lmic#pre-integrated-boards) | ||
|
||
Following boards are tested : | ||
- HELTEC WIRELESS STICK | ||
- HELTEC WIFI LORA 32 V1 | ||
- HELTEC WIFI LORA 32 V2 | ||
|
||
|
||
```c | ||
void begin(); | ||
``` | ||
Initialize the stack with pointer to pin mapping (see https://github.com/mcci-catena/arduino-lmic#pin-mapping) | ||
```c | ||
bool begin(const TTN_esp32_LMIC::HalPinmap_t* pPinmap); | ||
``` | ||
Initialize the LMIC stack with pinout as arguments | ||
```c | ||
void begin(uint8_t nss, uint8_t rxtx, uint8_t rst, uint8_t dio0, uint8_t dio1, uint8_t dio2); | ||
``` | ||
Example for HELTEC WIRELESS STICK | ||
```c | ||
// wireless stick pinout | ||
#define UNUSED_PIN 0xFF | ||
#define SS 18 | ||
#define RST_LoRa 14 | ||
#define DIO0 26 | ||
#define DIO1 35 | ||
#define DIO2 34 | ||
... | ||
ttn.begin(SS, UNUSED_PIN, RST_LoRa, DIO0,DIO1,DIO2); | ||
``` | ||
## Method: `getAppEui` | ||
Gets the provisioned AppEUI. The AppEUI is set using `provision()` or `join()`. | ||
```c | ||
size_t getAppEui(char *buffer, size_t size); | ||
``` | ||
return AppEui as an array of char | ||
```c | ||
String getAppEui(); | ||
``` | ||
return AppEui as String | ||
## Method: `getDevEui` | ||
Gets the provisioned DevEUI. The DevEUI is set using `provision()` or `join()`. | ||
```c | ||
size_t getDevEui(char *buffer, size_t size, bool hardwareEUI=false); | ||
``` | ||
return DevEUI as array of char | ||
```c | ||
String getDevEui(bool hardwareEui=false); | ||
``` | ||
return DevEUI as String | ||
|
||
- `bool hardwareEui=false`: if true get DevEUI from Mac Address. | ||
|
||
## Method: `isJoined` | ||
Check whether we have joined TTN | ||
```c | ||
bool isJoined(); | ||
``` | ||
return `true` if joined to TTN, `false` if not. | ||
## Method: `showStatus` | ||
|
||
Writes information about the device and LoRa module to `Serial` . | ||
|
||
```c | ||
void showStatus(); | ||
``` | ||
|
||
Will write something like: | ||
|
||
```bash | ||
---------------Status-------------- | ||
Device EUI: 004D22F44E5DCE53 | ||
Application EUI: 70B3D57ED0015575 | ||
netid: 13 | ||
devaddr: 26011B24 | ||
NwkSKey: 6A2D3C24AD3C0D17614D7325BCAA976 | ||
AppSKey: 9E68DCBEBF8AE9D891252FB7E6054 | ||
data rate: 5 | ||
tx power: 14dB | ||
freq: 867100000Hz | ||
----------------------------------- | ||
``` | ||
|
||
## Method: `onMessage` | ||
|
||
Sets a function which will be called to process incoming messages. You'll want to do this in your `setup()` function and then define a `void (*cb)(const byte* payload, size_t length, port_t port)` function somewhere else in your sketch. | ||
|
||
```c | ||
void onMessage(void (*cb)(const uint8_t *payload, size_t size, int rssi)); | ||
``` | ||
- `const uint8_t* payload`: Bytes received. | ||
- `size_t size`: Number of bytes. | ||
- `int rssi`: the rssi in dB. | ||
See the [ttn-otaa](https://github.com/rgot-org/TheThingsNetwork_esp32/blob/master/examples/ttn-otaa/ttn-otaa.ino) example. | ||
## Method: `join` | ||
Activate the device via OTAA (default). | ||
```c | ||
bool join(); | ||
bool join(const char *app_eui, const char *app_key, int8_t retries = -1, uint32_t retryDelay = 10000); | ||
bool join(const char *dev_eui, const char *app_eui, const char *app_key, int8_t retries = -1, uint32_t retryDelay = 10000); | ||
``` | ||
|
||
- `const char *app_eui`: Application EUI the device is registered to. | ||
- `const char *app_key`: Application Key assigned to the device. | ||
- `const char *dev_eui`: Device EUI | ||
- `int8_t retries = -1`: Number of times to retry after failed or unconfirmed join. Defaults to `-1` which means infinite. | ||
- `uint32_t retryDelay = 10000`: Delay in ms between attempts. Defaults to 10 seconds. | ||
|
||
Returns `true` or `false` depending on whether it received confirmation that the activation was successful before the maximum number of attempts. | ||
|
||
Call the method without the first two arguments if the device's LoRa module is provisioned or comes with NVS stored values. See `provision`, `saveKeys` and `restoreKeys` | ||
|
||
## Method: `personalize` | ||
|
||
Activate the device via ABP. | ||
|
||
```c | ||
bool personalize(const char *devAddr, const char *nwkSKey, const char *appSKey); | ||
bool personalize(); | ||
``` | ||
- `const char *devAddr`: Device Address assigned to the device. | ||
- `const char *nwkSKey`: Network Session Key assigned to the device for identification. | ||
- `const char *appSKey`: Application Session Key assigned to the device for encryption. | ||
Returns `true` or `false` depending on whether the activation was successful. | ||
Call the method with no arguments if the device's LoRa module is provisioned or comes with NVS stored values. See `provisionABP`, `saveKeys` and `restoreKeys` | ||
See the [ttn_abp](https://github.com/rgot-org/TheThingsNetwork_esp32/tree/master/examples/ttn_abp) example. | ||
## Method: `sendBytes` | ||
Send a message to the application using raw bytes. | ||
```c | ||
bool sendBytes(uint8_t *payload, size_t length, uint8_t port = 1, uint8_t confirm = 0); | ||
``` | ||
|
||
- `uint8_t *payload `: Bytes to send. | ||
- `size_t length`: The number of bytes. Use `sizeof(payload)` to get it. | ||
- `uint8_t port = 1`: The port to address. Defaults to `1`. | ||
- `uint8_t confirm = false`: Whether to ask for confirmation. Defaults to `false` | ||
|
||
## Method: `poll` | ||
|
||
Calls `sendBytes()` with `{ 0x00 }` as payload to poll for incoming messages. | ||
|
||
```c | ||
int8_t poll(uint8_t port = 1, uint8_t confirm = 0); | ||
``` | ||
- `uint8_t port = 1`: The port to address. Defaults to `1`. | ||
- `uint8_t confirm = 0`: Whether to ask for confirmation. | ||
Returns the result of `sendBytes()`. | ||
## Method: `provision` | ||
Sets the informations needed to activate the device via OTAA, without actually activating. Call join() without the first 2 arguments to activate. | ||
```c | ||
bool provision(const char *appEui, const char *appKey); | ||
bool provision(const char *devEui, const char *appEui, const char *appKey); | ||
``` | ||
|
||
- `const char *appEui`: Application Identifier for the device. | ||
- `const char *appKey`: Application Key assigned to the device. | ||
- `const char *devEui`: Device EUI. | ||
## Method: `provisionABP` | ||
|
||
Sets the informations needed to activate the device via ABP, without actually activating. call `personalize()` without arguments to activate. | ||
```c | ||
bool provisionABP(const char *devAddr, const char *nwkSKey, const char *appSKey); | ||
``` | ||
- `const char *devAddr`: Device Address. | ||
- `const char *nwkSKey`: Network Session Key. | ||
- `const char *appSKey`: Application Session Key. | ||
## Method: `saveKeys` | ||
Save the provisioning keys (OTAA and ABP) in Non Volatile Storage (NVS). | ||
```c | ||
bool saveKeys(); | ||
``` | ||
## Method: `restoreKeys` | ||
Restore the keys from NVS and provisioning the informations for OTAA or ABP connection. Call `join()` or `Personalize()` after this method to activate the device. | ||
```c | ||
boobool restoreKeys(bool silent=true); | ||
``` | ||
- `bool silent=true`: silent mode (no log) | ||
93 changes: 93 additions & 0 deletions
93
examples/ttn-otaa-BLE-provisioning/ttn-otaa-BLE-provisioning.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/*************************************************************************************** | ||
To use this sketch you must install the TTN ESP32 BLE Provisioning APP from gGoogle Play | ||
https://play.google.com/store/apps/details?id=org.rgot.BLE_TEST | ||
this program was tested with heltech boards (Heltec Wifi Lora 32 & Heltec Wireless Stick) | ||
When running press the user button (named PROG on board) the on board Led Light | ||
and the Bluetooth Low Energy (BLE) is power on. | ||
On the Android application you can see a new device named "RGOT_xxx" where xxx is the hardware devEui. | ||
When you tap on this device, you can complete a form with devEUI, AppEui and AppKey. | ||
On the keyboard press Save (enter) to save the parameter. | ||
When finish press the back arrow, then the esp32 board reboot and take your new parameters. | ||
*/ | ||
#include "LoRaWan_BLE_esp32.h" | ||
#include <LoRaWan_esp32.h> | ||
#include "LoRaWan_CayenneLPP.h" | ||
|
||
// wireless stick pinout | ||
|
||
#define INTERVAL 30000 | ||
LoRaWan_esp32 ttn; | ||
LoRaWan_BLE_esp32 ble; | ||
LoRaWan_CayenneLPP lpp; | ||
|
||
void setup() { | ||
|
||
Serial.begin(115200); | ||
Serial.println("Starting"); | ||
ttn.begin(); | ||
if (ttn.restoreKeys()) {// provisioning with restored key from NVS | ||
Serial.println("devEui : "+ ttn.getDevEui()); | ||
Serial.println("appEui : "+ ttn.getAppEui()); | ||
ttn.join(); | ||
Serial.println("joining"); | ||
} | ||
else | ||
{ | ||
Serial.println("No key are provisioned, please press the User Button\n\ | ||
then launch the \'TTN ESP32 Prosioning\' Android App \n\ | ||
Select the RGOT_... device and provisioning the keys\n\ | ||
Quit the android App, then the esp32 restart... "); | ||
} | ||
pinMode(KEY_BUILTIN, INPUT); | ||
pinMode(LED, OUTPUT); | ||
digitalWrite(LED, LOW); | ||
} | ||
|
||
void loop() { | ||
static bool jonction = false; | ||
static float nb = 0.0; | ||
static unsigned previoumillis = 0; | ||
if (!digitalRead(KEY_BUILTIN) && !ble.getInitialized()) | ||
{ | ||
ttn.stop(); | ||
ble.begin(); | ||
digitalWrite(LED, HIGH); | ||
while (!digitalRead(KEY_BUILTIN)); | ||
|
||
} | ||
|
||
if (ttn.isJoined()) | ||
{ | ||
if (!jonction) | ||
{ | ||
ttn.showStatus(); | ||
jonction = true; | ||
} | ||
if (millis() - previoumillis > INTERVAL) | ||
{ | ||
if (ttn.isRunning()) | ||
{ | ||
nb += 0.1; | ||
lpp.reset(); | ||
lpp.addTemperature(1, nb); | ||
if (ttn.sendBytes(lpp.getBuffer(), lpp.getSize(), 1, 1)) { | ||
Serial.printf("envoi reussi : %d %x %02X%02X\n", lpp.getBuffer()[0], lpp.getBuffer()[1], lpp.getBuffer()[2], lpp.getBuffer()[3]); | ||
} | ||
} | ||
|
||
previoumillis = millis(); | ||
} | ||
} | ||
else { | ||
if (ttn.isRunning()) | ||
{ | ||
Serial.print("."); | ||
delay(500); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const char* config_devEui = "CHANGE_ME"; // Change to TTN Device EUI | ||
const char* config_appEui = "CHANGE_ME"; // Change to TTN Application EUI | ||
const char* config_appKey = "CHANGE_ME"; // Chaneg to TTN Application Key |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#pragma once | ||
/* | ||
Example for LyLigo T3S3 | ||
Arduino IDE options : | ||
T3-S3 Value | ||
Board ESP32S3 Dev Module | ||
Port Your port | ||
USB CDC On Boot Enable | ||
CPU Frequency 240MHZ(WiFi) | ||
Core Debug Level None | ||
USB DFU On Boot Disable | ||
Erase All Flash Disable | ||
Events Run On Core1 | ||
Flash Mode QIO 80MHZ | ||
Flash Size 4MB(32Mb) | ||
Arduino Runs On Core1 | ||
USB FW MSC On Boot Disable | ||
Partition Scheme Default 4M Flash with spiffs(1.2M APP/1.5MB SPIFFS) | ||
PSRAM QSPI PSRAM | ||
Upload Mode UART0/Hardware CDC | ||
Upload Speed 921600 | ||
USB Mode CDC and JTAG | ||
Programmer Esptool | ||
*/ | ||
// T3S3 with sx1262 | ||
#define BRD_sx1262_radio 1 | ||
#define RADIO_SCLK_PIN 5 | ||
#define RADIO_MISO_PIN 3 | ||
#define RADIO_MOSI_PIN 6 | ||
#define RADIO_CS_PIN 7 | ||
#define RADIO_DIO1_PIN 33 //SX1280 DIO1 = IO9 | ||
#define RADIO_BUSY_PIN 34 //SX1280 BUSY = IO36 | ||
#define RADIO_RST_PIN 8 | ||
// T3S3 with other LoRaWAN chip see : https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/blob/master/examples/T3S3Factory/utilities.h | ||
|
||
const lmic_pinmap lmic_pins = { | ||
// NSS input pin for SPI communication (required) | ||
.nss = RADIO_CS_PIN, | ||
// If needed, these pins control the RX/TX antenna switch (active | ||
// high outputs). When you have both, the antenna switch can | ||
// powerdown when unused. If you just have a RXTX pin it should | ||
// usually be assigned to .tx, reverting to RX mode when idle). | ||
// | ||
// The SX127x has an RXTX pin that can automatically control the | ||
// antenna switch (if internally connected on the transceiver | ||
// board). This pin is always active, so no configuration is needed | ||
// for that here. | ||
// On SX126x, the DIO2 can be used for the same thing, but this is | ||
// disabled by default. To enable this, set .tx to | ||
// LMIC_CONTROLLED_BY_DIO2 below (this seems to be common and | ||
// enabling it when not needed is probably harmless, unless DIO2 is | ||
// connected to GND or VCC directly inside the transceiver board). | ||
.tx = LMIC_CONTROLLED_BY_DIO2, // this constant is defined automaticaly when BRD_sx1262_radio is defined | ||
.rx = LMIC_UNUSED_PIN, | ||
// Radio reset output pin (active high for SX1276, active low for | ||
// others). When omitted, reset is skipped which might cause problems. | ||
.rst = RADIO_RST_PIN, | ||
// DIO input pins. | ||
// For SX127x, LoRa needs DIO0 and DIO1, FSK needs DIO0, DIO1 and DIO2 | ||
// For SX126x, Only DIO1 is needed (so leave DIO0 and DIO2 as LMIC_UNUSED_PIN) | ||
.dio = {/* DIO0 */ LMIC_UNUSED_PIN, /* DIO1 */ RADIO_DIO1_PIN, /* DIO2 */ LMIC_UNUSED_PIN}, | ||
// Busy input pin (SX126x only). When omitted, a delay is used which might | ||
// cause problems. | ||
.busy = RADIO_BUSY_PIN, | ||
// TCXO oscillator enable output pin (active high). | ||
// | ||
// For SX127x this should be an I/O pin that controls the TCXO, or | ||
// LMIC_UNUSED_PIN when a crystal is used instead of a TCXO. | ||
// | ||
// For SX126x this should be LMIC_CONTROLLED_BY_DIO3 when a TCXO is | ||
// directly connected to the transceiver DIO3 to let the transceiver | ||
// start and stop the TCXO, or LMIC_UNUSED_PIN when a crystal is | ||
// used instead of a TCXO. Controlling the TCXO from the MCU is not | ||
// supported. | ||
.tcxo = LMIC_CONTROLLED_BY_DIO3, //this constant is defined automaticaly when BRD_sx1262_radio is defined | ||
}; | ||
|
Oops, something went wrong.