mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Allow lora on ESP8266
This commit is contained in:
parent
87567b25b2
commit
b218f6bff1
15
tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino
Normal file
15
tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
xdrv_73_0_lora_struct.ino - LoRa support for Tasmota
|
||||||
|
|
||||||
|
SPDX-FileCopyrightText: 2024 Theo Arends
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_SPI
|
||||||
|
#ifdef USE_SPI_LORA
|
||||||
|
|
||||||
|
#define LORA_MAX_PACKET_LENGTH 252 // Max packet length allowed (defined by RadioLib driver)
|
||||||
|
|
||||||
|
#endif // USE_SPI_LORA
|
||||||
|
#endif // USE_SPI
|
106
tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx1262.ino
Normal file
106
tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx1262.ino
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
xdrv_73_3_lora_sx1262.ino - LoRa support for Tasmota
|
||||||
|
|
||||||
|
SPDX-FileCopyrightText: 2024 Theo Arends
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_SPI
|
||||||
|
#ifdef USE_SPI_LORA
|
||||||
|
#ifdef USE_LORA_SX1262
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Demo of LoRa using LilyGo T3S3 using SX1262 on 868MHz
|
||||||
|
*
|
||||||
|
* Tasmota currently does not support user config of GPIO33 and GPIO34 on ESP32S3
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#include <RadioLib.h>
|
||||||
|
SX1262 LoRa = nullptr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
// flag to indicate that a packet was received
|
||||||
|
volatile bool receivedFlag;
|
||||||
|
// disable interrupt when it's not needed
|
||||||
|
volatile bool enableInterrupt;
|
||||||
|
|
||||||
|
bool sendFlag;
|
||||||
|
} Sx1262;
|
||||||
|
|
||||||
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
// this function is called when a complete packet is received by the module
|
||||||
|
// IMPORTANT: this function MUST be 'void' type and MUST NOT have any arguments!
|
||||||
|
void LoraSetFlagSx1262(void) {
|
||||||
|
// check if the interrupt is enabled
|
||||||
|
if (!Sx1262.enableInterrupt) { return; }
|
||||||
|
// we got a packet, set the flag
|
||||||
|
Sx1262.receivedFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoraAvailableSx1262(void) {
|
||||||
|
// check if the flag is set
|
||||||
|
return (Sx1262.receivedFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoraInputSx1262(char* data) {
|
||||||
|
int packet_size = 0;
|
||||||
|
|
||||||
|
// disable the interrupt service routine while processing the data
|
||||||
|
Sx1262.enableInterrupt = false;
|
||||||
|
|
||||||
|
// reset flag
|
||||||
|
Sx1262.receivedFlag = false;
|
||||||
|
|
||||||
|
// String str;
|
||||||
|
// int state = LoRa.readData(str);
|
||||||
|
int state = LoRa.readData((uint8_t*)data, LORA_MAX_PACKET_LENGTH -1);
|
||||||
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
|
if (!Sx1262.sendFlag) {
|
||||||
|
// Find end of raw data being non-zero (No way to know raw data length)
|
||||||
|
packet_size = LORA_MAX_PACKET_LENGTH;
|
||||||
|
while (packet_size-- && (0 == data[packet_size]));
|
||||||
|
if (0 != data[packet_size]) { packet_size++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||||
|
// packet was received, but is malformed
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: CRC error"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// some other error occurred
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Receive error %d"), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// put module back to listen mode
|
||||||
|
LoRa.startReceive();
|
||||||
|
|
||||||
|
Sx1262.sendFlag = false;
|
||||||
|
// we're ready to receive more packets, enable interrupt service routine
|
||||||
|
Sx1262.enableInterrupt = true;
|
||||||
|
|
||||||
|
return packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoraInitSx1262(void) {
|
||||||
|
// LoRa = new Module(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_DI1), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_BUSY));
|
||||||
|
LoRa = new Module(Pin(GPIO_LORA_CS), 33, Pin(GPIO_LORA_RST), 34);
|
||||||
|
if (RADIOLIB_ERR_NONE == LoRa.begin(868.0)) {
|
||||||
|
Sx1262.enableInterrupt = true;
|
||||||
|
LoRa.setDio1Action(LoraSetFlagSx1262);
|
||||||
|
if (RADIOLIB_ERR_NONE == LoRa.startReceive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoraSendSx1262(char* data, uint32_t len) {
|
||||||
|
Sx1262.sendFlag = true;
|
||||||
|
LoRa.startTransmit(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_LORA_SX1262
|
||||||
|
#endif // USE_SPI_LORA
|
||||||
|
#endif // USE_SPI
|
||||||
|
|
@ -1,133 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
xdrv_80_esp32_lora.ino - LoRa support for Tasmota
|
xdrv_73_9_lora.ino - LoRa support for Tasmota
|
||||||
|
|
||||||
SPDX-FileCopyrightText: 2024 Theo Arends
|
SPDX-FileCopyrightText: 2024 Theo Arends
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-3.0-only
|
SPDX-License-Identifier: GPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
#ifdef USE_SPI
|
#ifdef USE_SPI
|
||||||
#ifdef USE_SPI_LORA
|
#ifdef USE_SPI_LORA
|
||||||
#ifdef USE_LORA_SX1262
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Demo of LoRa using LilyGo T3S3 using SX1262 on 868MHz
|
* LoRa
|
||||||
*
|
|
||||||
* Tasmota currently does not support user config of GPIO33 and GPIO34 on ESP32S3
|
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define XDRV_80 80
|
#define XDRV_73 73
|
||||||
|
|
||||||
#define LORA_MAX_PACKET_LENGTH 252 // Max packet length allowed (defined by RadioLib driver)
|
|
||||||
|
|
||||||
#include <RadioLib.h>
|
|
||||||
SX1262 LoRa = nullptr;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// flag to indicate that a packet was received
|
|
||||||
volatile bool receivedFlag;
|
|
||||||
// disable interrupt when it's not needed
|
|
||||||
volatile bool enableInterrupt;
|
|
||||||
|
|
||||||
bool sendFlag;
|
|
||||||
bool raw;
|
bool raw;
|
||||||
bool present;
|
bool present;
|
||||||
} Lora;
|
} Lora;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
// this function is called when a complete packet is received by the module
|
|
||||||
// IMPORTANT: this function MUST be 'void' type and MUST NOT have any arguments!
|
|
||||||
void LoraSetFlag(void) {
|
|
||||||
// check if the interrupt is enabled
|
|
||||||
if (!Lora.enableInterrupt) { return; }
|
|
||||||
// we got a packet, set the flag
|
|
||||||
Lora.receivedFlag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
|
||||||
|
|
||||||
void LoraInput(void) {
|
void LoraInput(void) {
|
||||||
// check if the flag is set
|
if (!LoraAvailableSx1262()) { return; }
|
||||||
if (!Lora.receivedFlag) { return; }
|
|
||||||
|
|
||||||
// disable the interrupt service routine while processing the data
|
|
||||||
Lora.enableInterrupt = false;
|
|
||||||
|
|
||||||
// reset flag
|
|
||||||
Lora.receivedFlag = false;
|
|
||||||
|
|
||||||
// String str;
|
|
||||||
// int state = LoRa.readData(str);
|
|
||||||
char data[LORA_MAX_PACKET_LENGTH] = { 0 };
|
char data[LORA_MAX_PACKET_LENGTH] = { 0 };
|
||||||
int state = LoRa.readData((uint8_t*)data, LORA_MAX_PACKET_LENGTH -1);
|
int packet_size = LoraInputSx1262(data);
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (!packet_size) { return; }
|
||||||
if (!Lora.sendFlag) {
|
|
||||||
// Find end of raw data being non-zero (No way to know raw data length)
|
bool raw = Lora.raw;
|
||||||
uint32_t len = LORA_MAX_PACKET_LENGTH;
|
// Set raw mode if zeroes within data
|
||||||
while (len-- && (0 == data[len]));
|
for (uint32_t i = 0; i < packet_size; i++) {
|
||||||
if (len) {
|
if (0 == data[i]) {
|
||||||
len++;
|
raw = true;
|
||||||
bool raw = Lora.raw;
|
break;
|
||||||
// Set raw mode if zeroes within data
|
|
||||||
for (uint32_t i = 0; i < len; i++) {
|
|
||||||
if (0 == data[i]) {
|
|
||||||
raw = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool assume_json = (!raw && (data[0] == '{'));
|
|
||||||
Response_P(PSTR("{\"LoRaReceived\":"));
|
|
||||||
if (assume_json) {
|
|
||||||
ResponseAppend_P(data);
|
|
||||||
} else {
|
|
||||||
ResponseAppend_P(PSTR("\""));
|
|
||||||
if (raw) {
|
|
||||||
ResponseAppend_P(PSTR("%*_H"), len, data);
|
|
||||||
} else {
|
|
||||||
ResponseAppend_P(EscapeJSONString(data).c_str());
|
|
||||||
}
|
|
||||||
ResponseAppend_P(PSTR("\""));
|
|
||||||
}
|
|
||||||
float rssi = LoRa.getRSSI();
|
|
||||||
float snr = LoRa.getSNR();
|
|
||||||
ResponseAppend_P(PSTR(",\"RSSI\":%1_f,\"SNR\":%1_f}"), &rssi, &snr);
|
|
||||||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR("LoRaReceived"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
bool assume_json = (!raw && (data[0] == '{'));
|
||||||
// packet was received, but is malformed
|
Response_P(PSTR("{\"LoRaReceived\":"));
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: CRC error"));
|
if (assume_json) {
|
||||||
}
|
ResponseAppend_P(data);
|
||||||
else {
|
} else {
|
||||||
// some other error occurred
|
ResponseAppend_P(PSTR("\""));
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Receive error %d"), state);
|
if (raw) {
|
||||||
|
ResponseAppend_P(PSTR("%*_H"), packet_size, data);
|
||||||
|
} else {
|
||||||
|
ResponseAppend_P(EscapeJSONString(data).c_str());
|
||||||
|
}
|
||||||
|
ResponseAppend_P(PSTR("\""));
|
||||||
}
|
}
|
||||||
|
// float rssi = LoRa.getRSSI();
|
||||||
|
// float snr = LoRa.getSNR();
|
||||||
|
// ResponseAppend_P(PSTR(",\"RSSI\":%1_f,\"SNR\":%1_f}"), &rssi, &snr);
|
||||||
|
ResponseJsonEnd();
|
||||||
|
|
||||||
// put module back to listen mode
|
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR("LoRaReceived"));
|
||||||
LoRa.startReceive();
|
|
||||||
|
|
||||||
Lora.sendFlag = false;
|
|
||||||
// we're ready to receive more packets,
|
|
||||||
// enable interrupt service routine
|
|
||||||
Lora.enableInterrupt = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoraInit(void) {
|
void LoraInit(void) {
|
||||||
if ((SPI_MOSI_MISO == TasmotaGlobal.spi_enabled) &&
|
if ((SPI_MOSI_MISO == TasmotaGlobal.spi_enabled) &&
|
||||||
(PinUsed(GPIO_LORA_CS)) && (PinUsed(GPIO_LORA_RST))) {
|
(PinUsed(GPIO_LORA_CS)) && (PinUsed(GPIO_LORA_RST))) {
|
||||||
|
#ifdef ESP8266
|
||||||
|
SPI.begin();
|
||||||
|
#endif // ESP8266
|
||||||
|
#ifdef ESP32
|
||||||
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
||||||
|
#endif // ESP32
|
||||||
// LoRa = new Module(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_DI1), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_BUSY));
|
if (LoraInitSx1262()) {
|
||||||
LoRa = new Module(Pin(GPIO_LORA_CS), 33, Pin(GPIO_LORA_RST), 34);
|
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Initialized"));
|
||||||
if (RADIOLIB_ERR_NONE == LoRa.begin(868.0)) {
|
Lora.present = true;
|
||||||
Lora.enableInterrupt = true;
|
|
||||||
LoRa.setDio1Action(LoraSetFlag);
|
|
||||||
if (RADIOLIB_ERR_NONE == LoRa.startReceive()) {
|
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Initialized"));
|
|
||||||
Lora.present = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,11 +97,11 @@ void CmndLoraSend(void) {
|
|||||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
||||||
Lora.raw = (XdrvMailbox.index > 3); // Global flag set even without data
|
Lora.raw = (XdrvMailbox.index > 3); // Global flag set even without data
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint8_t data[LORA_MAX_PACKET_LENGTH];
|
char data[LORA_MAX_PACKET_LENGTH];
|
||||||
uint32_t len = (XdrvMailbox.data_len < LORA_MAX_PACKET_LENGTH -1) ? XdrvMailbox.data_len : LORA_MAX_PACKET_LENGTH -2;
|
uint32_t len = (XdrvMailbox.data_len < LORA_MAX_PACKET_LENGTH -1) ? XdrvMailbox.data_len : LORA_MAX_PACKET_LENGTH -2;
|
||||||
if (1 == XdrvMailbox.index) { // "Hello Tiger\n"
|
if (1 == XdrvMailbox.index) { // "Hello Tiger\n"
|
||||||
memcpy(data, XdrvMailbox.data, len);
|
memcpy(data, XdrvMailbox.data, len);
|
||||||
data[len++] = (uint8_t)'\n';
|
data[len++] = '\n';
|
||||||
}
|
}
|
||||||
else if ((2 == XdrvMailbox.index) || (4 == XdrvMailbox.index)) { // "Hello Tiger" or "A0"
|
else if ((2 == XdrvMailbox.index) || (4 == XdrvMailbox.index)) { // "Hello Tiger" or "A0"
|
||||||
memcpy(data, XdrvMailbox.data, len);
|
memcpy(data, XdrvMailbox.data, len);
|
||||||
@ -199,8 +140,7 @@ void CmndLoraSend(void) {
|
|||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
if (len) {
|
if (len) {
|
||||||
Lora.sendFlag = true;
|
LoraSendSx1262(data, len);
|
||||||
LoRa.startTransmit(data, len);
|
|
||||||
}
|
}
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
}
|
}
|
||||||
@ -211,7 +151,7 @@ void CmndLoraSend(void) {
|
|||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
bool Xdrv80(uint32_t function) {
|
bool Xdrv73(uint32_t function) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (FUNC_INIT == function) {
|
if (FUNC_INIT == function) {
|
||||||
@ -234,8 +174,6 @@ bool Xdrv80(uint32_t function) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_LORA_SX1262
|
|
||||||
#endif // USE_SPI_LORA
|
#endif // USE_SPI_LORA
|
||||||
#endif // USE_SPI
|
#endif // USE_SPI
|
||||||
#endif // ESP32
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user