forked from mcci-catena/arduino-lmic
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example for usage of this library with a single-channel gateway
- Loading branch information
Showing
2 changed files
with
262 additions
and
1 deletion.
There are no files selected for viewing
261 changes: 261 additions & 0 deletions
261
examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.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,261 @@ | ||
/******************************************************************************* | ||
* The Things Network - ABP Feather | ||
* | ||
* Example of using an Adafruit Feather M0 and DHT22 with a | ||
* single-channel TheThingsNetwork gateway. | ||
* | ||
* This uses ABP (Activation by Personalization), where session keys for | ||
* communication would be assigned/generated by TTN and hard-coded on the device. | ||
* | ||
* Learn Guide: https://learn.adafruit.com/lora-pi | ||
* | ||
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman | ||
* Copyright (c) 2018 Terry Moore, MCCI | ||
* Copyright (c) 2018 Brent Rubell, Adafruit Industries | ||
* | ||
* Permission is hereby granted, free of charge, to anyone | ||
* obtaining a copy of this document and accompanying files, | ||
* to do whatever they want with them without any restriction, | ||
* including, but not limited to, copying, modification and redistribution. | ||
* NO WARRANTY OF ANY KIND IS PROVIDED. | ||
*******************************************************************************/ | ||
#include <lmic.h> | ||
#include <hal/hal.h> | ||
#include <SPI.h> | ||
|
||
// include the DHT22 Sensor Library | ||
#include "DHT.h" | ||
|
||
// DHT digital pin and sensor type | ||
#define DHTPIN 10 | ||
#define DHTTYPE DHT22 | ||
|
||
// | ||
// For normal use, we require that you edit the sketch to replace FILLMEIN | ||
// with values assigned by the TTN console. However, for regression tests, | ||
// we want to be able to compile these scripts. The regression tests define | ||
// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- | ||
// working but innocuous value. | ||
// | ||
#ifdef COMPILE_REGRESSION_TEST | ||
# define FILLMEIN 0 | ||
#else | ||
# warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" | ||
# define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) | ||
#endif | ||
|
||
// LoRaWAN NwkSKey, network session key | ||
static const PROGMEM u1_t NWKSKEY[16] = { FILLMEIN }; | ||
|
||
// LoRaWAN AppSKey, application session key | ||
static const u1_t PROGMEM APPSKEY[16] = { FILLMEIN }; | ||
|
||
// LoRaWAN end-device address (DevAddr) | ||
// See http://thethingsnetwork.org/wiki/AddressSpace | ||
// The library converts the address to network byte order as needed. | ||
static const u4_t DEVADDR = FILLMEIN ; // <-- Change this address for every node! | ||
|
||
// These callbacks are only used in over-the-air activation, so they are | ||
// left empty here (we cannot leave them out completely unless | ||
// DISABLE_JOIN is set in config.h, otherwise the linker will complain). | ||
void os_getArtEui (u1_t* buf) { } | ||
void os_getDevEui (u1_t* buf) { } | ||
void os_getDevKey (u1_t* buf) { } | ||
|
||
// payload to send to TTN gateway | ||
static uint8_t payload[5]; | ||
static osjob_t sendjob; | ||
|
||
// Schedule TX every this many seconds (might become longer due to duty | ||
// cycle limitations). | ||
const unsigned TX_INTERVAL = 30; | ||
|
||
// Pin mapping for Adafruit Feather M0 LoRa | ||
const lmic_pinmap lmic_pins = { | ||
.nss = 8, | ||
.rxtx = LMIC_UNUSED_PIN, | ||
.rst = 4, | ||
.dio = {3, 6, LMIC_UNUSED_PIN}, | ||
.rxtx_rx_active = 0, | ||
.rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB | ||
.spi_freq = 8000000, | ||
}; | ||
|
||
// init. DHT | ||
DHT dht(DHTPIN, DHTTYPE); | ||
|
||
void onEvent (ev_t ev) { | ||
Serial.print(os_getTime()); | ||
Serial.print(": "); | ||
switch(ev) { | ||
case EV_SCAN_TIMEOUT: | ||
Serial.println(F("EV_SCAN_TIMEOUT")); | ||
break; | ||
case EV_BEACON_FOUND: | ||
Serial.println(F("EV_BEACON_FOUND")); | ||
break; | ||
case EV_BEACON_MISSED: | ||
Serial.println(F("EV_BEACON_MISSED")); | ||
break; | ||
case EV_BEACON_TRACKED: | ||
Serial.println(F("EV_BEACON_TRACKED")); | ||
break; | ||
case EV_JOINING: | ||
Serial.println(F("EV_JOINING")); | ||
break; | ||
case EV_JOINED: | ||
Serial.println(F("EV_JOINED")); | ||
break; | ||
/* | ||
|| This event is defined but not used in the code. No | ||
|| point in wasting codespace on it. | ||
|| | ||
|| case EV_RFU1: | ||
|| Serial.println(F("EV_RFU1")); | ||
|| break; | ||
*/ | ||
case EV_JOIN_FAILED: | ||
Serial.println(F("EV_JOIN_FAILED")); | ||
break; | ||
case EV_REJOIN_FAILED: | ||
Serial.println(F("EV_REJOIN_FAILED")); | ||
break; | ||
case EV_TXCOMPLETE: | ||
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); | ||
if (LMIC.txrxFlags & TXRX_ACK) | ||
Serial.println(F("Received ack")); | ||
if (LMIC.dataLen) { | ||
Serial.println(F("Received ")); | ||
Serial.println(LMIC.dataLen); | ||
Serial.println(F(" bytes of payload")); | ||
} | ||
// Schedule next transmission | ||
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); | ||
break; | ||
case EV_LOST_TSYNC: | ||
Serial.println(F("EV_LOST_TSYNC")); | ||
break; | ||
case EV_RESET: | ||
Serial.println(F("EV_RESET")); | ||
break; | ||
case EV_RXCOMPLETE: | ||
// data received in ping slot | ||
Serial.println(F("EV_RXCOMPLETE")); | ||
break; | ||
case EV_LINK_DEAD: | ||
Serial.println(F("EV_LINK_DEAD")); | ||
break; | ||
case EV_LINK_ALIVE: | ||
Serial.println(F("EV_LINK_ALIVE")); | ||
break; | ||
/* | ||
|| This event is defined but not used in the code. No | ||
|| point in wasting codespace on it. | ||
|| | ||
|| case EV_SCAN_FOUND: | ||
|| Serial.println(F("EV_SCAN_FOUND")); | ||
|| break; | ||
*/ | ||
case EV_TXSTART: | ||
Serial.println(F("EV_TXSTART")); | ||
break; | ||
default: | ||
Serial.print(F("Unknown event: ")); | ||
Serial.println((unsigned) ev); | ||
break; | ||
} | ||
} | ||
|
||
void do_send(osjob_t* j){ | ||
// Check if there is not a current TX/RX job running | ||
if (LMIC.opmode & OP_TXRXPEND) { | ||
Serial.println(F("OP_TXRXPEND, not sending")); | ||
} else { | ||
// read the temperature from the DHT22 | ||
float temperature = dht.readTemperature(); | ||
Serial.print("Temperature: "); Serial.print(temperature); | ||
Serial.println(" *C"); | ||
// adjust for the f2sflt16 range (-1 to 1) | ||
temperature = temperature / 100; | ||
|
||
// read the humidity from the DHT22 | ||
float rHumidity = dht.readHumidity(); | ||
Serial.print("%RH "); | ||
Serial.println(rHumidity); | ||
// adjust for the f2sflt16 range (-1 to 1) | ||
rHumidity = rHumidity / 100; | ||
|
||
// float -> int | ||
// note: this uses the sflt16 datum (https://github.com/mcci-catena/arduino-lmic#sflt16) | ||
uint16_t payloadTemp = LMIC_f2sflt16(temperature); | ||
// int -> bytes | ||
byte tempLow = lowByte(payloadTemp); | ||
byte tempHigh = highByte(payloadTemp); | ||
// place the bytes into the payload | ||
payload[0] = tempLow; | ||
payload[1] = tempHigh; | ||
|
||
// float -> int | ||
uint16_t payloadHumid = LMIC_f2sflt16(rHumidity); | ||
// int -> bytes | ||
byte humidLow = lowByte(payloadHumid); | ||
byte humidHigh = highByte(payloadHumid); | ||
payload[2] = humidLow; | ||
payload[3] = humidHigh; | ||
|
||
// prepare upstream data transmission at the next possible time. | ||
// transmit on port 1 (the first parameter); you can use any value from 1 to 223 (others are reserved). | ||
// don't request an ack (the last parameter, if not zero, requests an ack from the network). | ||
// Remember, acks consume a lot of network resources; don't ask for an ack unless you really need it. | ||
LMIC_setTxData2(1, payload, sizeof(payload)-1, 0); | ||
} | ||
// Next TX is scheduled after TX_COMPLETE event. | ||
} | ||
|
||
void setup() { | ||
delay(5000); | ||
while (!Serial); | ||
Serial.begin(115200); | ||
delay(100); | ||
Serial.println(F("Starting")); | ||
|
||
// LMIC init | ||
os_init(); | ||
// Reset the MAC state. Session and pending data transfers will be discarded. | ||
LMIC_reset(); | ||
|
||
// Set static session parameters. Instead of dynamically establishing a session | ||
// by joining the network, precomputed session parameters are be provided. | ||
// On AVR, these values are stored in flash and only copied to RAM | ||
// once. Copy them to a temporary buffer here, LMIC_setSession will | ||
// copy them into a buffer of its own again. | ||
uint8_t appskey[sizeof(APPSKEY)]; | ||
uint8_t nwkskey[sizeof(NWKSKEY)]; | ||
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); | ||
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); | ||
LMIC_setSession (0x13, DEVADDR, nwkskey, appskey); | ||
|
||
// We'll disable all 72 channels used by TTN | ||
for (int c = 0; c < 72; c++){ | ||
LMIC_disableChannel(c); | ||
} | ||
|
||
// We'll only enable Channel 16 (905.5Mhz) since we're transmitting on a single-channel | ||
LMIC_enableChannel(16); | ||
|
||
// Disable link check validation | ||
LMIC_setLinkCheckMode(0); | ||
|
||
// TTN uses SF9 for its RX2 window. | ||
LMIC.dn2Dr = DR_SF9; | ||
|
||
// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library) | ||
LMIC_setDrTxpow(DR_SF7,14); | ||
|
||
// Start job | ||
do_send(&sendjob); | ||
} | ||
|
||
void loop() { | ||
os_runloop_once(); | ||
} |
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