From c9dad0563122c597a38fae08d69c38a3ae37b900 Mon Sep 17 00:00:00 2001 From: Simon Milvert Date: Mon, 25 May 2026 21:38:02 +0200 Subject: [PATCH] Update to use e22 instead of sx1278 --- sender/platformio.ini | 2 +- sender/src/lorahandler.cpp | 143 +++++++++++++++++++++++++++++-------- sender/src/lorahandler.hpp | 7 +- sender/src/main.cpp | 30 ++++++++ sender/src/pins.hpp | 7 +- sender/src/tpl5110.cpp | 32 +++++++++ sender/src/tpl5110.hpp | 17 +++++ 7 files changed, 203 insertions(+), 35 deletions(-) create mode 100644 sender/src/tpl5110.cpp create mode 100644 sender/src/tpl5110.hpp diff --git a/sender/platformio.ini b/sender/platformio.ini index 0b5c2d2..2a68113 100644 --- a/sender/platformio.ini +++ b/sender/platformio.ini @@ -19,6 +19,6 @@ lib_deps = zinggjm/GxEPD2@^1.5.6 bblanchon/ArduinoJson@^7.0.4 peterus/esp-logger@^1.0.0 - sandeepmistry/LoRa@^0.8.0 + jgromes/RadioLib@^6.0.0 olikraus/U8g2_for_Adafruit_GFX@^1.8.0 milesburton/DallasTemperature@^3.11.0 diff --git a/sender/src/lorahandler.cpp b/sender/src/lorahandler.cpp index 6c8deeb..cd83f7c 100644 --- a/sender/src/lorahandler.cpp +++ b/sender/src/lorahandler.cpp @@ -6,50 +6,131 @@ extern logging::Logger logger; extern Config config; +LoraHandler::LoraHandler() { + // Initialize with new SX1268 radio +} + void LoraHandler::setup() { - - logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "Set SPI pins!"); - SPI.begin(RADIO_SCK, RADIO_MISO, RADIO_MOSI, RADIO_CS); - LoRa.setPins(RADIO_CS, RADIO_RST, RADIO_IRQ); - - long freq = config.loraConfig.frequency; - if (!LoRa.begin(freq)) + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "Initializing SX1268 with RadioLib!"); + + // Create new SPI instance for LoRa + spi = new SPIClass(VSPI); + spi->begin(RADIO_SCK, RADIO_MISO, RADIO_MOSI, RADIO_CS); + + // Create SX1268 instance + radio = new SX1268(new SPIDriver(spi, RADIO_CS)); + + // Configure RXEN/TXEN pins + pinMode(RADIO_RXEN, OUTPUT); + pinMode(RADIO_TXEN, OUTPUT); + digitalWrite(RADIO_RXEN, LOW); + digitalWrite(RADIO_TXEN, LOW); + + // Initialize LoRa module + int state = radio->begin(); + if (state != RADIOLIB_ERR_NONE) { - logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "Starting LoRa failed!"); - // show_display("ERROR", "Starting LoRa failed!"); - while (true) - { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "LoRa init failed: %i", state); + while (true) { delay(1000); } } - LoRa.setSpreadingFactor(config.loraConfig.spreadingFactor); - LoRa.setSignalBandwidth(config.loraConfig.signalBandwidth); - LoRa.setCodingRate4(config.loraConfig.codingRate4); - LoRa.enableCrc(); - LoRa.setTxPower(config.loraConfig.power); - logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", "LoRa init done!"); - String currentLoRainfo = "LoRa Freq: " + String(config.loraConfig.frequency) + " / SF:" + String(config.loraConfig.spreadingFactor) + " / CR: " + String(config.loraConfig.codingRate4); + + // Configure LoRa parameters + long freq = config.loraConfig.frequency; + state = radio->setFrequency(freq); + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setFrequency failed: %i", state); + } + + state = radio->setSpreadingFactor(config.loraConfig.spreadingFactor); + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setSpreadingFactor failed: %i", state); + } + + state = radio->setBandwidth(config.loraConfig.signalBandwidth); + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setBandwidth failed: %i", state); + } + + state = radio->setCodingRate(config.loraConfig.codingRate4); + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setCodingRate failed: %i", state); + } + + state = radio->setOutputPower(config.loraConfig.power); + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa", "setOutputPower failed: %i", state); + } + + // Enable CRC + radio->setCRC(true); + + 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); logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa", currentLoRainfo.c_str()); } +void LoraHandler::sendPacket(const String& data) +{ + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Tx", "Sending: %s", data.c_str()); + + // Enable TX mode + digitalWrite(RADIO_TXEN, HIGH); + digitalWrite(RADIO_RXEN, LOW); + delay(10); + + int state = radio->transmit(data); + + // Disable TX mode + digitalWrite(RADIO_TXEN, LOW); + + if (state != RADIOLIB_ERR_NONE) + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa Tx", "Transmit failed: %i", state); + } + else + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Tx", "Packet sent!"); + } +} + ReceivedLoRaPacket LoraHandler::receivePacket() { ReceivedLoRaPacket receivedLoraPacket; - String packet = ""; - int packetSize = LoRa.parsePacket(); - if (packetSize) + + // Enable RX mode + digitalWrite(RADIO_RXEN, HIGH); + digitalWrite(RADIO_TXEN, LOW); + + int state = radio->receive(0); // 0 = non-blocking + + if (state == RADIOLIB_ERR_RX_ONGOING) { - while (LoRa.available()) - { - int inChar = LoRa.read(); - packet += (char)inChar; - } - receivedLoraPacket.text = packet; - receivedLoraPacket.rssi = LoRa.packetRssi(); - receivedLoraPacket.snr = LoRa.packetSnr(); - receivedLoraPacket.freqError = LoRa.packetFrequencyError(); - logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "LoRa Rx", "---> %s", packet.c_str()); + // 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)", + receivedLoraPacket.text.c_str(), receivedLoraPacket.rssi, receivedLoraPacket.snr); + } + else + { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "LoRa Rx", "Receive error: %i", state); + } + return receivedLoraPacket; } \ No newline at end of file diff --git a/sender/src/lorahandler.hpp b/sender/src/lorahandler.hpp index 2aac8f4..a4ecf98 100644 --- a/sender/src/lorahandler.hpp +++ b/sender/src/lorahandler.hpp @@ -2,8 +2,7 @@ #define LORAHANDLER_H #include "config.hpp" -#include -#include +#include struct ReceivedLoRaPacket { String text; @@ -14,9 +13,13 @@ struct ReceivedLoRaPacket { class LoraHandler { public: + LoraHandler(); void setup(); + void sendPacket(const String& data); ReceivedLoRaPacket receivePacket(); private: + SX1268* radio; + SPIClass* spi; }; #endif /* LORAHANDLER_H */ \ No newline at end of file diff --git a/sender/src/main.cpp b/sender/src/main.cpp index 12499e6..787d838 100644 --- a/sender/src/main.cpp +++ b/sender/src/main.cpp @@ -2,10 +2,16 @@ #include "config.hpp" #include "eink.hpp" #include "io.hpp" +#include "lorahandler.hpp" +#include "tpl5110.hpp" +#include "pins.hpp" +#include logging::Logger logger; Eink eink; IO io; +LoraHandler lora; +TPL5110 tpl5110(TPL5110_DONE); RTC_DATA_ATTR int bootCount = 0; RTC_DATA_ATTR int updateCount = 0; @@ -22,6 +28,8 @@ void setup() #ifndef DEBUG logger.setDebugLevel(logging::LoggerLevel::LOGGER_LEVEL_INFO); #endif + + tpl5110.setup(); // Initialize TPL5110 timer io.setup_io(); io.set_low_power(); @@ -57,7 +65,29 @@ void setup() eink.show_count(180 - 24 - 4 - 100 - 60, 12, (float)bootCount, "c: "); eink.show_count(180 - 24 - 4 - 100 - 60 - 50, 12, (float)bootCount, "u: "); eink.display(true); + + // Initialize LoRa and send data + lora.setup(); + + // Create JSON payload + JsonDocument doc; + doc["temp"] = temp; + doc["battery"] = battery; + doc["boot"] = bootCount; + doc["update"] = updateCount; + + String payload; + serializeJson(doc, payload); + + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "MAIN", "Sending LoRa payload: %s", payload.c_str()); + lora.sendPacket(payload); + + delay(1000); // Give time for transmission } + + // Signal TPL5110 that work is done - device will sleep + tpl5110.signalDone(); + delay(100); io.set_deep_sleep(); } diff --git a/sender/src/pins.hpp b/sender/src/pins.hpp index 5fd32ce..65b0bfc 100644 --- a/sender/src/pins.hpp +++ b/sender/src/pins.hpp @@ -11,13 +11,18 @@ const int EPD_RSET = 16; const int EPD_DC = 17; const int EPD_CS = 5; -// Pin assignments for LORA module +// Pin assignments for LORA module (SX1268 E22-400M22S) const int RADIO_SCK = 5; const int RADIO_MISO = 19; const int RADIO_MOSI = 27; const int RADIO_CS = 18; // CS --> NSS const int RADIO_RST = 14; const int RADIO_IRQ = 26; // IRQ --> DIO0 +const int RADIO_RXEN = 2; // RX Enable +const int RADIO_TXEN = 13; // TX Enable + +// TPL5110 timer module +const int TPL5110_DONE = 15; // DONE signal // Battery pin const int ADC_BATTERY = 35; //builtin = 35 diff --git a/sender/src/tpl5110.cpp b/sender/src/tpl5110.cpp new file mode 100644 index 0000000..ca86615 --- /dev/null +++ b/sender/src/tpl5110.cpp @@ -0,0 +1,32 @@ +#include "tpl5110.hpp" +#include "logger.h" + +extern logging::Logger logger; + +TPL5110::TPL5110(int donePin) : _donePin(donePin) { +} + +void TPL5110::setup() { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "Initializing TPL5110 timer!"); + pinMode(_donePin, OUTPUT); + digitalWrite(_donePin, LOW); // DONE pin starts LOW + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "TPL5110 initialized!"); +} + +void TPL5110::signalDone() { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "Signaling DONE to TPL5110!"); + digitalWrite(_donePin, HIGH); + delay(100); // Hold HIGH for 100ms + digitalWrite(_donePin, LOW); + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "DONE signal sent - device will sleep now"); +} + +void TPL5110::setActive() { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "TPL5110 set to ACTIVE"); + digitalWrite(_donePin, LOW); +} + +void TPL5110::setInactive() { + logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "TPL5110", "TPL5110 set to INACTIVE"); + digitalWrite(_donePin, HIGH); +} diff --git a/sender/src/tpl5110.hpp b/sender/src/tpl5110.hpp new file mode 100644 index 0000000..f847705 --- /dev/null +++ b/sender/src/tpl5110.hpp @@ -0,0 +1,17 @@ +#ifndef TPL5110_H +#define TPL5110_H + +#include + +class TPL5110 { + public: + TPL5110(int donePin); + void setup(); + void signalDone(); + void setActive(); + void setInactive(); + private: + int _donePin; +}; + +#endif /* TPL5110_H */