Adding docker + shared lora settings

This commit is contained in:
Simon Milvert 2026-06-11 07:18:26 +00:00
parent dab36592a6
commit 7bf2947076
13 changed files with 99 additions and 51 deletions

18
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,18 @@
FROM python:3.14.5-slim-bookworm
ENV PLATFORMIO_CORE_DIR=/workspace/.platformio
ENV PATH="/root/.platformio/penv/bin:${PATH}"
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
build-essential \
ca-certificates \
udev \
&& rm -rf /var/lib/apt/lists/*
RUN python -m pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir platformio
WORKDIR /workspace
CMD ["pio", "run"]

View File

@ -0,0 +1,14 @@
{
"name": "Water Temp Dev Container",
"build": {
"dockerfile": "./Dockerfile"
},
"customizations": {
"vscode": {
"settings": {},
"extensions": [
"platformio.platformio-ide"
]
}
}
}

View File

@ -0,0 +1,20 @@
#ifndef LORA_CONFIG_H
#define LORA_CONFIG_H
struct LoraConfig {
float frequency;
int spreadingFactor;
float signalBandwidth;
int codingRate4;
int power;
};
namespace LoraDefaults {
constexpr float frequency = 433.775f;
constexpr int spreadingFactor = 12;
constexpr float signalBandwidth = 125.0f;
constexpr int codingRate4 = 5;
constexpr int power = 20;
}
#endif /* LORA_CONFIG_H */

View File

@ -15,6 +15,7 @@ framework = arduino
monitor_speed = 115200
build_flags =
-D DEBUG
-I../common/include
-D MOCK_LORA
-D MQTT_MAX_PACKET_SIZE=1024
lib_deps =

View File

