refacto: change lora to class with ITransmitter interface

This commit is contained in:
Alexis Fourmaux 2026-05-06 17:25:17 +02:00
parent 2d87381903
commit 244d1eea21
7 changed files with 225 additions and 179 deletions

View file

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
class ITransmitter {
public:
virtual ~ITransmitter() = default;
virtual void init() = 0;
virtual void join() = 0;
virtual void send(uint8_t* payload, size_t size) = 0;
};

View file

@ -0,0 +1,147 @@
#include <LoRaTransmitter.h>
RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE];
LoRaTransmitter::LoRaTransmitter(
uint64_t joinEUI,
uint64_t devEUI,
uint8_t* nwkKey,
uint8_t* appKey
)
: _joinEUI(joinEUI),
_devEUI(devEUI),
_radio(new Module(LORA_NSS, LORA_DIO0, LORA_RST, LORA_DIO1)),
_node(&_radio, &EU868)
{
memcpy(_nwkKey, nwkKey, 16);
memcpy(_appKey, appKey, 16);
memset(_noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
}
void LoRaTransmitter::init()
{
_reset();
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_NSS);
Serial.print("[LoRaWAN] Init... ");
int state = _radio.begin();
if (state != RADIOLIB_ERR_NONE)
{
Serial.printf("ERREUR %d\n", state);
while (true)
{
delay(1000);
}
}
Serial.println("OK");
}
void LoRaTransmitter::join()
{
int16_t state = RADIOLIB_ERR_NETWORK_NOT_JOINED;
_node.beginOTAA(_joinEUI, _devEUI, _nwkKey, _appKey);
_restoreDevNonce();
if (_restoreSession() != RADIOLIB_LORAWAN_SESSION_RESTORED)
{
Serial.print("[LoRaWAN] Join complet...");
int16_t state = _fullJoin();
if (state != RADIOLIB_LORAWAN_NEW_SESSION)
{
Serial.printf("Echec : %d\n", state);
while (true)
{
delay(1000);
}
}
}
Serial.println("OK");
_saveSession();
}
void LoRaTransmitter::send(uint8_t payload[], size_t size)
{
int state = _node.sendReceive(payload, size, 1);
if (state == RADIOLIB_ERR_NONE || state == RADIOLIB_LORAWAN_NO_DOWNLINK)
{
Serial.println("[TX] OK");
}
else
{
Serial.printf("[TX] Erreur : %d\n", state);
}
_saveSession();
}
void LoRaTransmitter::_reset()
{
pinMode(LORA_RST, OUTPUT);
digitalWrite(LORA_RST, LOW);
delay(10);
digitalWrite(LORA_RST, HIGH);
delay(10);
}
void LoRaTransmitter::_restoreDevNonce()
{
_prefs.begin("lorawan");
if (_prefs.isKey("nonces"))
{
_prefs.getBytes("nonces", _noncesBuffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
}
else
{
Serial.println("[NVS] Aucune donnée trouvée, buffer initialisé à zéro");
memset(_noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
}
_prefs.end();
_node.setBufferNonces(_noncesBuffer);
}
void LoRaTransmitter::_persistDevNonce()
{
_prefs.begin("lorawan");
uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];
uint8_t *persist = _node.getBufferNonces();
memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
size_t result = _prefs.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
_prefs.end();
}
int16_t LoRaTransmitter::_restoreSession()
{
Serial.print("[LoRaWAN] Tentative de restaurer la session...");
int16_t state = _node.setBufferSession(LWsession);
if (state == RADIOLIB_ERR_NONE)
{
state = _node.activateOTAA();
}
else {
Serial.println("Echec");
}
return state;
}
void LoRaTransmitter::_saveSession()
{
uint8_t *session = _node.getBufferSession();
memcpy(LWsession, session, RADIOLIB_LORAWAN_SESSION_BUF_SIZE);
Serial.println("[RTC] Session sauvegardée");
}
int16_t LoRaTransmitter::_fullJoin()
{
_node.beginOTAA(_joinEUI, _devEUI, _nwkKey, _appKey);
_restoreDevNonce();
int16_t state = _node.activateOTAA();
_persistDevNonce();
return state;
}

View file

@ -0,0 +1,47 @@
#pragma once
#include <ITransmitter.h>
#include <SPI.h>
#include <RadioLib.h>
#include <Preferences.h>
#include <config.h>
#define LORA_SCK 5
#define LORA_MISO 19
#define LORA_MOSI 27
#define LORA_NSS 18
#define LORA_RST 23
#define LORA_DIO0 26
#define LORA_DIO1 33
class LoRaTransmitter : public ITransmitter {
public:
LoRaTransmitter(
uint64_t joinEUI,
uint64_t devEUI,
uint8_t* nwkKey,
uint8_t* appKey
);
void init() override;
void join() override;
void send(uint8_t* payload, size_t size) override;
private:
uint64_t _joinEUI;
uint64_t _devEUI;
uint8_t _nwkKey[16];
uint8_t _appKey[16];
SX1276 _radio;
LoRaWANNode _node;
Preferences _prefs;
uint8_t _noncesBuffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];
void _reset();
void _restoreDevNonce();
void _persistDevNonce();
int16_t _restoreSession();
void _saveSession();
int16_t _fullJoin();
};

View file

