mirror of https://github.com/arendst/Tasmota.git
Fix LoRa Config
This commit is contained in:
parent
77cba87994
commit
24b59376bb
|
@ -8,8 +8,44 @@
|
|||
|
||||
#ifdef USE_SPI
|
||||
#ifdef USE_SPI_LORA
|
||||
/*********************************************************************************************\
|
||||
* LoRa defines and global struct
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define LORA_MAX_PACKET_LENGTH 252 // Max packet length allowed (defined by RadioLib driver)
|
||||
//#define USE_LORA_DEBUG
|
||||
|
||||
#define LORA_MAX_PACKET_LENGTH 252 // Max packet length allowed (keeping room for control bytes)
|
||||
|
||||
#ifndef TAS_LORA_FREQUENCY
|
||||
#define TAS_LORA_FREQUENCY 868.0 // Allowed values range from 150.0 to 960.0 MHz
|
||||
#endif
|
||||
#ifndef TAS_LORA_BANDWIDTH
|
||||
#define TAS_LORA_BANDWIDTH 125.0 // Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz
|
||||
#endif
|
||||
#ifndef TAS_LORA_SPREADING_FACTOR
|
||||
#define TAS_LORA_SPREADING_FACTOR 9 // Allowed values range from 5 to 12
|
||||
#endif
|
||||
#ifndef TAS_LORA_CODING_RATE
|
||||
#define TAS_LORA_CODING_RATE 7 // Allowed values range from 5 to 8
|
||||
#endif
|
||||
#ifndef TAS_LORA_SYNC_WORD
|
||||
#define TAS_LORA_SYNC_WORD 0x12 // Allowed values range from 1 to 255
|
||||
#endif
|
||||
#ifndef TAS_LORA_OUTPUT_POWER
|
||||
#define TAS_LORA_OUTPUT_POWER 10 // Allowed values range from 1 to 20
|
||||
#endif
|
||||
#ifndef TAS_LORA_PREAMBLE_LENGTH
|
||||
#define TAS_LORA_PREAMBLE_LENGTH 8 // Allowed values range from 1 to 65535
|
||||
#endif
|
||||
#ifndef TAS_LORA_CURRENT_LIMIT
|
||||
#define TAS_LORA_CURRENT_LIMIT 60.0 // Overcurrent Protection - OCP in mA
|
||||
#endif
|
||||
#ifndef TAS_LORA_HEADER
|
||||
#define TAS_LORA_HEADER 0 // Explicit (0) or Implicit (1 to 4) Header
|
||||
#endif
|
||||
#ifndef TAS_LORA_CRC_BYTES
|
||||
#define TAS_LORA_CRC_BYTES 2 // No (0) or Number (1 to 4) of CRC bytes
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bool (* Config)(void);
|
||||
|
@ -18,18 +54,17 @@ struct {
|
|||
bool (* Send)(char*, uint32_t);
|
||||
float rssi;
|
||||
float snr;
|
||||
int packet_size;
|
||||
float frequency; // 868.0 MHz
|
||||
float bandwidth; // 125.0 kHz
|
||||
int spreading_factor; // 9
|
||||
int coding_rate; // 7
|
||||
int sync_word; // 0x12
|
||||
int output_power; // 10 dBm
|
||||
long preamble_length; // 8 symbols
|
||||
float current_limit; // 60.0 mA (Overcurrent Protection (OCP))
|
||||
int implicit_header; // 0
|
||||
bool crc_bytes; // 2 bytes
|
||||
uint8_t gain;
|
||||
uint16_t preamble_length; // 8 symbols
|
||||
uint8_t sync_word; // 0x12
|
||||
uint8_t spreading_factor; // 9
|
||||
uint8_t coding_rate; // 7
|
||||
uint8_t output_power; // 10 dBm
|
||||
uint8_t implicit_header; // 0
|
||||
uint8_t crc_bytes; // 2 bytes
|
||||
uint8_t packet_size; // Max is 255 (LORA_MAX_PACKET_LENGTH)
|
||||
volatile bool receivedFlag; // flag to indicate that a packet was received
|
||||
volatile bool enableInterrupt; // disable interrupt when it's not needed
|
||||
bool sendFlag;
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
* - SPI_MOSI
|
||||
* - LoRa_CS
|
||||
* - LoRa_Rst
|
||||
* - Lora_Busy (Tasmota currently does not support user config of GPIO34 on ESP32S3
|
||||
* - Lora_DI1 (Tasmota currently does not support user config of GPIO33 on ESP32S3
|
||||
* - Lora_Busy
|
||||
* - Lora_DI1
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
@ -46,10 +46,10 @@ int LoraReceiveSx126x(char* data) {
|
|||
int state = LoRaRadio.readData((uint8_t*)data, LORA_MAX_PACKET_LENGTH -1);
|
||||
if (RADIOLIB_ERR_NONE == state) {
|
||||
if (!Lora.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++; }
|
||||
packet_size = LoRaRadio.getPacketLength();
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Packet %d, Rcvd %32_H"), packet_size, data);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (RADIOLIB_ERR_CRC_MISMATCH == state) {
|
||||
|
@ -72,36 +72,45 @@ int LoraReceiveSx126x(char* data) {
|
|||
|
||||
bool LoraSendSx126x(char* data, uint32_t len) {
|
||||
Lora.sendFlag = true;
|
||||
// int state = LoRaRadio.startTransmit(data, len);
|
||||
// return (RADIOLIB_ERR_NONE == state);
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Len %d, Send %*_H"), len, len + 2, data);
|
||||
#endif
|
||||
/*
|
||||
int state = LoRaRadio.startTransmit(data, len);
|
||||
return (RADIOLIB_ERR_NONE == state);
|
||||
*/
|
||||
// https://learn.circuit.rocks/battery-powered-lora-sensor-node
|
||||
uint32_t retry_CAD = 0;
|
||||
uint32_t retry_send = 0;
|
||||
bool send_success = false;
|
||||
while (!send_success) {
|
||||
// time_t lora_time = millis();
|
||||
#ifdef USE_LORA_DEBUG
|
||||
time_t lora_time = millis();
|
||||
#endif
|
||||
// Check 200ms for an opportunity to send
|
||||
while (LoRaRadio.scanChannel() != RADIOLIB_CHANNEL_FREE) {
|
||||
retry_CAD++;
|
||||
if (retry_CAD == 20) {
|
||||
// LoRa channel is busy too long, give up
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Channel is too busy, give up"));
|
||||
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Channel is too busy, give up"));
|
||||
#endif
|
||||
retry_send++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: CAD finished after %ldms tried %d times"), (millis() - loraTime), retryCAD);
|
||||
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: CAD finished after %ldms tried %d times"), (millis() - lora_time), retry_CAD);
|
||||
#endif
|
||||
if (retry_CAD < 20) {
|
||||
// Channel is free, start sending
|
||||
// lora_time = millis();
|
||||
#ifdef USE_LORA_DEBUG
|
||||
lora_time = millis();
|
||||
#endif
|
||||
int status = LoRaRadio.transmit(data, len);
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Transmit finished after %ldms with status %d"), (millis() - loraTime), status);
|
||||
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Transmit finished after %ldms with status %d"), (millis() - lora_time), status);
|
||||
#endif
|
||||
if (status == RADIOLIB_ERR_NONE) {
|
||||
send_success = true;
|
||||
}
|
||||
|
@ -110,9 +119,9 @@ bool LoraSendSx126x(char* data, uint32_t len) {
|
|||
}
|
||||
}
|
||||
if (retry_send == 3) {
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Failed 3 times to send data, giving up"));
|
||||
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Failed 3 times to send data, giving up"));
|
||||
#endif
|
||||
send_success = true;
|
||||
}
|
||||
}
|
||||
|
@ -120,15 +129,15 @@ bool LoraSendSx126x(char* data, uint32_t len) {
|
|||
}
|
||||
|
||||
bool LoraConfigSx126x(void) {
|
||||
LoRaRadio.setFrequency(Lora.frequency);
|
||||
LoRaRadio.setBandwidth(Lora.bandwidth);
|
||||
LoRaRadio.setSpreadingFactor(Lora.spreading_factor);
|
||||
LoRaRadio.setCodingRate(Lora.coding_rate);
|
||||
LoRaRadio.setSyncWord(Lora.sync_word);
|
||||
LoRaRadio.setOutputPower(Lora.output_power);
|
||||
LoRaRadio.setPreambleLength(Lora.preamble_length);
|
||||
LoRaRadio.setCurrentLimit(Lora.current_limit);
|
||||
LoRaRadio.setCRC(Lora.crc_bytes);
|
||||
LoRaRadio.setSpreadingFactor(Lora.spreading_factor);
|
||||
LoRaRadio.setBandwidth(Lora.bandwidth);
|
||||
LoRaRadio.setFrequency(Lora.frequency);
|
||||
LoRaRadio.setOutputPower(Lora.output_power);
|
||||
if (Lora.implicit_header) {
|
||||
LoRaRadio.implicitHeader(Lora.implicit_header);
|
||||
} else {
|
||||
|
@ -138,11 +147,7 @@ bool LoraConfigSx126x(void) {
|
|||
}
|
||||
|
||||
bool LoraInitSx126x(void) {
|
||||
int lora_di1 = Pin(GPIO_LORA_DI1);
|
||||
if (lora_di1 == -1) { lora_di1 = 33; } // Workaround support user config of GPIO33 on ESP32S3 for LilyGo T3S3
|
||||
int lora_busy = Pin(GPIO_LORA_BUSY);
|
||||
if (lora_busy == -1) { lora_busy = 34; } // Workaround support user config of GPIO34 on ESP32S3 for LilyGo T3S3
|
||||
LoRaRadio = new Module(Pin(GPIO_LORA_CS), lora_di1, Pin(GPIO_LORA_RST), lora_busy);
|
||||
LoRaRadio = new Module(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_DI1), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_BUSY));
|
||||
if (RADIOLIB_ERR_NONE == LoRaRadio.begin(Lora.frequency)) {
|
||||
LoraConfigSx126x();
|
||||
LoRaRadio.setDio1Action(LoraOnReceiveSx126x);
|
||||
|
|
|
@ -31,9 +31,9 @@
|
|||
|
||||
void LoraOnCadDoneSx127x(boolean signalDetected) {
|
||||
if (signalDetected) { // detect preamble
|
||||
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Signal detected"));
|
||||
|
||||
#endif
|
||||
LoRa.receive(); // put the radio into continuous receive mode
|
||||
} else {
|
||||
LoRa.channelActivityDetection(); // try next activity dectection
|
||||
|
|
|
@ -49,6 +49,19 @@ void LoraInput(void) {
|
|||
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR("LoRaReceived"));
|
||||
}
|
||||
|
||||
void LoraDefaults(void) {
|
||||
Lora.frequency = TAS_LORA_FREQUENCY;
|
||||
Lora.bandwidth = TAS_LORA_BANDWIDTH;
|
||||
Lora.spreading_factor = TAS_LORA_SPREADING_FACTOR;
|
||||
Lora.coding_rate = TAS_LORA_CODING_RATE;
|
||||
Lora.sync_word = TAS_LORA_SYNC_WORD;
|
||||
Lora.output_power = TAS_LORA_OUTPUT_POWER;
|
||||
Lora.preamble_length = TAS_LORA_PREAMBLE_LENGTH;
|
||||
Lora.current_limit = TAS_LORA_CURRENT_LIMIT;
|
||||
Lora.implicit_header = TAS_LORA_HEADER;
|
||||
Lora.crc_bytes = TAS_LORA_CRC_BYTES;
|
||||
}
|
||||
|
||||
void LoraInit(void) {
|
||||
if ((SPI_MOSI_MISO == TasmotaGlobal.spi_enabled) &&
|
||||
(PinUsed(GPIO_LORA_CS)) && (PinUsed(GPIO_LORA_RST))) {
|
||||
|
@ -59,18 +72,8 @@ void LoraInit(void) {
|
|||
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
||||
#endif // ESP32
|
||||
|
||||
Lora.frequency = 868.0; // MHz
|
||||
Lora.bandwidth = 125.0; // kHz
|
||||
Lora.spreading_factor = 9;
|
||||
Lora.coding_rate = 7;
|
||||
Lora.sync_word = 0x12;
|
||||
Lora.output_power = 10; // dBm
|
||||
Lora.preamble_length = 8; // symbols
|
||||
Lora.current_limit = 60.0; // mA (Overcurrent Protection (OCP))
|
||||
Lora.implicit_header = 0; // explicit
|
||||
Lora.crc_bytes = 2; // bytes
|
||||
|
||||
Lora.enableInterrupt = true;
|
||||
LoraDefaults();
|
||||
|
||||
char hardware[20];
|
||||
if (false) {
|
||||
|
@ -89,14 +92,16 @@ void LoraInit(void) {
|
|||
}
|
||||
#endif // USE_LORA_SX127X
|
||||
#ifdef USE_LORA_SX126X
|
||||
else if (LoraInitSx126x()) {
|
||||
else if (PinUsed(GPIO_LORA_DI1) && PinUsed(GPIO_LORA_BUSY)) {
|
||||
// SX1262, LilyGoT3S3
|
||||
Lora.Config = &LoraConfigSx126x;
|
||||
Lora.Available = &LoraAvailableSx126x;
|
||||
Lora.Receive = &LoraReceiveSx126x;
|
||||
Lora.Send = &LoraSendSx126x;
|
||||
strcpy_P(hardware, PSTR("SX126x"));
|
||||
Lora.present = true;
|
||||
if (LoraInitSx126x()) {
|
||||
Lora.Config = &LoraConfigSx126x;
|
||||
Lora.Available = &LoraAvailableSx126x;
|
||||
Lora.Receive = &LoraReceiveSx126x;
|
||||
Lora.Send = &LoraSendSx126x;
|
||||
strcpy_P(hardware, PSTR("SX126x"));
|
||||
Lora.present = true;
|
||||
}
|
||||
}
|
||||
#endif // USE_LORA_SX126X
|
||||
else {
|
||||
|
@ -121,18 +126,23 @@ void (* const LoraCommand[])(void) PROGMEM = {
|
|||
|
||||
void CmndLoraSend(void) {
|
||||
// LoRaSend "Hello Tiger" - Send "Hello Tiger\n"
|
||||
// LoRaSend - Set to text decoding
|
||||
// LoRaSend1 "Hello Tiger" - Send "Hello Tiger\n"
|
||||
// LoRaSend2 "Hello Tiger" - Send "Hello Tiger"
|
||||
// LoRaSend3 "Hello Tiger" - Send "Hello Tiger\f"
|
||||
// LoRaSend4 = LoraSend2
|
||||
// LoRaSend4 - Set to binary decoding
|
||||
// LoRaSend4 "Hello Tiger" - Send "Hello Tiger" and set to binary decoding
|
||||
// LoRaSend5 "AA004566" - Send "AA004566" as hex values
|
||||
// LoRaSend6 "72,101,108,108" - Send decimals as hex values
|
||||
// if (XdrvMailbox.index > 9) { XdrvMailbox.index -= 10; } // Allows leading spaces (not supported - See support_command/CommandHandler)
|
||||
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
||||
Lora.raw = (XdrvMailbox.index > 3); // Global flag set even without data
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
char data[LORA_MAX_PACKET_LENGTH];
|
||||
char data[LORA_MAX_PACKET_LENGTH] = { 0 };
|
||||
uint32_t len = (XdrvMailbox.data_len < LORA_MAX_PACKET_LENGTH -1) ? XdrvMailbox.data_len : LORA_MAX_PACKET_LENGTH -2;
|
||||
#ifdef USE_LORA_DEBUG
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Len %d, Send %*_H"), len, len + 2, XdrvMailbox.data);
|
||||
#endif
|
||||
if (1 == XdrvMailbox.index) { // "Hello Tiger\n"
|
||||
memcpy(data, XdrvMailbox.data, len);
|
||||
data[len++] = '\n';
|
||||
|
@ -183,23 +193,29 @@ void CmndLoraSend(void) {
|
|||
|
||||
void CmndLoraConfig(void) {
|
||||
// LoRaConfig - Show all parameters
|
||||
// LoRaConfig 1 - Set default parameters
|
||||
// LoRaConfig {"Frequency":868.0,"Bandwidth":125.0} - Enter float parameters
|
||||
// LoRaConfig {"SyncWord":18} - Enter decimal parameter (=0x12)
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
JsonParser parser(XdrvMailbox.data);
|
||||
JsonParserObject root = parser.getRootObject();
|
||||
if (root) {
|
||||
Lora.frequency = root.getFloat(PSTR(D_JSON_FREQUENCY), Lora.frequency);
|
||||
Lora.bandwidth = root.getFloat(PSTR(D_JSON_BANDWIDTH), Lora.bandwidth);
|
||||
Lora.spreading_factor = root.getUInt(PSTR(D_JSON_SPREADING_FACTOR), Lora.spreading_factor);
|
||||
Lora.coding_rate = root.getUInt(PSTR(D_JSON_CODINGRATE4), Lora.coding_rate);
|
||||
Lora.sync_word = root.getUInt(PSTR(D_JSON_SYNCWORD), Lora.sync_word);
|
||||
Lora.output_power = root.getUInt(PSTR(D_JSON_OUTPUT_POWER), Lora.output_power);
|
||||
Lora.preamble_length = root.getUInt(PSTR(D_JSON_PREAMBLE_LENGTH), Lora.preamble_length);
|
||||
Lora.current_limit = root.getFloat(PSTR(D_JSON_CURRENT_LIMIT), Lora.current_limit);
|
||||
Lora.implicit_header = root.getUInt(PSTR(D_JSON_IMPLICIT_HEADER), Lora.implicit_header);
|
||||
Lora.crc_bytes = root.getUInt(PSTR(D_JSON_CRC_BYTES), Lora.crc_bytes);
|
||||
if (XdrvMailbox.payload == 1) {
|
||||
LoraDefaults();
|
||||
Lora.Config();
|
||||
} else {
|
||||
JsonParser parser(XdrvMailbox.data);
|
||||
JsonParserObject root = parser.getRootObject();
|
||||
if (root) {
|
||||
Lora.frequency = root.getFloat(PSTR(D_JSON_FREQUENCY), Lora.frequency);
|
||||
Lora.bandwidth = root.getFloat(PSTR(D_JSON_BANDWIDTH), Lora.bandwidth);
|
||||
Lora.spreading_factor = root.getUInt(PSTR(D_JSON_SPREADING_FACTOR), Lora.spreading_factor);
|
||||
Lora.coding_rate = root.getUInt(PSTR(D_JSON_CODINGRATE4), Lora.coding_rate);
|
||||
Lora.sync_word = root.getUInt(PSTR(D_JSON_SYNCWORD), Lora.sync_word);
|
||||
Lora.output_power = root.getUInt(PSTR(D_JSON_OUTPUT_POWER), Lora.output_power);
|
||||
Lora.preamble_length = root.getUInt(PSTR(D_JSON_PREAMBLE_LENGTH), Lora.preamble_length);
|
||||
Lora.current_limit = root.getFloat(PSTR(D_JSON_CURRENT_LIMIT), Lora.current_limit);
|
||||
Lora.implicit_header = root.getUInt(PSTR(D_JSON_IMPLICIT_HEADER), Lora.implicit_header);
|
||||
Lora.crc_bytes = root.getUInt(PSTR(D_JSON_CRC_BYTES), Lora.crc_bytes);
|
||||
Lora.Config();
|
||||
}
|
||||
}
|
||||
}
|
||||
ResponseCmnd(); // {"LoRaConfig":
|
||||
|
|
Loading…
Reference in New Issue