Version 5.3.2; This version enabled _LOCALSERVER functionality: So when this parameter is set and the NwkSKey and AppSKey are set for a sensor in sensor.h the gateway will decode messages of nodes.
rodzic
4fb6a406c8
commit
3ccb50554a
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,6 +1,6 @@
|
|||
# Single Channel LoRaWAN Gateway
|
||||
|
||||
Version 5.3.1, June 30, 2018
|
||||
Version 5.3.2, July 07, 2018
|
||||
Author: M. Westenberg (mw12554@hotmail.com)
|
||||
Copyright: M. Westenberg (mw12554@hotmail.com)
|
||||
|
||||
|
@ -16,6 +16,16 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
|
|||
|
||||
# Release Notes
|
||||
|
||||
New features in version 5.3.2 (July 07, 2018)
|
||||
- Support for local decoding of sensor messages received by the gateway.
|
||||
Use #define _LOCALSERVER 1, to enable this functionality. Also specify for each node that you want
|
||||
to inspect the messages from the NwkSKey and AppSKey in the sensor.h file.
|
||||
NOTE: the heap of the ESP32 is much larger than of the ESP8266. SO please be careful not to add too many
|
||||
features to the "old" gateway modules
|
||||
- As a result reworked the sensor functions and changes such as adding/changing DevAddrm NwkSKEY
|
||||
and AppSKey parameters to several functions
|
||||
- Several in-line documentaton enhancements and typos were fixed
|
||||
|
||||
New features in version 5.3.1 (June 30, 2018)
|
||||
- Included support for T-Beam board including on board GPS sensor (_sensor.ino). #define GATEWAYNODE 1 will
|
||||
turn the gateway into a node as well. Remember to set the address etc in ESP-sc-gway.h.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1 H
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2 H
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
|
||||
// Contibutions of Dorijan Morelj and Andreas Spies for OLED support.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains a number of compile-time settings that can be set on (=1) or off (=0)
|
||||
|
@ -19,13 +21,13 @@
|
|||
//
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#define VERSION "V.5.3.1.H; 180630a"
|
||||
#define VERSION "V.5.3.2.H; 1800707a"
|
||||
|
||||
// This value of DEBUG determines whether some parts of code get compiled.
|
||||
// Also this is the initial value of debug parameter.
|
||||
// The value can be changed using the admin webserver
|
||||
// For operational use, set initial DEBUG vaulue 0
|
||||
#define DEBUG 0
|
||||
#define DEBUG 1
|
||||
|
||||
// Debug message will be put on Serial is this one is set.
|
||||
// If set to 0, not USB Serial prints are done
|
||||
|
@ -76,7 +78,7 @@
|
|||
// connect with USB.
|
||||
#define A_OTA 1
|
||||
|
||||
// We support two pin-out configurations out-of-the-box: HALLARD and COMPRESULT.
|
||||
// We support a few pin-out configurations out-of-the-box: HALLARD, COMPRESULT and TTGO ESP32.
|
||||
// If you use one of these two, just set the parameter to the right value.
|
||||
// If your pin definitions are different, update the loraModem.h file to reflect these settings.
|
||||
// 1: HALLARD
|
||||
|
@ -185,6 +187,10 @@
|
|||
//#define _THINGPORT <port> // e.g. 1700
|
||||
//#define _THINGSERVER "<dns.server.com>" // Server URL of the LoRa-udp.js handler
|
||||
|
||||
// This defines whether or not we would use the gateway as
|
||||
// as sort of backend system which decodes messages (see sensor.h file)
|
||||
#define _LOCALSERVER 0 // See server definitions for decodes
|
||||
|
||||
// Gateway Ident definitions
|
||||
#define _DESCRIPTION "ESP Gateway" // Name of the gateway
|
||||
#define _EMAIL "mw12554@hotmail.com" // Owner
|
||||
|
@ -233,28 +239,8 @@
|
|||
// 2: Same as 1, but is nodes NOT in the nodes list below they are NOT
|
||||
// forwarded or counted! (not yet fully implemented)
|
||||
#define TRUSTED_NODES 1
|
||||
#if TRUSTED_NODES >= 1
|
||||
struct nodex {
|
||||
uint32_t id;
|
||||
char nm[32];
|
||||
};
|
||||
#define TRUSTED_DECODE 1
|
||||
|
||||
// Add all your named and trusted nodes to this list
|
||||
nodex nodes[] = {
|
||||
{ 0x260116BD , "lora-34 PIR node" }, // F=0
|
||||
{ 0x26011152 , "lora-35 temp+humi node" }, // F=0
|
||||
{ 0x2601148C , "lora-36 test node" }, // F=0
|
||||
{ 0x26011B90 , "lora-39 temp DS18B20" }, // F=1
|
||||
{ 0x260119A6 , "lora-40 airquality" }, // F=0
|
||||
{ 0x2601117D , "lora-41 temp+humi SR04T" },
|
||||
{ 0x26011514 , "lora-43 ch1, no sensors" }, // F=1
|
||||
{ 0x26011D77 , "lora-45 not sensor" },
|
||||
{ 0x2601160F , "lora-46 HTU21 metal case" }, // F=0
|
||||
{ 0x26011E52 , "lora-53 gas sensor" }, // F=ALL
|
||||
{ 0x02020441 , "lora-65 Waterproof temp humi" },// F=0
|
||||
{ 0x26011999 , "lora-901 distance sensor" } // F=0
|
||||
};
|
||||
#endif
|
||||
|
||||
// Wifi definitions
|
||||
// WPA is an array with SSID and password records. Set WPA size to number of entries in array
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// Based on work done by Thomas Telkamp for Raspberry PI 1-ch gateway and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// The protocols and specifications used for this 1ch gateway:
|
||||
// 1. LoRA Specification version V1.0 and V1.1 for Gateway-Node communication
|
||||
//
|
||||
|
@ -53,6 +55,7 @@
|
|||
// Local include files
|
||||
#include "loraModem.h"
|
||||
#include "loraFiles.h"
|
||||
#include "sensor.h"
|
||||
#include "oLED.h"
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the LoRa filesystem specific code
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg
|
||||
//
|
||||
// This file contains the functions to do management over UDP
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the LoRa filesystem specific code
|
||||
|
@ -34,6 +36,21 @@ void id_print (String id, String val) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INITCONFIG; Init the gateway configuration file
|
||||
// Espcecially when calling SPIFFS.format() the gateway is left in an init
|
||||
// which is not very well defined. This function will init some of the settings
|
||||
// to well known settings.
|
||||
// ----------------------------------------------------------------------------
|
||||
int initConfig(struct espGwayConfig *c) {
|
||||
(*c).ch = 0;
|
||||
(*c).sf = SF8;
|
||||
(*c).debug = 1;
|
||||
(*c).pdebug = P_GUI;
|
||||
(*c).cad = _CAD;
|
||||
(*c).hop = false;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read the gateway configuration file
|
||||
|
@ -52,6 +69,7 @@ int readConfig(const char *fn, struct espGwayConfig *c) {
|
|||
Serial.print(F(" does not exist .. Formatting"));
|
||||
#endif
|
||||
SPIFFS.format();
|
||||
initConfig(c);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -78,6 +96,7 @@ int readConfig(const char *fn, struct espGwayConfig *c) {
|
|||
Serial.println(F("Formatting"));
|
||||
#endif
|
||||
SPIFFS.format();
|
||||
initConfig(c);
|
||||
f = SPIFFS.open(fn, "r");
|
||||
tries = 0;
|
||||
}
|
||||
|
@ -209,15 +228,20 @@ int writeGwayCfg(const char *fn) {
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Write the configuration ad found in the espGwayConfig structure
|
||||
// Write the configuration as found in the espGwayConfig structure
|
||||
// to SPIFFS
|
||||
// Parameters:
|
||||
// fn; Filename
|
||||
// c; struct config
|
||||
// Returns:
|
||||
// 1 when successful, -1 on error
|
||||
// ----------------------------------------------------------------------------
|
||||
int writeConfig(const char *fn, struct espGwayConfig *c) {
|
||||
|
||||
if (!SPIFFS.exists(fn)) {
|
||||
Serial.print("WARNING:: writeConfig, file not exists, formatting ");
|
||||
SPIFFS.format();
|
||||
// XXX make all initial declarations here if config vars need to have a value
|
||||
initConfig(c); // XXX make all initial declarations here if config vars need to have a value
|
||||
Serial.println(fn);
|
||||
}
|
||||
File f = SPIFFS.open(fn, "w");
|
||||
|
@ -256,12 +280,17 @@ int writeConfig(const char *fn, struct espGwayConfig *c) {
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Add a line with statitics to the log.
|
||||
// Add a line with statistics to the log.
|
||||
//
|
||||
// We put the check in the function to protect against calling
|
||||
// the function without STAT_LOG being proper defined
|
||||
// ToDo: Store the fileNo and the fileRec in the status file to save for
|
||||
// restarts
|
||||
// Parameters:
|
||||
// line; char array with characters to write to log
|
||||
// cnt;
|
||||
// Returns:
|
||||
// <none>
|
||||
// ----------------------------------------------------------------------------
|
||||
void addLog(const unsigned char * line, int cnt)
|
||||
{
|
||||
|
@ -312,8 +341,10 @@ void addLog(const unsigned char * line, int cnt)
|
|||
Serial.println(fn);
|
||||
}
|
||||
#endif
|
||||
return; // If file open failed, return
|
||||
}
|
||||
|
||||
int i;
|
||||
#if DUSB>=1
|
||||
if (( debug>=1 ) && ( pdebug & P_GUI )) {
|
||||
Serial.print(F("addLog:: fileno="));
|
||||
|
@ -322,8 +353,8 @@ void addLog(const unsigned char * line, int cnt)
|
|||
Serial.print(gwayConfig.logFileRec);
|
||||
|
||||
Serial.print(F(": "));
|
||||
int i;
|
||||
for (i=0; i< 12; i++) { // The first 12 bytes contain non printble characters
|
||||
|
||||
for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
|
||||
Serial.print(line[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
|
@ -333,12 +364,12 @@ void addLog(const unsigned char * line, int cnt)
|
|||
}
|
||||
#endif //DUSB
|
||||
|
||||
int i;
|
||||
for (i=0; i< 12; i++) { // The first 12 bytes contain non printble characters
|
||||
|
||||
for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
|
||||
// f.print(line[i],HEX);
|
||||
f.print('*');
|
||||
}
|
||||
f.write(&line[i], cnt-12); // write/append the line to the file
|
||||
f.write(&(line[i]), cnt-12); // write/append the line to the file
|
||||
f.print('\n');
|
||||
f.close(); // Close the file after appending to it
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the LoRa modem specific code enabling to receive
|
||||
|
@ -371,6 +373,15 @@ void hop() {
|
|||
// UP function
|
||||
// This is the "lowlevel" receive function called by stateMachine()
|
||||
// dealing with the radio specific LoRa functions
|
||||
//
|
||||
// Parameters:
|
||||
// Payload: uint8_t[] message. when message is read it is returned in payload.
|
||||
// Returns:
|
||||
// Length of payload received
|
||||
//
|
||||
// 9 bytes header
|
||||
// followed by data N bytes
|
||||
// 4 bytes MIC end
|
||||
// ----------------------------------------------------------------------------
|
||||
uint8_t receivePkt(uint8_t *payload)
|
||||
{
|
||||
|
@ -390,15 +401,11 @@ uint8_t receivePkt(uint8_t *payload)
|
|||
{
|
||||
#if DUSB>=1
|
||||
if (( debug>=0) && ( pdebug & P_RADIO )) {
|
||||
Serial.print(F("RxPkt:: Err CRC, ="));
|
||||
Serial.print(F("rxPkt:: Err CRC, ="));
|
||||
SerialTime();
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
// Reset CRC flag 0x20
|
||||
//writeRegister(REG_IRQ_FLAGS, (uint8_t)(IRQ_LORA_CRCERR_MASK | IRQ_LORA_RXDONE_MASK)); // 0x12; clear CRC (== 0x20) flag
|
||||
//writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
|
||||
//writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF); // XXX 180324 done in state machine
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -409,7 +416,7 @@ uint8_t receivePkt(uint8_t *payload)
|
|||
{
|
||||
#if DUSB>=1
|
||||
if (( debug>=0) && ( pdebug & P_RADIO )) {
|
||||
Serial.println(F("RxPkt:: Err HEADER"));
|
||||
Serial.println(F("rxPkt:: Err HEADER"));
|
||||
}
|
||||
#endif
|
||||
// Reset VALID-HEADER flag 0x10
|
||||
|
@ -423,7 +430,7 @@ uint8_t receivePkt(uint8_t *payload)
|
|||
cp_nb_rx_ok++; // Receive OK statistics counter
|
||||
|
||||
if (readRegister(REG_FIFO_RX_CURRENT_ADDR) != readRegister(REG_FIFO_RX_BASE_AD)) {
|
||||
if (debug>=1) {
|
||||
if (( debug>=0 ) && ( pdebug & P_RADIO )) {
|
||||
Serial.print(F("RX BASE <"));
|
||||
Serial.print(readRegister(REG_FIFO_RX_BASE_AD));
|
||||
Serial.print(F("> != RX CURRENT <"));
|
||||
|
@ -460,6 +467,9 @@ uint8_t receivePkt(uint8_t *payload)
|
|||
}
|
||||
|
||||
writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF); // Reset ALL interrupts
|
||||
|
||||
// A long as DUSB is enabled, and RX debug messages are selected,
|
||||
//the received packet is displayed on the output.
|
||||
#if DUSB>=1
|
||||
if (( debug>=0 ) && ( pdebug & P_RX )){
|
||||
|
||||
|
@ -482,23 +492,89 @@ uint8_t receivePkt(uint8_t *payload)
|
|||
Serial.print(F(", len="));
|
||||
Serial.print(receivedCount);
|
||||
|
||||
// If debug level 1 is specified, we display the content of the message as well
|
||||
// We need to decode the message as well will it make any sense
|
||||
|
||||
if (debug>=1) { // Must be 1 for operational use
|
||||
#if _TRUSTED_DECODE==2
|
||||
int index; // The index of the codex struct to decode
|
||||
String response="";
|
||||
|
||||
uint8_t data[receivedCount];
|
||||
|
||||
uint8_t DevAddr [4];
|
||||
DevAddr[0] = payload[4];
|
||||
DevAddr[1] = payload[3];
|
||||
DevAddr[2] = payload[2];
|
||||
DevAddr[3] = payload[1];
|
||||
|
||||
if ((index = inDecodes((char *)(payload+1))) >=0 ) {
|
||||
Serial.print(F(", Ind="));
|
||||
Serial.print(index);
|
||||
//Serial.println();
|
||||
}
|
||||
else if (debug>=1) {
|
||||
Serial.print(F(", No Index"));
|
||||
Serial.println();
|
||||
return(receivedCount);
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
|
||||
Serial.print(F(", data="));
|
||||
for (int i=0; i<receivedCount; i++) { data[i] = payload[i]; } // Copy array
|
||||
|
||||
//for (int i=0; i<receivedCount; i++) {
|
||||
// if (payload[i]<=0xF) Serial.print('0');
|
||||
// Serial.print(payload[i], HEX);
|
||||
// Serial.print(' ');
|
||||
//}
|
||||
|
||||
|
||||
|
||||
uint16_t frameCount=payload[7]*256 + payload[6];
|
||||
|
||||
// The message received has a length, but data starts at byte 9, and stops 4 bytes
|
||||
// before the end since those are MIC bytes
|
||||
uint8_t CodeLength = encodePacket((uint8_t *)(data + 9), receivedCount-9-4, (uint16_t)frameCount, DevAddr, decodes[index].appKey, 0);
|
||||
|
||||
Serial.print(F("- NEW fc="));
|
||||
Serial.print(frameCount);
|
||||
Serial.print(F(", addr="));
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
if (DevAddr[i]<=0xF) Serial.print('0');
|
||||
Serial.print(DevAddr[i], HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
|
||||
Serial.print(F(", len="));
|
||||
Serial.print(CodeLength);
|
||||
Serial.print(F(", data="));
|
||||
|
||||
for (int i=0; i<receivedCount; i++) {
|
||||
if (data[i]<=0xF) Serial.print('0');
|
||||
Serial.print(data[i], HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
#endif // _TRUSTED_DECODE
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (debug>=2) Serial.flush();
|
||||
}
|
||||
#endif
|
||||
#endif //DUSB
|
||||
return(receivedCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
writeRegister(REG_IRQ_FLAGS, (uint8_t) (
|
||||
IRQ_LORA_RXDONE_MASK |
|
||||
IRQ_LORA_RXTOUT_MASK |
|
||||
IRQ_LORA_HEADER_MASK |
|
||||
IRQ_LORA_CRCERR_MASK)); // 0x12; Clear RxDone IRQ_LORA_RXDONE_MASK
|
||||
return 0;
|
||||
}
|
||||
} //receivePkt
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the state machine code enabling to receive
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
|
@ -9,6 +9,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the ota code for the ESP Single Channel Gateway.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
|
||||
// Verison 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Verison 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the MIT License
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// sensor.ino; 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
|
||||
// Verison 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Verison 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the MIT License
|
||||
|
@ -21,13 +21,23 @@
|
|||
// - The battery sensor works by connecting the VCC pin to A0 analog port
|
||||
// ============================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
#if GATEWAYNODE==1
|
||||
|
||||
//#include "sensor.h" // Contains definitions for the sensor and TRUSTED info, ilcuded in ESP-sc-gway.ino
|
||||
#include "LoRaCode.h"
|
||||
|
||||
#if _GPS==1
|
||||
unsigned char DevAddr[4] = _DEVADDR ; // see ESP-sc-gway.h
|
||||
|
||||
|
||||
// Only used by GPS sensor code
|
||||
//
|
||||
#if _GPS==1
|
||||
// ----------------------------------------------------------------------------
|
||||
// Smartdelay is a function to delay processing but in the loop get info
|
||||
// from the GPS device
|
||||
// ----------------------------------------------------------------------------
|
||||
static void smartDelay(unsigned long ms)
|
||||
{
|
||||
unsigned long start = millis();
|
||||
|
@ -37,10 +47,10 @@ static void smartDelay(unsigned long ms)
|
|||
gps.encode(Serial1.read());
|
||||
} while (millis() - start < ms);
|
||||
}
|
||||
#endif
|
||||
#endif //_GPS
|
||||
|
||||
|
||||
|
||||
unsigned char DevAddr[4] = _DEVADDR ; // see ESP-sc-gway.h
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -68,33 +78,50 @@ static int LoRaSensors(uint8_t *buf) {
|
|||
|
||||
uint8_t tchars = 1;
|
||||
buf[0] = 0x86; // 134; User code <lCode + len==3 + Parity
|
||||
|
||||
|
||||
#if DUSB>=1
|
||||
if (debug>=0)
|
||||
Serial.print(F("LoRaSensors:: "));
|
||||
#endif
|
||||
|
||||
#if _BATTERY==1
|
||||
#if DUSB>=1
|
||||
if (debug>=0)
|
||||
Serial.println(F("LoRaSensors:: Battery"));
|
||||
Serial.print(F("Battery "));
|
||||
#endif
|
||||
buf[tchars] = 0x80; // 128; lCode code <battery>
|
||||
buf[tchars+1] = 0x3F; // 63; lCode code <value>/30
|
||||
tchars+=2;
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
|
||||
// For ESP there is no standard battery library
|
||||
// What we do is to measure GPIO35 pin which has a 100K voltage divider
|
||||
pinMode(35, INPUT);
|
||||
#if defined(ESP32)
|
||||
int devider=4095;
|
||||
#else
|
||||
int devider=1023;
|
||||
#endif //ESP32
|
||||
float volts=3.3 * analogRead(35) / 4095 * 2; // T_Beam connects to GPIO35
|
||||
#else
|
||||
// For ESP8266 no sensor defined
|
||||
float volts=0;
|
||||
#endif
|
||||
tchars += lcode.eBattery(volts, buf + tchars);
|
||||
#endif
|
||||
|
||||
#if _GPS==1
|
||||
#if DUSB>=1
|
||||
if (debug>=0)
|
||||
Serial.println(F("LoRaSensors:: GPS"));
|
||||
Serial.print(F("GPS "));
|
||||
|
||||
if (debug>=1) {
|
||||
Serial.print("Latitude : ");
|
||||
if (( debug>=1 ) && ( pdebug & P_MAIN )) {
|
||||
Serial.print("\tLatitude : ");
|
||||
Serial.println(gps.location.lat(), 5);
|
||||
Serial.print("Longitude : ");
|
||||
Serial.print("\tLongitude : ");
|
||||
Serial.println(gps.location.lng(), 4);
|
||||
Serial.print("Satellites: ");
|
||||
Serial.print("\tSatellites: ");
|
||||
Serial.println(gps.satellites.value());
|
||||
Serial.print("Altitude : ");
|
||||
Serial.print("\tAltitude : ");
|
||||
Serial.print(gps.altitude.feet() / 3.2808);
|
||||
Serial.println("M");
|
||||
Serial.print("Time : ");
|
||||
Serial.print("\tTime : ");
|
||||
Serial.print(gps.time.hour());
|
||||
Serial.print(":");
|
||||
Serial.print(gps.time.minute());
|
||||
|
@ -113,15 +140,19 @@ static int LoRaSensors(uint8_t *buf) {
|
|||
}
|
||||
|
||||
// Assuming we have a value, put it in the buf
|
||||
// The layout of thi message is specific to the user,
|
||||
// The layout of this message is specific to the user,
|
||||
// so adapt as needed.
|
||||
tchars += lcode.eGpsL(gps.location.lat(), gps.location.lng(), gps.altitude.value(),
|
||||
gps.satellites.value(), buf + tchars);
|
||||
|
||||
#endif
|
||||
|
||||
// If all sensor data is encoded, we encode the buffer
|
||||
|
||||
#if DUSB>=1
|
||||
if (debug>=0)
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
// If all sensor data is encoded, we encode the buffer
|
||||
lcode.eMsg(buf, tchars); // Fill byte 0 with bytecount and Parity
|
||||
|
||||
return(tchars); // return the number of bytes added to payload
|
||||
|
@ -215,9 +246,19 @@ static void generate_subkey(uint8_t *key, uint8_t *k1, uint8_t *k2) {
|
|||
//
|
||||
// cmac = aes128_encrypt(K, Block_A[i])
|
||||
// ----------------------------------------------------------------------------
|
||||
uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t Direction) {
|
||||
uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t *DevAddr, uint8_t *AppSKey, uint8_t Direction) {
|
||||
|
||||
unsigned char AppSKey[16] = _APPSKEY ; // see ESP-sc-gway.h
|
||||
#if DUSB>=1
|
||||
if (debug>=2) {
|
||||
Serial.print(F("encodePacket:: DevAddr="));
|
||||
for (int i=0; i<4; i++ ) { Serial.print(DevAddr[i],HEX); Serial.print(' '); }
|
||||
Serial.print(F("encodePacket:: AppSKey="));
|
||||
for (int i=0; i<16; i++ ) { Serial.print(AppSKey[i],HEX); Serial.print(' '); }
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
//unsigned char AppSKey[16] = _APPSKEY ; // see ESP-sc-gway.h
|
||||
uint8_t i, j;
|
||||
uint8_t Block_A[16];
|
||||
uint8_t bLen=16; // Block length is 16 except for last block in message
|
||||
|
@ -288,10 +329,10 @@ uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uin
|
|||
// MIC is cmac [0:3] of ( aes128_cmac(NwkSKey, B0 | Data )
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir) {
|
||||
uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t * NwkSKey, uint8_t dir) {
|
||||
|
||||
|
||||
unsigned char NwkSKey[16] = _NWKSKEY ;
|
||||
//uint8_t NwkSKey[16] = _NWKSKEY;
|
||||
uint8_t Block_B[16];
|
||||
uint8_t X[16];
|
||||
uint8_t Y[16];
|
||||
|
@ -365,7 +406,7 @@ uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir)
|
|||
|
||||
// ------------------------------------
|
||||
// Step 4: If there is a rest Block, padd it
|
||||
// Last block. We move step4 to the end as we need Y
|
||||
// Last block. We move step 4 to the end as we need Y
|
||||
// to compute the last block
|
||||
//
|
||||
if (restBits) {
|
||||
|
@ -410,6 +451,7 @@ uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir)
|
|||
// ----------------------------------------------------------------------------
|
||||
static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
|
||||
uint8_t cBuf[len+1];
|
||||
uint8_t NwkSKey[16] = _NWKSKEY;
|
||||
|
||||
if (debug>=2) {
|
||||
Serial.print(F("old="));
|
||||
|
@ -423,7 +465,7 @@ static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
|
|||
len -=4;
|
||||
|
||||
uint16_t FrameCount = ( cBuf[7] * 256 ) + cBuf[6];
|
||||
len += micPacket(cBuf, len, FrameCount, 0);
|
||||
len += micPacket(cBuf, len, FrameCount, NwkSKey, 0);
|
||||
|
||||
if (debug>=2) {
|
||||
Serial.print(F("new="));
|
||||
|
@ -433,8 +475,9 @@ static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
|
|||
}
|
||||
Serial.println();
|
||||
}
|
||||
// Mic is only checked, but len is not corrected
|
||||
}
|
||||
#endif
|
||||
#endif //_CHECK_MIC
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SENSORPACKET
|
||||
|
@ -469,6 +512,9 @@ int sensorPacket() {
|
|||
uint8_t mlength = 0;
|
||||
uint32_t tmst = micros();
|
||||
struct LoraUp LUP;
|
||||
uint8_t NwkSKey[16] = _NWKSKEY;
|
||||
uint8_t AppSKey[16] = _APPSKEY;
|
||||
uint8_t DevAddr[4] = _DEVADDR;
|
||||
|
||||
// Init the other LoraUp fields
|
||||
LUP.sf = 8; // Send with SF8
|
||||
|
@ -508,11 +554,34 @@ int sensorPacket() {
|
|||
// See LoRa spec para 4.3.2
|
||||
// You can add any byte string below based on you personal choice of sensors etc.
|
||||
//
|
||||
|
||||
// Payload bytes in this example are encoded in the LoRaCode(c) format
|
||||
uint8_t PayLength = LoRaSensors((uint8_t *)(LUP.payLoad + LUP.payLength));
|
||||
|
||||
#if DUSB>=1
|
||||
if ((debug>=2) && (pdebug & P_RADIO )) {
|
||||
Serial.print(F("old: "));
|
||||
for (int i=0; i<PayLength; i++) {
|
||||
Serial.print(LUP.payLoad[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
// we have to include the AES functions at this stage in order to generate LoRa Payload.
|
||||
uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, 0);
|
||||
uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, DevAddr, AppSKey, 0);
|
||||
|
||||
#if DUSB>=1
|
||||
if ((debug>=2) && (pdebug & P_RADIO )) {
|
||||
Serial.print(F("new: "));
|
||||
for (int i=0; i<CodeLength; i++) {
|
||||
Serial.print(LUP.payLoad[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
LUP.payLength += CodeLength; // length inclusive sensor data
|
||||
|
||||
|
@ -522,7 +591,18 @@ int sensorPacket() {
|
|||
// Note: Until MIC is done correctly, TTN does not receive these messages
|
||||
// The last 4 bytes are MIC bytes.
|
||||
//
|
||||
LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, 0);
|
||||
LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, NwkSKey, 0);
|
||||
|
||||
#if DUSB>=1
|
||||
if ((debug>=2) && (pdebug & P_RADIO )) {
|
||||
Serial.print(F("mic: "));
|
||||
for (int i=0; i<LUP.payLength; i++) {
|
||||
Serial.print(LUP.payLoad[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
// So now our package is ready, and we can send it up through the gateway interface
|
||||
// Note Be aware that the sensor message (which is bytes) in message will be
|
||||
|
@ -531,6 +611,7 @@ int sensorPacket() {
|
|||
int buff_index = buildPacket(tmst, buff_up, LUP, true);
|
||||
|
||||
frameCount++;
|
||||
cp_nb_rx_rcv++;
|
||||
|
||||
// In order to save the memory, we only write the framecounter
|
||||
// to EEPROM every 10 values. It also means that we will invalidate
|
||||
|
@ -542,16 +623,37 @@ int sensorPacket() {
|
|||
if (debug>0) Serial.println(F("sensorPacket:: ERROR buffer size too large"));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _TTNSERVER
|
||||
if (!sendUdp(ttnServer, _TTNPORT, buff_up, buff_index)) {
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
#ifdef _THINGSERVER
|
||||
if (!sendUdp(thingServer, _THINGPORT, buff_up, buff_index)) {
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DUSB>=1
|
||||
// If all is right, we should after decoding (which is the same as encoding) get
|
||||
// the original message back again.
|
||||
if ((debug>=2) && (pdebug & P_RADIO )) {
|
||||
CodeLength = encodePacket((uint8_t *)(LUP.payLoad + 9), PayLength, (uint16_t)frameCount-1, DevAddr, AppSKey, 0);
|
||||
Serial.print(F("rev: "));
|
||||
for (int i=0; i<CodeLength; i++) {
|
||||
Serial.print(LUP.payLoad[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.print(F(", addr="));
|
||||
for (int i=0; i<4; i++) {
|
||||
Serial.print(DevAddr[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_cad) {
|
||||
// Set the state to CAD scanning after sending a packet
|
||||
_state = S_SCAN; // Inititialise scanner
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the state machine code enabling to receive
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the LoRa modem specific code enabling to receive
|
||||
|
@ -213,12 +215,14 @@ int sendPacket(uint8_t *buf, uint8_t length)
|
|||
// build a gateway message to send upstream (to the user somewhere on the web).
|
||||
//
|
||||
// parameters:
|
||||
// tmst: Timestamp to include in the upstream message
|
||||
// buff_up: The buffer that is generated for upstream
|
||||
// message: The payload message to include in the the buff_up
|
||||
// messageLength: The number of bytes received by the LoRa transceiver
|
||||
// internal: Boolean value to indicate whether the local sensor is processed
|
||||
// tmst: Timestamp to include in the upstream message
|
||||
// buff_up: The buffer that is generated for upstream
|
||||
// message: The payload message to include in the the buff_up
|
||||
// messageLength: The number of bytes received by the LoRa transceiver
|
||||
// internal: Boolean value to indicate whether the local sensor is processed
|
||||
//
|
||||
// returns:
|
||||
// buff_index
|
||||
// ----------------------------------------------------------------------------
|
||||
int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool internal)
|
||||
{
|
||||
|
@ -253,8 +257,41 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
}
|
||||
|
||||
#if STATISTICS >= 1
|
||||
// Receive statistics
|
||||
// Receive statistics, move old statistics down 1 position
|
||||
// and fill the new top line with the latest received sensor values.
|
||||
// This works fine for the sensor, EXCEPT when we decode data for _LOCALSERVER
|
||||
//
|
||||
for (int m=( MAX_STAT -1); m>0; m--) statr[m]=statr[m-1];
|
||||
|
||||
// From now on we can fill start[0] with sensor data
|
||||
#if _LOCALSERVER==1
|
||||
statr[0].datal=0;
|
||||
int index;
|
||||
if ((index = inDecodes((char *)(LoraUp.payLoad+1))) >=0 ) {
|
||||
|
||||
uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
|
||||
|
||||
for (int k=0; (k<LoraUp.payLength) && (k<23); k++) {
|
||||
statr[0].data[k] = LoraUp.payLoad[k+9];
|
||||
};
|
||||
|
||||
// XXX Check that k<23 when leaving the for loop
|
||||
// XXX or we can not display in statr
|
||||
|
||||
uint8_t DevAddr[4];
|
||||
DevAddr[0]= LoraUp.payLoad[4];
|
||||
DevAddr[1]= LoraUp.payLoad[3];
|
||||
DevAddr[2]= LoraUp.payLoad[2];
|
||||
DevAddr[3]= LoraUp.payLoad[1];
|
||||
|
||||
statr[0].datal = encodePacket((uint8_t *)(statr[0].data),
|
||||
LoraUp.payLength-9-4,
|
||||
(uint16_t)frameCount,
|
||||
DevAddr,
|
||||
decodes[index].appKey,
|
||||
0);
|
||||
}
|
||||
#endif //_LOCALSERVER
|
||||
statr[0].tmst = now();
|
||||
statr[0].ch= ifreq;
|
||||
statr[0].prssi = prssi - rssicorr;
|
||||
|
@ -267,17 +304,19 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
if ((message[4] != 0x26) || (message[1]==0x99)) {
|
||||
Serial.print(F("addr="));
|
||||
for (int i=messageLength; i>0; i--) {
|
||||
if (message[i]<16) Serial.print('0');
|
||||
if (message[i]<0x10) Serial.print('0');
|
||||
Serial.print(message[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
#endif // DUSB
|
||||
#endif //DUSB
|
||||
statr[0].node = ( message[1]<<24 | message[2]<<16 | message[3]<<8 | message[4] );
|
||||
|
||||
#if STATISTICS >= 2
|
||||
// Fill in the statistics that we will also need for the GUI.
|
||||
// So
|
||||
switch (statr[0].sf) {
|
||||
case SF7: statc.sf7++; break;
|
||||
case SF8: statc.sf8++; break;
|
||||
|
@ -286,7 +325,7 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
case SF11: statc.sf11++; break;
|
||||
case SF12: statc.sf12++; break;
|
||||
}
|
||||
#endif // STATISTICS >= 2
|
||||
#endif //STATISTICS >= 2
|
||||
|
||||
#if STATISTICS >= 3
|
||||
if (statr[0].ch == 0) switch (statr[0].sf) {
|
||||
|
@ -315,9 +354,9 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
case SF11: statc.sf11_2++; break;
|
||||
case SF12: statc.sf12_2++; break;
|
||||
}
|
||||
#endif // STATISTICS >= 3
|
||||
#endif //STATISTICS >= 3
|
||||
|
||||
#endif // STATISTICS >= 2
|
||||
#endif //STATISTICS >= 2
|
||||
|
||||
#if DUSB>=1
|
||||
if (( debug>=2 ) && ( pdebug & P_RADIO )){
|
||||
|
@ -382,8 +421,10 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
int encodedLen = base64_enc_len(messageLength); // max 341
|
||||
#if DUSB>=1
|
||||
if ((debug>=1) && (encodedLen>255)) {
|
||||
Serial.println(F("buildPacket:: b64 error"));
|
||||
Serial.print(F("buildPacket:: b64 err, len="));
|
||||
Serial.println(encodedLen);
|
||||
if (debug>=2) Serial.flush();
|
||||
return(-1);
|
||||
}
|
||||
#endif // DUSB
|
||||
base64_encode(b64, (char *) message, messageLength);// max 341
|
||||
|
@ -523,7 +564,7 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
// UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP
|
||||
// Receive a LoRa package over the air, LoRa
|
||||
// Receive a LoRa package over the air, LoRa and deliver to server(s)
|
||||
//
|
||||
// Receive a LoRa message and fill the buff_up char buffer.
|
||||
// returns values:
|
||||
|
@ -546,7 +587,7 @@ int receivePacket()
|
|||
|
||||
// Take the timestamp as soon as possible, to have accurate reception timestamp
|
||||
// TODO: tmst can jump if micros() overflow.
|
||||
uint32_t tmst = (uint32_t) micros(); // Only microseconds, rollover in
|
||||
uint32_t tmst = (uint32_t) micros(); // Only microseconds, rollover in 5X minutes
|
||||
//lastTmst = tmst; // Following/according to spec
|
||||
|
||||
// Handle the physical data read from LoraUp
|
||||
|
@ -563,9 +604,6 @@ int receivePacket()
|
|||
return(-3);
|
||||
}
|
||||
#endif
|
||||
|
||||
LoraUp.payLength = 0;
|
||||
LoraUp.payLoad[0] = 0x00;
|
||||
|
||||
// This is one of the potential problem areas.
|
||||
// If possible, USB traffic should be left out of interrupt routines
|
||||
|
@ -576,12 +614,76 @@ int receivePacket()
|
|||
}
|
||||
yield();
|
||||
#endif
|
||||
|
||||
// Use our own defined server or a second well kon server
|
||||
#ifdef _THINGSERVER
|
||||
if (!sendUdp(thingServer, _THINGPORT, buff_up, build_index)) {
|
||||
return(-2); // received a message
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _LOCALSERVER==1
|
||||
// Or special case, we do not use a local server to receive
|
||||
// and decode the server. We use buildPacket() to call decode
|
||||
// and use statr[0] information to store decoded message
|
||||
|
||||
//DecodePayload: para 4.3.1 of Lora 1.1 Spec
|
||||
// MHDR
|
||||
// 1 byte Payload[0]
|
||||
// FHDR
|
||||
// 4 byte Dev Addr Payload[1-4]
|
||||
// 1 byte FCtrl Payload[5]
|
||||
// 2 bytes FCnt Payload[6-7]
|
||||
// = Optional 0 to 15 bytes Options
|
||||
// FPort
|
||||
// 1 bytes, 0x00 Payload[8]
|
||||
// ------------
|
||||
// +=9 BYTES HEADER
|
||||
//
|
||||
// FRMPayload
|
||||
// N bytes (Payload )
|
||||
//
|
||||
// 4 bytes MIC trailer
|
||||
|
||||
int index=0;
|
||||
if ((index = inDecodes((char *)(LoraUp.payLoad+1))) >=0 ) {
|
||||
|
||||
uint8_t DevAddr[4];
|
||||
DevAddr[0]= LoraUp.payLoad[4];
|
||||
DevAddr[1]= LoraUp.payLoad[3];
|
||||
DevAddr[2]= LoraUp.payLoad[2];
|
||||
DevAddr[3]= LoraUp.payLoad[1];
|
||||
uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
|
||||
|
||||
#if DUSB>=1
|
||||
|
||||
Serial.print(F("receivePacket:: Ind="));
|
||||
Serial.print(index);
|
||||
Serial.print(F(", Len="));
|
||||
Serial.print(LoraUp.payLength);
|
||||
Serial.print(F(", A="));
|
||||
for (int i=0; i<4; i++) {
|
||||
if (DevAddr[i]<0x0F) Serial.print('0');
|
||||
Serial.print(DevAddr[i],HEX);
|
||||
//Serial.print(' ');
|
||||
}
|
||||
|
||||
Serial.print(F(", Msg="));
|
||||
for (int i=0; (i<statr[0].datal) && (i<23); i++) {
|
||||
if (statr[0].data[i]<0x0F) Serial.print('0');
|
||||
Serial.print(statr[0].data[i],HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
else if (debug>=2) {
|
||||
Serial.println(F("receivePacket:: No Index"));
|
||||
}
|
||||
#endif //DUSB
|
||||
#endif // _LOCALSERVER
|
||||
|
||||
// Reset the message area
|
||||
LoraUp.payLength = 0;
|
||||
LoraUp.payLoad[0] = 0x00;
|
||||
return(build_index);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-31
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the utilities for time and other functions
|
||||
|
@ -161,12 +163,12 @@ void SerialStat(uint8_t intr)
|
|||
// ----------------------------------------------------------------------------
|
||||
// SerialName(id, response)
|
||||
// Check whether for address a (4 bytes in Unsigned Long) there is a name
|
||||
// This function only works if TRUSTED_NODES is set
|
||||
// This function only works if _TRUSTED_NODES is set
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int SerialName(char * a, String& response)
|
||||
{
|
||||
#if TRUSTED_NODES>=1
|
||||
#if _TRUSTED_NODES>=1
|
||||
uint32_t id = ((a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3]);
|
||||
|
||||
int i;
|
||||
|
@ -191,4 +193,23 @@ int SerialName(char * a, String& response)
|
|||
return(-1); // If no success OR is TRUSTED NODES not defined
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// inDecodes(id)
|
||||
// Find the id in Decodes array, and return the index of the item
|
||||
// Parameters:
|
||||
// id: The first field in the array (normally DevAddr id). Must be char[4]
|
||||
// Returns:
|
||||
// The index of the ID in the Array. Returns -1 if not found
|
||||
// ----------------------------------------------------------------------------
|
||||
int inDecodes(char * id) {
|
||||
|
||||
uint32_t ident = ((id[3]<<24) | (id[2]<<16) | (id[1]<<8) | id[0]);
|
||||
|
||||
int i;
|
||||
for ( i=0; i< (sizeof(decodes)/sizeof(codex)); i++) {
|
||||
if (ident == decodes[i].id) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by many people and making use of several libraries.
|
||||
//
|
||||
|
@ -10,6 +10,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains the webserver code for the ESP Single Channel Gateway.
|
||||
|
@ -77,10 +79,14 @@ boolean YesNo(String s)
|
|||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WWWFILES
|
||||
// WWWFILE
|
||||
// This function will open a pop-up in the browser and then
|
||||
// display the contents of a file in that window
|
||||
// Output is sent to server.sendContent()
|
||||
// Parameters:
|
||||
// fn; String with filename
|
||||
// Returns:
|
||||
// <none>
|
||||
// ----------------------------------------------------------------------------
|
||||
void wwwFile(String fn) {
|
||||
|
||||
|
@ -91,7 +97,7 @@ void wwwFile(String fn) {
|
|||
#endif
|
||||
return;
|
||||
}
|
||||
#if DUSB>=1
|
||||
#if DUSB>=2
|
||||
else {
|
||||
Serial.print(F("wwwButtons:: File existist= "));
|
||||
Serial.println(fn);
|
||||
|
@ -119,16 +125,17 @@ void wwwFile(String fn) {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Button function Stat, display statistics
|
||||
// This is a button on the top of the GUI screen.
|
||||
// ----------------------------------------------------------------------------
|
||||
void buttonStat()
|
||||
{
|
||||
Serial.print(F("Log"));
|
||||
Serial.println();
|
||||
//Serial.print(F("Log"));
|
||||
//Serial.println();
|
||||
|
||||
printLog();
|
||||
//printLog();
|
||||
|
||||
String response = "";
|
||||
response+= "alert('Log');";
|
||||
response+= "<script> confirm('Confirm Log'); </script>";
|
||||
server.sendContent(response);
|
||||
|
||||
}
|
||||
|
@ -136,6 +143,7 @@ void buttonStat()
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Button gunction Log displays logfiles.
|
||||
// This is a button on the top of the GUI screen
|
||||
// ----------------------------------------------------------------------------
|
||||
void buttonLog()
|
||||
{
|
||||
|
@ -177,6 +185,11 @@ static void wwwButtons()
|
|||
// results are sent back to the web client.
|
||||
// Commands: DEBUG, ADDRESS, IP, CONFIG, GETTIME, SETTIME
|
||||
// The webpage is completely built response and then printed on screen.
|
||||
// Parameters:
|
||||
// cmd: Contains a character array with the command to execute
|
||||
// arg: Contains the parameter value of that command
|
||||
// Returns:
|
||||
// <none>
|
||||
// ----------------------------------------------------------------------------
|
||||
static void setVariables(const char *cmd, const char *arg) {
|
||||
|
||||
|
@ -329,7 +342,7 @@ static void openWebPage()
|
|||
|
||||
response += "<style>.thead {background-color:green; color:white;} ";
|
||||
response += ".cell {border: 1px solid black;}";
|
||||
response += ".config_table {max_width:100%; min-width:400px; width:95%; border:1px solid black; border-collapse:collapse;}";
|
||||
response += ".config_table {max_width:100%; min-width:400px; width:98%; border:1px solid black; border-collapse:collapse;}";
|
||||
response += "</style></HEAD><BODY>";
|
||||
|
||||
response +="<h1>ESP Gateway Config</h1>";
|
||||
|
@ -774,6 +787,16 @@ static void statisticsData()
|
|||
// ----------------------------------------------------------------------------
|
||||
// SENSORDATA
|
||||
// If enabled, display the sensorHistory on the current webserver Page.
|
||||
// In this GUI section a number of statr[x] records are displayed such as:
|
||||
//
|
||||
// Time, The time the sensor message was received
|
||||
// Node, the DevAddr or even Node name for Trusted nodes,
|
||||
// Data (Localserver), when _LOCALSERVER is enabled contains decoded data
|
||||
// C, Channel frequency on which the sensor was received
|
||||
// Freq, The frequency of the channel
|
||||
// SF, Spreading Factor
|
||||
// pRSSI, Packet RSSI
|
||||
//
|
||||
// Parameters:
|
||||
// - <none>
|
||||
// Returns:
|
||||
|
@ -789,6 +812,9 @@ static void sensorData()
|
|||
response += "<tr>";
|
||||
response += "<th class=\"thead\">Time</th>";
|
||||
response += "<th class=\"thead\">Node</th>";
|
||||
#if _LOCALSERVER==1
|
||||
response += "<th class=\"thead\">Data</th>";
|
||||
#endif
|
||||
response += "<th class=\"thead\" style=\"width: 20px;\">C</th>";
|
||||
response += "<th class=\"thead\">Freq</th>";
|
||||
response += "<th class=\"thead\" style=\"width: 40px;\">SF</th>";
|
||||
|
@ -806,16 +832,26 @@ static void sensorData()
|
|||
|
||||
response = "";
|
||||
|
||||
response += String() + "<tr><td class=\"cell\">";
|
||||
response += String() + "<tr><td class=\"cell\">"; // Tmst
|
||||
stringTime((statr[i].tmst), response); // XXX Change tmst not to be millis() dependent
|
||||
response += "</td>";
|
||||
response += String() + "<td class=\"cell\">";
|
||||
|
||||
if (SerialName((char *)(& (statr[i].node)), response) < 0) { // works with TRUSTED_NODES >= 1
|
||||
printHEX((char *)(& (statr[i].node)),' ',response); // else
|
||||
|
||||
response += String() + "<td class=\"cell\">"; // Node
|
||||
if (SerialName((char *)(& (statr[i].node)), response) < 0) { // works with TRUSTED_NODES >= 1
|
||||
printHEX((char *)(& (statr[i].node)),' ',response); // else
|
||||
}
|
||||
|
||||
response += "</td>";
|
||||
|
||||
#if _LOCALSERVER==1
|
||||
response += String() + "<td class=\"cell\">"; // Data
|
||||
for (int j=0; j<statr[i].datal; j++) {
|
||||
if (statr[i].data[j] <0x10) response+= "0";
|
||||
response += String(statr[i].data[j],HEX) + " ";
|
||||
}
|
||||
response += "</td>";
|
||||
#endif
|
||||
|
||||
|
||||
response += String() + "<td class=\"cell\">" + statr[i].ch + "</td>";
|
||||
response += String() + "<td class=\"cell\">" + freqs[statr[i].ch] + "</td>";
|
||||
response += String() + "<td class=\"cell\">" + statr[i].sf + "</td>";
|
||||
|
@ -1000,6 +1036,7 @@ void setupWWW()
|
|||
server.on("/FORMAT", []() {
|
||||
Serial.print(F("FORMAT ..."));
|
||||
SPIFFS.format(); // Normally disabled. Enable only when SPIFFS corrupt
|
||||
initConfig(&gwayConfig);
|
||||
Serial.println(F("DONE"));
|
||||
});
|
||||
|
||||
|
@ -1260,9 +1297,10 @@ void setupWWW()
|
|||
#endif
|
||||
// Display Statistics
|
||||
server.on("/STAT", []() {
|
||||
server.sendHeader("Location", String("/"), true);
|
||||
buttonStat();
|
||||
server.send ( 302, "text/plain", "");
|
||||
//server.sendHeader("Location", String("/"), true);
|
||||
|
||||
//server.send ( 302, "text/plain", "");
|
||||
});
|
||||
server.on("/LOG", []() {
|
||||
server.sendHeader("Location", String("/"), true);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains a number of compile-time settings that can be set on (=1) or off (=0)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many other contributors.
|
||||
|
@ -11,6 +11,8 @@
|
|||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains a number of compile-time settings and declarations that are
|
||||
|
@ -254,7 +256,11 @@ struct stat_t {
|
|||
#if RSSI==1
|
||||
int8_t rssi; // XXX Can be < -128
|
||||
#endif
|
||||
int8_t prssi; // XXX Can be < -128
|
||||
int8_t prssi; // XXX Can be < -128
|
||||
#if _LOCALSERVER==1
|
||||
uint8_t data[23]; // For memory purposes, only 23 chars
|
||||
uint8_t datal; // Length of decoded message 1 char
|
||||
#endif
|
||||
} stat_t;
|
||||
|
||||
|
||||
|
@ -294,6 +300,9 @@ struct stat_c statc;
|
|||
// History of received uplink messages from nodes
|
||||
struct stat_t statr[MAX_STAT];
|
||||
|
||||
|
||||
|
||||
|
||||
#else // STATISTICS==0
|
||||
struct stat_t statr[1]; // Always have at least one element to store in
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
// 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.1
|
||||
// Date: 2018-06-30
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many others.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the MIT License
|
||||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains a number of compile-time settings and definitions for OLED support.
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
// sensor.h; 1-channel LoRa Gateway for ESP8266
|
||||
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
|
||||
// Version 5.3.2
|
||||
// Date: 2018-07-07
|
||||
//
|
||||
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
|
||||
// and many other contributors.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the MIT License
|
||||
// which accompanies this distribution, and is available at
|
||||
// https://opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// NO WARRANTY OF ANY KIND IS PROVIDED
|
||||
//
|
||||
// Author: Maarten Westenberg (mw12554@hotmail.com)
|
||||
//
|
||||
// This file contains a number of compile-time settings and declarations that are
|
||||
// specific to the LoRa rfm95, sx1276, sx1272 radio of the gateway.
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
#if _TRUSTED_NODES >= 1
|
||||
struct nodex {
|
||||
uint32_t id; // This i sthe decide ID (coded in 4 bytes uint32_t
|
||||
char nm[32];
|
||||
};
|
||||
|
||||
// Add all your named and trusted nodes to this list
|
||||
nodex nodes[] = {
|
||||
{ 0x260116BD , "lora-34 PIR node" }, // F=0
|
||||
{ 0x26011152 , "lora-35 temp+humi node" }, // F=0
|
||||
{ 0x2601148C , "lora-36 test node" }, // F=0
|
||||
{ 0x26011B90 , "lora-39 temp DS18B20" }, // F=1
|
||||
{ 0x260119A6 , "lora-40 airquality" }, // F=0
|
||||
{ 0x2601117D , "lora-41 temp+humi SR04T" },
|
||||
{ 0x26011514 , "lora-43 ch1, no sensors" }, // F=1
|
||||
{ 0x26011D77 , "lora-45 not sensor" },
|
||||
{ 0x2601160F , "lora-46 HTU21 metal case" }, // F=0
|
||||
{ 0x26011E71 , "lora-47 Dallas temperature" }, // F=0
|
||||
{ 0x26011E52 , "lora-53 gas sensor" }, // F=ALL
|
||||
{ 0x02020441 , "lora-65 Waterproof temp humi" }, // F=0
|
||||
{ 0x26011b96 , "lora-50 Internal T-Beam gway" }, // F=0
|
||||
{ 0x26011999 , "lora-901 distance sensor" } // F=0
|
||||
};
|
||||
|
||||
|
||||
#endif //_TRUSTED_NODES
|
||||
|
||||
#if _LOCALSERVER==1
|
||||
|
||||
struct codex {
|
||||
uint32_t id; // This is the device ID (coded in 4 bytes uint32_t
|
||||
char nm[32]; // A name string which is free to choose
|
||||
uint8_t nwkKey[16]; // The Network Session Key
|
||||
uint8_t appKey[16]; // The Application Session Key
|
||||
};
|
||||
|
||||
// Sometimes we want to decode the sensor completely as we do in the TTN server
|
||||
// This means that for all nodes we want to view the dara of, we need to provide
|
||||
// he AppsSKey and the NwkSKey
|
||||
|
||||
// Definition of all nodes that we want to decode locally on the gateway.
|
||||
//
|
||||
codex decodes[] = {
|
||||
{ 0x2601148C , "lora-36", // F=0
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
},
|
||||
{ 0x26011b96 , "lora-50", // F=0
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x02, 0x04, 0x32, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x69, 0x6E, 0x67, 0x73, 0x34, 0x55 }
|
||||
},
|
||||
{ 0x26011999 , "lora-901", // F=0
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
}
|
||||
};
|
||||
#endif //_LOCALSERVER
|
17
README.md
17
README.md
|
@ -1,6 +1,6 @@
|
|||
# Single Channel LoRaWAN Gateway
|
||||
|
||||
Version 5.3.1, June 30, 2018
|
||||
Version 5.3.2, July 07, 2018
|
||||
Author: M. Westenberg (mw12554@hotmail.com)
|
||||
Copyright: M. Westenberg (mw12554@hotmail.com)
|
||||
|
||||
|
@ -49,18 +49,11 @@ under the Gateway chapter.
|
|||
|
||||
## testing
|
||||
|
||||
This Gateway code has been tested on the following boards:
|
||||
|
||||
- Wemos D1 Mini + Hallard board with RFM95
|
||||
- Wemos D1 Mini + Comresult board with RFM95
|
||||
- TTGO T-Beam board, ESP32, SX1276, Battery and GPS
|
||||
- TTGO ESP32 V1 board, SX1276 on EU868
|
||||
- TTGO ESP32 V1 board, SX1278, OLED on 433MHz
|
||||
|
||||
The single channel gateway has been tested on a gateway with the Wemos D1 Mini, using a HopeRF RFM95W transceiver.
|
||||
The LoRa nodes tested againts this gateway are:
|
||||
|
||||
- TeensyLC with HopeRF RFM95 radio
|
||||
- Arduino Pro-Mini (default Atmega328 model, 8MHz 3.3V and 16MHz 3.3V)
|
||||
- Arduino Pro-Mini (default Armega328 model, 8MHz 3.3V and 16MHz 3.3V)
|
||||
- ESP8266 based nodes with RFM95 transceivers.
|
||||
|
||||
The code has been tested on at least 8 separate gateway boards both based on the Hallard and the Comresult boards.
|
||||
|
@ -400,9 +393,9 @@ The following things are still on my wish list to make to the single channel gat
|
|||
|
||||
- Receive downstream message with commands from the server. These can be used to configure
|
||||
the gateway through downlink messages (such as setting the SF)
|
||||
- Support for ESP32 and RFM95 on 915 MHz
|
||||
- Support for ESP32 and RFM95 on 433 MHz
|
||||
- Use the SPIFFS for storing .css files
|
||||
- Use the SPIFFS for storing node data (for later analysis)
|
||||
- Look at CLass B and C support
|
||||
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue