From 7bf294707673aed7cfaf20a9c983e3029e91aa03 Mon Sep 17 00:00:00 2001 From: Simon Milvert Date: Thu, 11 Jun 2026 07:18:26 +0000 Subject: [PATCH] Adding docker + shared lora settings --- .devcontainer/Dockerfile | 18 +++++++++++++++++ .devcontainer/devcontainer.json | 14 ++++++++++++++ common/include/lora_config.hpp | 20 +++++++++++++++++++ reciver/platformio.ini | 1 + reciver/src/config.cpp | 16 +++++++++------- reciver/src/config.hpp | 9 +-------- reciver/src/lorahandler.cpp | 7 ++++--- sender/platformio.ini | 1 + sender/src/config.cpp | 16 +++++++++------- sender/src/config.hpp | 9 +-------- sender/src/lorahandler.cpp | 34 +++++++++++++++++---------------- sender/src/lorahandler.hpp | 4 ++-- sender/src/main.cpp | 1 + 13 files changed, 99 insertions(+), 51 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 common/include/lora_config.hpp diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..8e70fab --- /dev/null +++ b/.devcontainer/Dockerfile @@ -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"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..bfea7fb --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "Water Temp Dev Container", + "build": { + "dockerfile": "./Dockerfile" + }, + "customizations": { + "vscode": { + "settings": {}, + "extensions": [ + "platformio.platformio-ide" + ] + } + } +} \ No newline at end of file diff --git a/common/include/lora_config.hpp b/common/include/lora_config.hpp new file mode 100644 index 0000000..1024003 --- /dev/null +++ b/common/include/lora_config.hpp @@ -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 */ diff --git a/reciver/platformio.ini b/reciver/platformio.ini index 3bbb2cb..8726f0a 100644 --- a/reciver/platformio.ini +++ b/reciver/platformio.ini @@ -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 = diff --git a/reciver/src/config.cpp b/reciver/src/config.cpp index 7bc2e2b..d1a14eb 100644 --- a/reciver/src/config.cpp +++ b/reciver/src/config.cpp @@ -35,9 +35,9 @@ void Config::readFile(fs::FS &fs, const char *fileName) mqtt.id = data["mqtt"]["id"].as(); LoraConfig lora; - lora.frequency = data["lora"]["frequency"].as(); + lora.frequency = data["lora"]["frequency"].as(); lora.spreadingFactor = data["lora"]["spreadingFactor"].as(); - lora.signalBandwidth = data["lora"]["signalBandwidth"].as(); + lora.signalBandwidth = data["lora"]["signalBandwidth"].as(); lora.codingRate4 = data["lora"]["codingRate4"].as(); lora.power = data["lora"]["power"].as(); logConfigInfo(data); @@ -63,11 +63,11 @@ void Config::writeData() mqttJson["topic"] = this->mqttConfig.topic; JsonObject lora = doc["lora"].to(); - 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()); } else if (jsonValue.is()) { value = String(jsonValue.as()); + } else if (jsonValue.is()) { + value = String(jsonValue.as(), 3); } else if (jsonValue.is()) { value = jsonValue.as() ? "true" : "false"; } else if (jsonValue.is() || jsonValue.is()) { diff --git a/reciver/src/config.hpp b/reciver/src/config.hpp index 232223a..82a916c 100644 --- a/reciver/src/config.hpp +++ b/reciver/src/config.hpp @@ -4,6 +4,7 @@ #include #include #include +#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: diff --git a/reciver/src/lorahandler.cpp b/reciver/src/lorahandler.cpp index dcd5ccf..7f3f55e 100644 --- a/reciver/src/lorahandler.cpp +++ b/reciver/src/lorahandler.cpp @@ -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() diff --git a/sender/platformio.ini b/sender/platformio.ini index 2a68113..99f57f2 100644 --- a/sender/platformio.ini +++ b/sender/platformio.ini @@ -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 diff --git a/sender/src/config.cpp b/sender/src/config.cpp index 4d96cb2..59ecf71 100644 --- a/sender/src/config.cpp +++ b/sender/src/config.cpp @@ -28,9 +28,9 @@ void Config::readFile(fs::FS &fs, const char *fileName) } LoraConfig lora; - lora.frequency = data["lora"]["frequency"].as(); + lora.frequency = data["lora"]["frequency"].as(); lora.spreadingFactor = data["lora"]["spreadingFactor"].as(); - lora.signalBandwidth = data["lora"]["signalBandwidth"].as(); + lora.signalBandwidth = data["lora"]["signalBandwidth"].as(); lora.codingRate4 = data["lora"]["codingRate4"].as(); lora.power = data["lora"]["power"].as(); logConfigInfo(data); @@ -47,11 +47,11 @@ void Config::writeData() JsonDocument doc; JsonObject lora = doc["lora"].to(); - 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()); } else if (jsonValue.is()) { value = String(jsonValue.as()); + } else if (jsonValue.is()) { + value = String(jsonValue.as(), 3); } else if (jsonValue.is()) { value = jsonValue.as() ? "true" : "false"; } else if (jsonValue.is() || jsonValue.is()) { diff --git a/sender/src/config.hpp b/sender/src/config.hpp index 67fd770..87db9cb 100644 --- a/sender/src/config.hpp +++ b/sender/src/config.hpp @@ -4,16 +4,9 @@ #include #include #include +#include "lora_config.hpp" -class LoraConfig { -public: - long frequency; - int spreadingFactor; - long signalBandwidth; - int codingRate4; - int power; -}; class Config { public: diff --git a/sender/src/lorahandler.cpp b/sender/src/lorahandler.cpp index cd83f7c..243a7ca 100644 --- a/sender/src/lorahandler.cpp +++ b/sender/src/lorahandler.cpp @@ -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 diff --git a/sender/src/lorahandler.hpp b/sender/src/lorahandler.hpp index a4ecf98..f3c6c7a 100644 --- a/sender/src/lorahandler.hpp +++ b/sender/src/lorahandler.hpp @@ -6,9 +6,9 @@ struct ReceivedLoRaPacket { String text; - int rssi; + float rssi; float snr; - int freqError; + float freqError; }; class LoraHandler { diff --git a/sender/src/main.cpp b/sender/src/main.cpp index 787d838..c459794 100644 --- a/sender/src/main.cpp +++ b/sender/src/main.cpp @@ -8,6 +8,7 @@ #include logging::Logger logger; +Config config; Eink eink; IO io; LoraHandler lora;