@ -1,22 +1,8 @@
#ifndef CONFIG_H #pragma once
#define CONFIG_H
#include <Arduino.h>
#define LORA_SCK 5
#define LORA_MISO 19
#define LORA_MOSI 27
#define LORA_NSS 18
#define LORA_RST 23
#define LORA_DIO0 26
#define LORA_DIO1 33
uint64_t joinEUI = 0x35f48318e1324e2e; uint64_t joinEUI = 0x35f48318e1324e2e;
uint64_t devEUI = 0x0586fe41112d83d9; uint64_t devEUI = 0x0586fe41112d83d9;
uint8_t appKey[] = { uint8_t appKey[] = {
0x0b, 0x84, 0xb4, 0x04, 0x0f, 0xd5, 0x56, 0x1b, 0x0b, 0x84, 0xb4, 0x04, 0x0f, 0xd5, 0x56, 0x1b,
0x00, 0x53, 0x94, 0x22, 0xc1, 0xf1, 0x4f, 0xd6 0x00, 0x53, 0x94, 0x22, 0xc1, 0xf1, 0x4f, 0xd6};
};
uint8_t *nwkKey = appKey; uint8_t *nwkKey = appKey;
#endif

View file

@ -1,140 +0,0 @@
#include <config.h>
#include <SPI.h>
#include <RadioLib.h>
#include <Preferences.h>
Preferences prefs;
SX1276 radio = new Module(LORA_NSS, LORA_DIO0, LORA_RST, LORA_DIO1);
LoRaWANNode node(&radio, &EU868);
uint8_t noncesBuffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];
RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE];
void loraReset()
{
pinMode(LORA_RST, OUTPUT);
digitalWrite(LORA_RST, LOW);
delay(10);
digitalWrite(LORA_RST, HIGH);
delay(10);
}
void loraInit()
{
loraReset();
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_NSS);
Serial.print("[LoRaWAN] Init... ");
int state = radio.begin();
if (state != RADIOLIB_ERR_NONE)
{
Serial.printf("ERREUR %d\n", state);
while (true)
{
delay(1000);
}
}
Serial.println("OK");
}
void loraRestoreDevNonce()
{
prefs.begin("lorawan");
if (prefs.isKey("nonces"))
{
prefs.getBytes("nonces", noncesBuffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
}
else
{
Serial.println("[NVS] Aucune donnée trouvée, buffer initialisé à zéro");
memset(noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
}
prefs.end();
node.setBufferNonces(noncesBuffer);
}
void loraPersistDevNonce()
{
prefs.begin("lorawan");
uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];
uint8_t *persist = node.getBufferNonces();
memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
size_t result = prefs.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
prefs.end();
}
int16_t loraRestoreSession()
{
Serial.print("[LoRaWAN] Tentative de restaurer la session...");
int16_t state = node.setBufferSession(LWsession);
if (state == RADIOLIB_ERR_NONE)
{
state = node.activateOTAA();
}
else {
Serial.println("Echec");
}
return state;
}
void loraSaveSession()
{
uint8_t *session = node.getBufferSession();
memcpy(LWsession, session, RADIOLIB_LORAWAN_SESSION_BUF_SIZE);
Serial.println("[RTC] Session sauvegardée");
}
int16_t loraFullJoin()
{
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
loraRestoreDevNonce();
int16_t state = node.activateOTAA();
loraPersistDevNonce();
return state;
}
void loraJoin()
{
int16_t state = RADIOLIB_ERR_NETWORK_NOT_JOINED;
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
loraRestoreDevNonce();
if (loraRestoreSession() != RADIOLIB_LORAWAN_SESSION_RESTORED)
{
Serial.print("[LoRaWAN] Join complet...");
int16_t state = loraFullJoin();
if (state != RADIOLIB_LORAWAN_NEW_SESSION)
{
Serial.printf("Echec : %d\n", state);
while (true)
{
delay(1000);
}
}
}
Serial.println("OK");
loraSaveSession();
}
void loraSend(uint8_t payload[], size_t size)
{
int state = node.sendReceive(payload, size, 1);
if (state == RADIOLIB_ERR_NONE || state == RADIOLIB_LORAWAN_NO_DOWNLINK)
{
Serial.println("[TX] OK");
}
else
{
Serial.printf("[TX] Erreur : %d\n", state);
}
loraSaveSession();
}

View file

@ -1,15 +0,0 @@
#ifndef LORA_H
#define LORA_H
#include <Arduino.h>
void loraReset();
void loraInit();
void loraJoin();
void loraSend(uint8_t payload[], size_t size);
void loraPersistDevNonce();
void loraSaveDevNonce();
void loraRestoreSession();
void loraSaveSession();
#endif

View file

@ -1,16 +1,26 @@
#include <lora.h> #include <Arduino.h>
#include "LoRaTransmitter.h"
#include "config.h"
ITransmitter* transmitter = new LoRaTransmitter(
joinEUI,
devEUI,
nwkKey,
appKey
);
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
delay(2000); delay(2000);
loraInit(); transmitter->init();
transmitter->join();
} }
void loop() { void loop() {
loraJoin();
uint8_t payload[] = { 0x01, 0x02, 0x03 }; uint8_t payload[] = { 0x01, 0x02, 0x03 };
loraSend(payload, sizeof(payload)); transmitter->send(payload, sizeof(payload));
Serial.flush(); Serial.flush();
esp_deep_sleep(60000000); esp_deep_sleep(60000000);
} }