Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Commit 16c4af5

Browse files
committed
refactor: add state machine for Class A, C in LoRaWANClass::update
1 parent 668d630 commit 16c4af5

File tree

2 files changed

+165
-55
lines changed

2 files changed

+165
-55
lines changed

src/arduino-rfm/lorawan-arduino-rfm.cpp

Lines changed: 146 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ bool LoRaWANClass::init(void)
171171
{
172172
return 0;
173173
}
174+
175+
lora_state = LORA_STATE_IDLE;
176+
rx1_timeout = 0;
177+
rx2_timeout = 0;
178+
rx1_channel = 0;
179+
rx1_datarate = 0;
180+
174181
return 1;
175182
}
176183

@@ -458,65 +465,149 @@ bool LoRaWANClass::readAck(void)
458465
return false;
459466
}
460467

461-
void LoRaWANClass::update(void)
462-
{
463-
//Type A mote transmit receive cycle
464-
if ((RFM_Command_Status == NEW_RFM_COMMAND || RFM_Command_Status == JOIN) && LoRa_Settings.Mote_Class == CLASS_A)
465-
{
466-
//LoRaWAN TX/RX cycle
467-
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
468-
469-
if ((Message_Rx.Frame_Control & 0x20) > 0){ // ack get only in RX1 window
470-
Ack_Status = NEW_ACK;
471-
}
472-
473-
if (Buffer_Rx.Counter != 0x00)
474-
{
475-
Rx_Status = NEW_RX;
476-
}
477-
478-
RFM_Command_Status = NO_RFM_COMMAND;
479-
480-
}
481-
482-
//Type C mote transmit and receive handling
483-
if (LoRa_Settings.Mote_Class == CLASS_C)
484-
{
485-
//Transmit -> this will be never used in Class C since device start as class A all the time.
486-
// in Class C mode we will only listen upcoming messages
487-
if (RFM_Command_Status == NEW_RFM_COMMAND)
488-
{
489-
//LoRaWAN TX/RX cycle
490-
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
491-
if (Buffer_Rx.Counter != 0x00)
492-
{
493-
Rx_Status = NEW_RX;
468+
void LoRaWANClass::update(void) {
469+
switch (lora_state) {
470+
case LORA_STATE_IDLE:
471+
// Verificar si hay un comando pendiente (transmisión o unión)
472+
if (RFM_Command_Status == NEW_RFM_COMMAND || RFM_Command_Status == JOIN) {
473+
lora_state = LORA_STATE_TX;
494474
}
495-
RFM_Command_Status = NO_RFM_COMMAND;
496-
}
497-
498-
//Receive in Class C mode
499-
bool isRxDone;
500-
if (RFM_pins.DIO0 != -1)
501-
{
502-
isRxDone = digitalRead(RFM_pins.DIO0) == HIGH;
503-
}
504-
else
505-
{
506-
isRxDone = RFM_isRxDone();
507-
}
508-
if (isRxDone)
509-
{
510-
LORA_Receive_Data(&Buffer_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
511-
if (Buffer_Rx.Counter != 0x00)
512-
{
513-
Rx_Status = NEW_RX;
475+
// Para clase C, mantener recepción continua
476+
if (LoRa_Settings.Mote_Class == CLASS_C && digitalRead(RFM_pins.DIO0)) {
477+
LORA_Receive_Data(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
478+
if (Data_Rx.Counter > 0) {
479+
Rx_Status = NEW_RX;
480+
if (Message_Rx.Frame_Control & 0x20) {
481+
Ack_Status = NEW_ACK;
482+
}
483+
}
484+
// Reanudar recepción continua
485+
RFM_Continuous_Receive(&LoRa_Settings);
514486
}
515-
}
487+
break;
488+
489+
case LORA_STATE_TX:
490+
// Procesar comando de unión (OTAA) o transmisión de datos
491+
if (RFM_Command_Status == JOIN) {
492+
LoRa_Send_JoinReq(&OTAA_Data, &LoRa_Settings);
493+
} else {
494+
LORA_Send_Data(&Data_Tx, &Session_Data, &LoRa_Settings);
495+
}
496+
RFM_Command_Status = NO_RFM_COMMAND;
516497

517-
RFM_Command_Status = NO_RFM_COMMAND;
518-
}
498+
// Guardar configuración de RX1
499+
rx1_channel = LoRa_Settings.Channel_Rx;
500+
rx1_datarate = LoRa_Settings.Datarate_Rx;
501+
502+
if (LoRa_Settings.Mote_Class == CLASS_A) {
503+
// Iniciar espera para RX1
504+
rx1_timeout = millis() + 1000; // Receive_Delay_1
505+
lora_state = LORA_STATE_WAIT_RX1;
506+
} else {
507+
// Clase C: Configurar RX2 e ir a recepción continua
508+
#ifdef US_915
509+
LoRa_Settings.Channel_Rx = 0x08; // 923.3 MHz
510+
LoRa_Settings.Datarate_Rx = SF12BW500;
511+
#elif defined(EU_868)
512+
LoRa_Settings.Channel_Rx = CHRX2; // 869.525 MHz
513+
LoRa_Settings.Datarate_Rx = SF12BW125;
514+
#elif defined(AS_923) || defined(AS_923_2)
515+
LoRa_Settings.Channel_Rx = 0x00; // 923.2 o 921.4 MHz
516+
LoRa_Settings.Datarate_Rx = SF10BW125;
517+
#endif
518+
RFM_Continuous_Receive(&LoRa_Settings);
519+
lora_state = LORA_STATE_RX_CONT;
520+
}
521+
break;
522+
523+
case LORA_STATE_WAIT_RX1:
524+
// Esperar hasta que llegue el tiempo de RX1
525+
if (millis() >= rx1_timeout) {
526+
lora_state = LORA_STATE_RX1;
527+
LoRa_Settings.Channel_Rx = rx1_channel;
528+
LoRa_Settings.Datarate_Rx = rx1_datarate;
529+
RFM_Single_Receive(&LoRa_Settings);
530+
}
531+
break;
532+
533+
case LORA_STATE_RX1:
534+
// Verificar si hay datos recibidos
535+
if (digitalRead(RFM_pins.DIO0)) {
536+
LORA_Receive_Data(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
537+
if (Data_Rx.Counter > 0) {
538+
Rx_Status = NEW_RX;
539+
if (Message_Rx.Frame_Control & 0x20) {
540+
Ack_Status = NEW_ACK;
541+
}
542+
lora_state = LORA_STATE_IDLE; // Datos recibidos, terminar
543+
break;
544+
}
545+
if (RFM_Command_Status == JOIN) {
546+
if (LORA_join_Accept(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx)) {
547+
lora_state = LORA_STATE_IDLE;
548+
break;
549+
}
550+
}
551+
}
552+
// Pasar a RX2 después de un tiempo
553+
if (millis() >= rx1_timeout + 1000) { // Receive_Delay_2
554+
lora_state = LORA_STATE_WAIT_RX2;
555+
rx2_timeout = millis();
556+
#ifdef US_915
557+
LoRa_Settings.Channel_Rx = 0x08; // 923.3 MHz
558+
LoRa_Settings.Datarate_Rx = SF12BW500;
559+
#elif defined(EU_868)
560+
LoRa_Settings.Channel_Rx = CHRX2; // 869.525 MHz
561+
LoRa_Settings.Datarate_Rx = SF12BW125;
562+
#elif defined(AS_923) || defined(AS_923_2)
563+
LoRa_Settings.Channel_Rx = 0x00; // 923.2 o 921.4 MHz
564+
LoRa_Settings.Datarate_Rx = SF10BW125;
565+
#endif
566+
}
567+
break;
519568

569+
case LORA_STATE_WAIT_RX2:
570+
// Esperar hasta que llegue el tiempo de RX2
571+
if (millis() >= rx2_timeout) {
572+
lora_state = LORA_STATE_RX2;
573+
RFM_Single_Receive(&LoRa_Settings);
574+
}
575+
break;
576+
577+
case LORA_STATE_RX2:
578+
// Verificar si hay datos recibidos
579+
if (digitalRead(RFM_pins.DIO0)) {
580+
LORA_Receive_Data(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
581+
if (Data_Rx.Counter > 0) {
582+
Rx_Status = NEW_RX;
583+
if (Message_Rx.Frame_Control & 0x20) {
584+
Ack_Status = NEW_ACK;
585+
}
586+
}
587+
if (RFM_Command_Status == JOIN) {
588+
if (LORA_join_Accept(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx)) {
589+
lora_state = LORA_STATE_IDLE;
590+
break;
591+
}
592+
}
593+
}
594+
lora_state = LORA_STATE_IDLE; // Terminar ciclo
595+
break;
596+
597+
case LORA_STATE_RX_CONT:
598+
// Recepción continua para clase C
599+
if (digitalRead(RFM_pins.DIO0)) {
600+
LORA_Receive_Data(&Data_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
601+
if (Data_Rx.Counter > 0) {
602+
Rx_Status = NEW_RX;
603+
if (Message_Rx.Frame_Control & 0x20) {
604+
Ack_Status = NEW_ACK;
605+
}
606+
}
607+
RFM_Continuous_Receive(&LoRa_Settings); // Reanudar recepción
608+
}
609+
break;
610+
}
520611
}
521612

522613
void LoRaWANClass::randomChannel()

src/arduino-rfm/lorawan-arduino-rfm.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@
4747
*/
4848

4949
#define LORAWAN_VERSION "1.0.0"
50+
51+
typedef enum {
52+
LORA_STATE_IDLE, // Reposo, esperando un comando
53+
LORA_STATE_TX, // Transmitiendo datos
54+
LORA_STATE_WAIT_RX1, // Esperando ventana RX1 (clase A)
55+
LORA_STATE_RX1, // Recibiendo en RX1 (clase A)
56+
LORA_STATE_WAIT_RX2, // Esperando ventana RX2 (clase A)
57+
LORA_STATE_RX2, // Recibiendo en RX2 (clase A)
58+
LORA_STATE_RX_CONT, // Recepción continua (clase C)
59+
} lora_state_t;
60+
5061
/*
5162
*****************************************************************************************
5263
* CLASS
@@ -109,6 +120,14 @@ class LoRaWANClass
109120
void randomChannel();
110121

111122
private:
123+
124+
// State
125+
lora_state_t lora_state;
126+
unsigned long rx1_timeout;
127+
unsigned long rx2_timeout;
128+
unsigned char rx1_channel;
129+
unsigned char rx1_datarate;
130+
112131
// Messages
113132
unsigned char Data_Tx[MAX_UPLINK_PAYLOAD_SIZE];
114133
sBuffer Buffer_Tx;

0 commit comments

Comments
 (0)