Merge branch 'timmbogner:main' into dev_timekeeping

pull/142/head
Jeff Lehman 1 year ago committed by GitHub
commit eb818c5d7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -48,6 +48,7 @@
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
///#define USE_OLED
#define OLED_HEADER "FDRS"
#define OLED_PAGE_SECS 30
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16

@ -48,6 +48,7 @@
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
///#define USE_OLED
#define OLED_HEADER "FDRS"
#define OLED_PAGE_SECS 30
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16

@ -48,6 +48,7 @@
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
///#define USE_OLED
#define OLED_HEADER "FDRS"
#define OLED_PAGE_SECS 30
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16

@ -48,6 +48,7 @@
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
///#define USE_OLED
#define OLED_HEADER "FDRS"
#define OLED_PAGE_SECS 30
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16

@ -127,6 +127,7 @@ void setup() {
subscribeFDRS(READING_ID);
}
void loop() {
loopFDRS();
if (new_data) {
new_data = false;
if (hsv_mode) {

@ -8,8 +8,6 @@
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#define
#define CONTROL_1 101 //Address for controller 1
#define CONTROL_2 102 //Address for controller 2
#define CONTROL_3 103 //Address for controller 3
@ -25,36 +23,36 @@ int status_2 = 0;
int status_3 = 0;
int status_4 = 0;
bool newData = false;
bool isData = false;
bool newStatus = false;
void fdrs_recv_cb(DataReading theData) {
DBG(String(theData.id));
switch (theData.t) {
case 0: // Incoming command is to SET a value
switch (theData.id) {
case CONTROL_1:
status_1 = (int)theData.d;
newData = true;
isData = true;
break;
case CONTROL_2:
status_2 = (int)theData.d;
newData = true;
isData = true;
break;
case CONTROL_3:
status_3 = (int)theData.d;
newData = true;
isData = true;
break;
case CONTROL_4:
status_4 = (int)theData.d;
newData = true;
isData = true;
break;
}
break;
case 1: // Incoming command is to GET a value
switch (theData.id) {
switch (theData.id) {
case CONTROL_1:
if (digitalRead(COIL_1) == HIGH) {
loadFDRS(1, STATUS_T, CONTROL_1);
@ -86,7 +84,6 @@ switch (theData.id) {
}
newStatus = true;
break;
}
}
@ -143,6 +140,7 @@ void updateCoils() { //These are set up for relay module which are active-LOW.
void setup() {
beginFDRS();
pingFDRS(1000);
if (addFDRS(1000, fdrs_recv_cb)) {
subscribeFDRS(CONTROL_1);
subscribeFDRS(CONTROL_2);
@ -164,8 +162,9 @@ void setup() {
}
void loop() {
if (newData) {
newData = false;
loopFDRS();
if (isData) {
isData = false;
updateCoils();
checkCoils();
}

@ -17,6 +17,7 @@ void setup() {
pinMode(COIL_PIN, OUTPUT);
}
void loop() {
loopFDRS();
if (status) digitalWrite(COIL_PIN, HIGH);
else digitalWrite(COIL_PIN, LOW);
}

@ -80,6 +80,7 @@ void setup() {
void loop()
{
loopFDRS();
if (newData) {
newData = false;
updateScreen();

@ -48,6 +48,7 @@
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
///#define USE_OLED
#define OLED_HEADER "FDRS"
#define OLED_PAGE_SECS 30
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16

@ -85,13 +85,19 @@ LoRa chip select pin.
#### ```#define LORA_RST n```
LoRa reset pin.
#### ```#define LORA_DIO n```
LoRa DIO pin. This refers to DIO1 on SX127x chips and DIO1 on SX126x chips.
LoRa DIO pin. This refers to DIO0 on SX127x chips and DIO1 on SX126x chips.
#### ```#define LORA_BUSY n```
For SX126x chips: LoRa BUSY pin. For SX127x: DIO1 pin, or "RADIOLIB_NC" to leave it blank.
#### ```#define LORA_TXPWR n```
LoRa TX power in dBm.
#### ```#define USE_SX126X```
Enable this if using the SX126x series of LoRa chips.
#### ```#define CUSTOM_SPI```
Enable this to define non-default SPI pins.
#### ```#define LORA_SPI_SCK n```, ```LORA_SPI_MISO n```, ```LORA_SPI_MOSI n```
Custom SPI pin definitions.
#
**LoRa radio parameters are generally configured in the 'src/fdrs_globals.h' file.** The following values may be set in the gateway configuration file if the user wishes to override the global value:
@ -110,11 +116,6 @@ LoRa sync word. Can be used to distinguish different networks. Note that 0x34 is
#### ```#define LORA_INTERVAL n```
Interval between LoRa buffer releases. Must be longer than transmission time-on-air.
#### ```#define CUSTOM_SPI```
Enable this to define non-default SPI pins.
#### ```#define LORA_SPI_SCK n```, ```LORA_SPI_MISO n```, ```LORA_SPI_MOSI n```
Custom SPI pin definitions.
## WiFi and MQTT Configuration
WiFi and MQTT parameters are generally configured in the 'src/fdrs_globals.h' file. The following values may be set in the gateway configuration file if the user wishes to override the global value:
#### ```#define WIFI_SSID "cccc"``` and ``` WIFI_PASS "cccc" ```
@ -192,4 +193,4 @@ void loop() {
![Basic LoRa](Basic_LoRa_Setup.png)
![Advanced LoRa](Advanced_Setup_LoRa.png)
![Advanced LoRa](Advanced_Setup_LoRa.png)

@ -216,6 +216,9 @@ void loopFDRS()
#endif
#ifdef USE_WIFI
handleMQTT();
#endif
#ifdef USE_OLED
drawPageOLED(true);
#endif
if (newData != event_clear)
{

@ -72,21 +72,25 @@
#define FDRS_LORA_INTERVAL GLOBAL_LORA_INTERVAL
#endif // LORA_INTERVAL
const uint8_t lora_size = 256 / sizeof(DataReading);
#ifndef LORA_BUSY
#define LORA_BUSY RADIOLIB_NC
#endif
const uint8_t lora_size = 250 / sizeof(DataReading);
#ifdef CUSTOM_SPI
#ifdef ESP32
SPIClass SPI1(HSPI);
#endif // ESP32
#ifdef ARDUINO_ARCH_RP2040
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY, SPI1);
#endif // RP2040
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY, SPI);
#else
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY);
#endif // CUSTOM_SPI
#ifndef USE_ESPNOW // mac_prefix used for both ESP-NOW and LoRa - avoid redefinition warnings
const uint8_t mac_prefix[] = {MAC_PREFIX};
const uint8_t selfAddress[] = {MAC_PREFIX, UNIT_MAC};
const uint8_t mac_prefix[] = {MAC_PREFIX};
const uint8_t selfAddress[] = {MAC_PREFIX, UNIT_MAC};
#endif
bool pingFlag = false;
@ -201,10 +205,10 @@ crcResult transmitLoRa(uint16_t *destMac, DataReading *packet, uint8_t len)
// printf("CRC: %02X : %d\n",calcCRC, i);
calcCRC = crc16_update(calcCRC, pkt[i]);
}
if (*destMac == 0xFFFF)
{
calcCRC = crc16_update(calcCRC, 0xA1);
}
//if (*destMac == 0xFFFF)
//{
calcCRC = crc16_update(calcCRC, 0xA1);
//}
pkt[(len * sizeof(DataReading) + 4)] = (calcCRC >> 8); // Append calculated CRC to the last 2 bytes of the packet
pkt[(len * sizeof(DataReading) + 5)] = (calcCRC & 0x00FF);
DBG("Transmitting LoRa message of size " + String(sizeof(pkt)) + " bytes with CRC 0x" + String(calcCRC, HEX) + " to LoRa MAC 0x" + String(*destMac, HEX));
@ -284,7 +288,7 @@ void begin_lora()
{
#ifdef CUSTOM_SPI
#ifdef ESP32
SPI1.begin(LORA_SPI_SCK, LORA_SPI_MISO, LORA_SPI_MOSI);
SPI.begin(LORA_SPI_SCK, LORA_SPI_MISO, LORA_SPI_MOSI);
#endif // ESP32
#ifdef ARDUINO_ARCH_RP2040
SPI1.setRX(LORA_SPI_MISO);
@ -312,7 +316,7 @@ void begin_lora()
#ifdef USE_SX126X
radio.setDio1Action(setFlag);
#else
radio.setDio0Action(setFlag);
radio.setDio0Action(setFlag, RISING);
#endif
radio.setCRC(false);
@ -437,7 +441,7 @@ crcResult getLoRa()
return CRC_OK;
}
else if (packetCRC == crc16_update(calcCRC, 0xA1))
{ // Sender does not want ACK and CRC is valid
{ // Sender does not want ACK and CRC is valid
memcpy(receiveData, &packet[4], packetSize - 6); // Split off data portion of packet (N bytes)
if (ln == 1 && receiveData[0].cmd == cmd_ack)
{
@ -511,24 +515,24 @@ void sendLoRaNbr(uint8_t interface)
DBG("Sending to LoRa neighbor buffer");
switch (interface)
{
case 1:
{
for (int i = 0; i < ln; i++)
{
LORA1Buffer.buffer[LORA1Buffer.len + i] = theData[i];
}
LORA1Buffer.len += ln;
break;
}
case 2:
{
for (int i = 0; i < ln; i++)
{
LORA2Buffer.buffer[LORA2Buffer.len + i] = theData[i];
}
LORA2Buffer.len += ln;
break;
}
case 1:
{
for (int i = 0; i < ln; i++)
{
LORA1Buffer.buffer[LORA1Buffer.len + i] = theData[i];
}
LORA1Buffer.len += ln;
break;
}
case 2:
{
for (int i = 0; i < ln; i++)
{
LORA2Buffer.buffer[LORA2Buffer.len + i] = theData[i];
}
LORA2Buffer.len += ln;
break;
}
}
}
@ -537,75 +541,58 @@ void asyncReleaseLoRa(bool first_run)
delay(3);
if (first_run)
{
TxStatus = TxLoRa1;
if (LORA1Buffer.len > 0) {
TxStatus = TxLoRa1;
} else if (LORA2Buffer.len > 0) {
TxStatus = TxLoRa2;
} else if (LORABBuffer.len > 0) {
TxStatus = TxLoRaB;
} else {
goto TxFin;
}
tx_start_time = millis();
}
switch (TxStatus)
{
case TxLoRa1:
if (LORA1Buffer.len == 0)
{
TxStatus = TxLoRa2;
goto TxL2;
}
else
{
if (LORA1Buffer.len - tx_buffer_position > lora_size)
{
case TxLoRa1:
if (LORA1Buffer.len - tx_buffer_position > lora_size) {
transmitLoRa(&LoRa1, &LORA1Buffer.buffer[tx_buffer_position], lora_size);
tx_buffer_position += lora_size;
}
else
{
} else {
transmitLoRa(&LoRa1, &LORA1Buffer.buffer[tx_buffer_position], LORA1Buffer.len - tx_buffer_position);
tx_buffer_position = 0;
TxStatus = TxLoRa2;
if (LORA2Buffer.len > 0) {
TxStatus = TxLoRa2;
} else if ((LORABBuffer.len > 0)) {
TxStatus = TxLoRaB;
} else {
goto TxFin;
}
}
break;
case TxLoRa2:
TxL2:
if (LORA2Buffer.len == 0)
{
TxStatus = TxLoRaB;
goto TxLB;
}
else
{
if (LORA2Buffer.len - tx_buffer_position > lora_size)
{
transmitLoRa(&LoRa2, &LORA2Buffer.buffer[tx_buffer_position], lora_size);
tx_buffer_position += lora_size;
}
else
{
transmitLoRa(&LoRa2, &LORA2Buffer.buffer[tx_buffer_position], LORA2Buffer.len - tx_buffer_position);
tx_buffer_position = 0;
if (LORA2Buffer.len - tx_buffer_position > lora_size) {
transmitLoRa(&LoRa2, &LORA2Buffer.buffer[tx_buffer_position], lora_size);
tx_buffer_position += lora_size;
} else {
transmitLoRa(&LoRa2, &LORA2Buffer.buffer[tx_buffer_position], LORA2Buffer.len - tx_buffer_position);
tx_buffer_position = 0;
if (LORABBuffer.len > 0) {
TxStatus = TxLoRaB;
} else {
goto TxFin;
}
}
break;
case TxLoRaB:
TxLB:
// DBG(LORABBuffer.len);
if (LORABBuffer.len == 0)
{
TxStatus = TxIdle;
goto TxFin;
}
else
{
if (LORABBuffer.len - tx_buffer_position > lora_size)
{
transmitLoRa(&loraBroadcast, &LORABBuffer.buffer[tx_buffer_position], lora_size);
tx_buffer_position += lora_size;
}
else
{
transmitLoRa(&loraBroadcast, &LORABBuffer.buffer[tx_buffer_position], LORABBuffer.len - tx_buffer_position);
TxFin:
if (LORABBuffer.len + LORA1Buffer.len +LORA2Buffer.len > 0)
DBG("LoRa airtime: " + String(millis() - tx_start_time) + "ms");
radio.startReceive();
if (LORABBuffer.len - tx_buffer_position > lora_size) {
transmitLoRa(&loraBroadcast, &LORABBuffer.buffer[tx_buffer_position], lora_size);
tx_buffer_position += lora_size;
} else {
transmitLoRa(&loraBroadcast, &LORABBuffer.buffer[tx_buffer_position], LORABBuffer.len - tx_buffer_position);
TxFin:
if (LORABBuffer.len + LORA1Buffer.len + LORA2Buffer.len > 0) {
LORABBuffer.len = 0;
LORA1Buffer.len = 0;
LORA2Buffer.len = 0;
@ -614,10 +601,10 @@ void asyncReleaseLoRa(bool first_run)
}
}
break;
}
}
}
void asyncReleaseLoRaFirst()
{
asyncReleaseLoRa(true);
@ -628,6 +615,10 @@ crcResult handleLoRa()
crcResult crcReturned = CRC_NULL;
if (operationDone) // the interrupt was triggered
{
// DBG("Interrupt triggered");
// DBG("TxFlag: " + String(transmitFlag));
// DBG("TxStatus: " + String(TxStatus));
enableInterrupt = false;
operationDone = false;
if (transmitFlag) // the previous operation was transmission
@ -640,7 +631,7 @@ crcResult handleLoRa()
}
else
{
DBG("LoRa airtime: " + String(millis() - tx_start_time) + "ms");
radio.startReceive(); // return to listen mode
enableInterrupt = true;
transmitFlag = false;

@ -70,15 +70,14 @@
#endif // LORA_SYNCWORD
#ifdef CUSTOM_SPI
#ifdef ESP32
SPIClass SPI1(HSPI);
#endif // ESP32
#ifdef ARDUINO_ARCH_RP2040
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY, SPI1);
#endif // RP2040
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY, SPI);
#else
RADIOLIB_MODULE radio = new Module(LORA_SS, LORA_DIO, LORA_RST, LORA_BUSY);
#endif // CUSTOM_SPI
bool pingFlag = false;
bool transmitFlag = false; // flag to indicate transmission or reception state
volatile bool enableInterrupt = true; // disable interrupt when it's not needed
@ -148,7 +147,7 @@ void begin_lora()
{
#ifdef CUSTOM_SPI
#ifdef ESP32
SPI1.begin(LORA_SPI_SCK, LORA_SPI_MISO, LORA_SPI_MOSI);
SPI.begin(LORA_SPI_SCK, LORA_SPI_MISO, LORA_SPI_MOSI);
#endif // ESP32
#ifdef ARDUINO_ARCH_RP2040
SPI1.setRX(LORA_SPI_MISO);
@ -178,7 +177,7 @@ void begin_lora()
#ifdef USE_SX126X
radio.setDio1Action(setFlag);
#else
radio.setDio0Action(setFlag);
radio.setDio0Action(setFlag, RISING);
#endif
radio.setCRC(false);
LoRaAddress = ((radio.randomByte() << 8) | radio.randomByte());
@ -511,7 +510,9 @@ uint32_t pingFDRSLoRa(uint16_t *address, uint32_t timeout)
while ((millis() - ping_start) <= timeout)
{
handleLoRa();
yield(); // do I need to yield or does it automatically?
#ifdef ESP8266
yield();
#endif
if (pingFlag)
{
DBG("LoRa Ping Returned: " + String(millis() - ping_start) + "ms.");

@ -1,9 +1,12 @@
#include <ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays/src/SSD1306Wire.h>
#define DISPLAY_PAGES 4
String debug_buffer[5] = {"", "", "", "", ""};
SSD1306Wire display(0x3c, OLED_SDA, OLED_SCL); // ADDRESS, SDA, SCL
unsigned long displayEvent = 0;
uint8_t displayPage = 0;
void draw_OLED_header()
{
@ -33,13 +36,28 @@ void draw_OLED_header()
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
#endif
display.drawHorizontalLine(0, 15, 128);
display.drawHorizontalLine(0, 16, 128);
}
void drawDebugPage() {
draw_OLED_header();
uint8_t lineNumber = 0;
for (uint8_t i = 0; i < 5; i++)
{
uint8_t ret = display.FDRS_drawStringMaxWidth(0, 17 + (lineNumber * 9), 127, debug_buffer[i]);
lineNumber = ret + lineNumber;
if (lineNumber > 5)
break;
}
display.display();
}
void debug_OLED(String debug_text)
{
draw_OLED_header();
display.drawHorizontalLine(0, 15, 128);
display.drawHorizontalLine(0, 16, 128);
displayEvent = millis()/1000; // Display Event is tracked in units of seconds
displayPage = 0;
display.clear();
for (uint8_t i = 4; i > 0; i--)
{
@ -47,16 +65,73 @@ void debug_OLED(String debug_text)
debug_buffer[i] = debug_buffer[i - 1];
}
debug_buffer[0] = String(millis() / 1000) + " " + debug_text;
uint8_t lineNumber = 0;
for (uint8_t i = 0; i < 5; i++)
{
uint8_t ret = display.FDRS_drawStringMaxWidth(0, 17 + (lineNumber * 9), 127, debug_buffer[i]);
lineNumber = ret + lineNumber;
if (lineNumber > 5)
drawDebugPage();
}
void drawBlankPage() {
display.clear();
display.display();
}
void drawStatusPage() {
// draw_OLED_header();
// display.FDRS_drawStringMaxWidth(0, 17, 127, "Status Page 1 " + String(millis()/1000));
// display.display();
}
void drawPage2() {
// draw_OLED_header();
// display.FDRS_drawStringMaxWidth(0, 17, 127, "Page 2 " + String(millis()/1000));
// display.display();
}
void drawPage3() {
// draw_OLED_header();
// display.FDRS_drawStringMaxWidth(0, 17, 127, "Page 3 " + String(millis()/1000));
// display.display();
}
// write display content to display buffer
// nextpage = true -> flip 1 page
// When debug info comes in then switch to debug page
// after 60 seconds switch to blank page to save screen
void drawPageOLED(bool nextpage) {
if((millis()/1000 - displayEvent) > OLED_PAGE_SECS && nextpage) {
displayPage = (displayPage >= DISPLAY_PAGES) ? 0 : (displayPage + 1);
displayEvent = millis()/1000;
display.clear();
switch(displayPage) {
// page 0: debug output
// page 1: gateway/node status
// page 2: to be defined
// page 3: to be defined
// page 4: blank (screen saver)
case 0: // display debug output
drawDebugPage();
break;
case 1: // gateway/node status
// drawStatusPage();
// break;
case 2: // to be defined later
// drawPage2();
// break;
case 3: // to be defined later
// drawPage3();
// break;
case 4: // Blank page
drawBlankPage();
break;
default: // Blank page
drawBlankPage();
break;
}
}
display.display();
}
void init_oled(){
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
@ -66,6 +141,4 @@ void init_oled(){
display.init();
display.flipScreenVertically();
draw_OLED_header();
}
Loading…
Cancel
Save