@ -35,9 +35,9 @@ void Config::readFile(fs::FS &fs, const char *fileName)
mqtt.id = data["mqtt"]["id"].as<String>();
LoraConfig lora;
lora.frequency = data["lora"]["frequency"].as<long>();
lora.frequency = data["lora"]["frequency"].as<float>();
lora.spreadingFactor = data["lora"]["spreadingFactor"].as<int>();
lora.signalBandwidth = data["lora"]["signalBandwidth"].as<long>();
lora.signalBandwidth = data["lora"]["signalBandwidth"].as<float>();
lora.codingRate4 = data["lora"]["codingRate4"].as<int>();
lora.power = data["lora"]["power"].as<int>();
logConfigInfo(data);
@ -63,11 +63,11 @@ void Config::writeData()
mqttJson["topic"] = this->mqttConfig.topic;
JsonObject lora = doc["lora"].to<JsonObject>();
lora["frequency"] = 433775000;
lora["spreadingFactor"] = 12;
lora["signalBandwidth"] = 125000;
lora["codingRate4"] = 5;
lora["power"] = 20;
lora["frequency"] = LoraDefaults::frequency;
lora["spreadingFactor"] = LoraDefaults::spreadingFactor;
lora["signalBandwidth"] = LoraDefaults::signalBandwidth;
lora["codingRate4"] = LoraDefaults::codingRate4;
lora["power"] = LoraDefaults::power;
// Delete existing file, otherwise the configuration is appended to the file
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "CONFIG", "Write DATA to file");
@ -118,6 +118,8 @@ void Config::logConfigInfo(JsonDocument& doc) {
value = String(jsonValue.as<int>());
} else if (jsonValue.is<long>()) {
value = String(jsonValue.as<long>());
} else if (jsonValue.is<float>()) {
value = String(jsonValue.as<float>(), 3);
} else if (jsonValue.is<bool>()) {
value = jsonValue.as<bool>() ? "true" : "false";
} else if (jsonValue.is<JsonArray>() || jsonValue.is<JsonObject>()) {

View File

@ -4,6 +4,7 @@
#include <Arduino.h>
#include <FS.h>
#include <ArduinoJson.h>
#include "lora_config.hpp"
class MqttConfig {
public:
@ -17,14 +18,6 @@ class MqttConfig {
void setMqtt(const String& server, const int& port, const String& username, const String& password, const String& topic);
};
class LoraConfig {
public:
long frequency;
int spreadingFactor;
long signalBandwidth;
int codingRate4;
int power;
};
class Config {
public:

View File

@ -39,7 +39,8 @@ void LoraHandler::setup()
}
// Configure LoRa parameters
long freq = config.loraConfig.frequency;
const float freq = config.loraConfig.frequency;
const float bandwidth = config.loraConfig.signalBandwidth;
state = radio->setFrequency(freq);
if (state != RADIOLIB_ERR_NONE)
{
@ -52,7 +53,7 @@ void LoraHandler::setup()
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setSpreadingFactor failed: %i", state);
}
state = radio->setBandwidth(config.loraConfig.signalBandwidth);
state = radio->setBandwidth(bandwidth);
if (state != RADIOLIB_ERR_NONE)
{
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setBandwidth failed: %i", state);
@ -74,7 +75,7 @@ void LoraHandler::setup()
radio->setCRC(true);
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "SX1278 initialized successfully!");
String currentLoRainfo = "LoRa Freq: " + String(freq) + " / SF:" + String(config.loraConfig.spreadingFactor) + " / CR: " + String(config.loraConfig.codingRate4);
String currentLoRainfo = "LoRa Freq: " + String(freq, 3) + " MHz / BW: " + String(bandwidth, 1) + " kHz / SF:" + String(config.loraConfig.spreadingFactor) + " / CR: " + String(config.loraConfig.codingRate4);
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", currentLoRainfo.c_str());
}
ReceivedLoRaPacket LoraHandler::receivePacket()

View File

@ -15,6 +15,7 @@ framework = arduino
monitor_speed = 115200
build_flags =
-D DEBUG
-I../common/include
lib_deps =
zinggjm/GxEPD2@^1.5.6
bblanchon/ArduinoJson@^7.0.4

View File

@ -28,9 +28,9 @@ void Config::readFile(fs::FS &fs, const char *fileName)
}
LoraConfig lora;
lora.frequency = data["lora"]["frequency"].as<long>();
lora.frequency = data["lora"]["frequency"].as<float>();
lora.spreadingFactor = data["lora"]["spreadingFactor"].as<int>();
lora.signalBandwidth = data["lora"]["signalBandwidth"].as<long>();
lora.signalBandwidth = data["lora"]["signalBandwidth"].as<float>();
lora.codingRate4 = data["lora"]["codingRate4"].as<int>();
lora.power = data["lora"]["power"].as<int>();
logConfigInfo(data);
@ -47,11 +47,11 @@ void Config::writeData()
JsonDocument doc;
JsonObject lora = doc["lora"].to<JsonObject>();
lora["frequency"] = 433775000;
lora["spreadingFactor"] = 12;
lora["signalBandwidth"] = 125000;
lora["codingRate4"] = 5;
lora["power"] = 20;
lora["frequency"] = LoraDefaults::frequency;
lora["spreadingFactor"] = LoraDefaults::spreadingFactor;
lora["signalBandwidth"] = LoraDefaults::signalBandwidth;
lora["codingRate4"] = LoraDefaults::codingRate4;
lora["power"] = LoraDefaults::power;
// Delete existing file, otherwise the configuration is appended to the file
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "CONFIG", "Write DATA to file");
@ -95,6 +95,8 @@ void Config::logConfigInfo(JsonDocument& doc) {
value = String(jsonValue.as<int>());
} else if (jsonValue.is<long>()) {
value = String(jsonValue.as<long>());
} else if (jsonValue.is<float>()) {
value = String(jsonValue.as<float>(), 3);
} else if (jsonValue.is<bool>()) {
value = jsonValue.as<bool>() ? "true" : "false";
} else if (jsonValue.is<JsonArray>() || jsonValue.is<JsonObject>()) {

View File

@ -4,16 +4,9 @@
#include <Arduino.h>
#include <FS.h>
#include <ArduinoJson.h>
#include "lora_config.hpp"
class LoraConfig {
public:
long frequency;
int spreadingFactor;
long signalBandwidth;
int codingRate4;
int power;
};
class Config {
public:

View File

@ -6,9 +6,7 @@
extern logging::Logger logger;
extern Config config;
LoraHandler::LoraHandler() {
// Initialize with new SX1268 radio
}
LoraHandler::LoraHandler() : radio(nullptr), spi(nullptr) {}
void LoraHandler::setup()
{
@ -19,7 +17,7 @@ void LoraHandler::setup()
spi->begin(RADIO_SCK, RADIO_MISO, RADIO_MOSI, RADIO_CS);
// Create SX1268 instance
radio = new SX1268(new SPIDriver(spi, RADIO_CS));
radio = new SX1268(new Module(RADIO_CS, RADIO_IRQ, RADIO_RST, RADIOLIB_NC, *spi));
// Configure RXEN/TXEN pins
pinMode(RADIO_RXEN, OUTPUT);
@ -27,6 +25,9 @@ void LoraHandler::setup()
digitalWrite(RADIO_RXEN, LOW);
digitalWrite(RADIO_TXEN, LOW);
const float freq = config.loraConfig.frequency;
const float bandwidth = config.loraConfig.signalBandwidth;
// Initialize LoRa module
int state = radio->begin();
if (state != RADIOLIB_ERR_NONE)
@ -38,7 +39,6 @@ void LoraHandler::setup()
}
// Configure LoRa parameters
long freq = config.loraConfig.frequency;
state = radio->setFrequency(freq);
if (state != RADIOLIB_ERR_NONE)
{
@ -51,7 +51,7 @@ void LoraHandler::setup()
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setSpreadingFactor failed: %i", state);
}
state = radio->setBandwidth(config.loraConfig.signalBandwidth);
state = radio->setBandwidth(bandwidth);
if (state != RADIOLIB_ERR_NONE)
{
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setBandwidth failed: %i", state);
@ -69,11 +69,15 @@ void LoraHandler::setup()
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setOutputPower failed: %i", state);
}
// Enable CRC
radio->setCRC(true);
// Enable 2-byte LoRa CRC
state = radio->setCRC(2);
if (state != RADIOLIB_ERR_NONE)
{
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setCRC failed: %i", state);
}
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "SX1268 initialized successfully!");
String currentLoRainfo = "LoRa Freq: " + String(freq) + " / SF:" + String(config.loraConfig.spreadingFactor) + " / CR: " + String(config.loraConfig.codingRate4);
String currentLoRainfo = "LoRa Freq: " + String(freq, 3) + " MHz / BW: " + String(bandwidth, 1) + " kHz / SF:" + String(config.loraConfig.spreadingFactor) + " / CR: " + String(config.loraConfig.codingRate4);
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", currentLoRainfo.c_str());
}
@ -86,7 +90,8 @@ void LoraHandler::sendPacket(const String& data)
digitalWrite(RADIO_RXEN, LOW);
delay(10);
int state = radio->transmit(data);
String payload = data;
int state = radio->transmit(payload);
// Disable TX mode
digitalWrite(RADIO_TXEN, LOW);
@ -109,22 +114,19 @@ ReceivedLoRaPacket LoraHandler::receivePacket()
digitalWrite(RADIO_RXEN, HIGH);
digitalWrite(RADIO_TXEN, LOW);
int state = radio->receive(0); // 0 = non-blocking
int state = radio->receive(receivedLoraPacket.text);
if (state == RADIOLIB_ERR_RX_ONGOING)
if (state == RADIOLIB_ERR_RX_TIMEOUT)
{
// No packet received yet
return receivedLoraPacket;
}
else if (state == RADIOLIB_ERR_NONE)
{
// Packet received!
receivedLoraPacket.text = radio->readData();
receivedLoraPacket.rssi = radio->getRSSI();
receivedLoraPacket.snr = radio->getSNR();
receivedLoraPacket.freqError = radio->getFrequencyError();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Rx", "---> %s (RSSI: %d, SNR: %.1f)",
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Rx", "---> %s (RSSI: %.1f, SNR: %.1f)",
receivedLoraPacket.text.c_str(), receivedLoraPacket.rssi, receivedLoraPacket.snr);
}
else

View File

@ -6,9 +6,9 @@
struct ReceivedLoRaPacket {
String text;
int rssi;
float rssi;
float snr;
int freqError;
float freqError;
};
class LoraHandler {

View File

@ -8,6 +8,7 @@
#include <ArduinoJson.h>
logging::Logger logger;
Config config;
Eink eink;
IO io;
LoraHandler lora;