LoRa_Node_STM32F103C8T6

Dependencies:   mbed mbed-STM32F103C8T6 OneWireCRC_LoRa_Node SX1276Lib_LoRa_Node

Committer:
lukas_formanek
Date:
Sat May 08 16:04:09 2021 +0000
Revision:
9:bc6233d6a997
Parent:
8:978eb43296ae
Lora_Node

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lukas_formanek 0:cc04364f049a 1 #include "RFM95W.h"
lukas_formanek 0:cc04364f049a 2
lukas_formanek 6:531b8dccca06 3 RFM95W rfm;
lukas_formanek 0:cc04364f049a 4
lukas_formanek 0:cc04364f049a 5 //--------------------------- Callback funkcie ---------------------------------
lukas_formanek 6:531b8dccca06 6 void TxDone(void)
lukas_formanek 6:531b8dccca06 7 {
lukas_formanek 6:531b8dccca06 8 rfm.OnTxDone();
lukas_formanek 6:531b8dccca06 9 };
lukas_formanek 0:cc04364f049a 10
lukas_formanek 6:531b8dccca06 11 void RxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
lukas_formanek 6:531b8dccca06 12 {
lukas_formanek 6:531b8dccca06 13 rfm.OnRxDone(payload,size,rssi,snr);
lukas_formanek 6:531b8dccca06 14 };
lukas_formanek 0:cc04364f049a 15
lukas_formanek 6:531b8dccca06 16 void TxTimeout(void)
lukas_formanek 6:531b8dccca06 17 {
lukas_formanek 6:531b8dccca06 18 rfm.OnTxTimeout();
lukas_formanek 6:531b8dccca06 19 };
lukas_formanek 0:cc04364f049a 20
lukas_formanek 6:531b8dccca06 21 void RxTimeout(void)
lukas_formanek 6:531b8dccca06 22 {
lukas_formanek 6:531b8dccca06 23 rfm.OnRxTimeout();
lukas_formanek 6:531b8dccca06 24 };
lukas_formanek 0:cc04364f049a 25
lukas_formanek 6:531b8dccca06 26 void RxError(void)
lukas_formanek 6:531b8dccca06 27 {
lukas_formanek 6:531b8dccca06 28 rfm.OnRxError();
lukas_formanek 6:531b8dccca06 29 };
lukas_formanek 0:cc04364f049a 30
lukas_formanek 6:531b8dccca06 31 void CadDone(bool channelActivityDetected)
lukas_formanek 6:531b8dccca06 32 {
lukas_formanek 6:531b8dccca06 33 rfm.OnCadDone(channelActivityDetected);
lukas_formanek 6:531b8dccca06 34 };
lukas_formanek 0:cc04364f049a 35 //------------------------------------------------------------------------------
lukas_formanek 0:cc04364f049a 36
lukas_formanek 0:cc04364f049a 37 RFM95W::RFM95W()
lukas_formanek 0:cc04364f049a 38 : radio(NULL),
lukas_formanek 1:a54ff5e2c2f3 39 indicationLed(LED_PIN),
lukas_formanek 0:cc04364f049a 40 noise(NOISE_PIN)
lukas_formanek 0:cc04364f049a 41 {
lukas_formanek 0:cc04364f049a 42 memset(receivedMessage, '\0', sizeof(receivedMessage));
lukas_formanek 0:cc04364f049a 43 ledState = 0;
lukas_formanek 9:bc6233d6a997 44 timeOnAirSec = 0.4;
lukas_formanek 0:cc04364f049a 45 indicationLed = 1;
lukas_formanek 0:cc04364f049a 46 messageNumber = NODE_ID;
lukas_formanek 3:369546c57dc7 47 sendCounter = 0;
lukas_formanek 3:369546c57dc7 48 receivedAck = false;
lukas_formanek 0:cc04364f049a 49 };
lukas_formanek 0:cc04364f049a 50
lukas_formanek 0:cc04364f049a 51 void RFM95W::OnLedTick()
lukas_formanek 0:cc04364f049a 52 {
lukas_formanek 0:cc04364f049a 53 if(ledState<6) {
lukas_formanek 0:cc04364f049a 54 indicationLed = !indicationLed;
lukas_formanek 0:cc04364f049a 55 } else {
lukas_formanek 0:cc04364f049a 56 ledState = 0;
lukas_formanek 0:cc04364f049a 57 indicationLed = 1;
lukas_formanek 0:cc04364f049a 58 ledTicker.detach();
lukas_formanek 0:cc04364f049a 59 }
lukas_formanek 0:cc04364f049a 60 ledState++;
lukas_formanek 0:cc04364f049a 61 }
lukas_formanek 0:cc04364f049a 62
lukas_formanek 1:a54ff5e2c2f3 63 void RFM95W::SendMessage()
lukas_formanek 1:a54ff5e2c2f3 64 {
lukas_formanek 4:a8853c148f2a 65 snprintf((char *)ack, 3, "%c%c%c",NODE_ID, sendBuffer[0], messageNumber);
lukas_formanek 9:bc6233d6a997 66 radio.Send( sendBuffer, 30 );
lukas_formanek 1:a54ff5e2c2f3 67 }
lukas_formanek 1:a54ff5e2c2f3 68
lukas_formanek 0:cc04364f049a 69 void RFM95W::SendAck(uint8_t addr, uint8_t messageNumber)
lukas_formanek 0:cc04364f049a 70 {
lukas_formanek 0:cc04364f049a 71 uint8_t ack[3];
lukas_formanek 4:a8853c148f2a 72 snprintf((char *)ack, sizeof(ack), "%c%c%c", addr, NODE_ID, messageNumber);
lukas_formanek 8:978eb43296ae 73 // PC.printf("Sending Ack : %s \r\n",ack);
lukas_formanek 0:cc04364f049a 74 radio.Send(ack, 3);
lukas_formanek 0:cc04364f049a 75 };
lukas_formanek 0:cc04364f049a 76
lukas_formanek 2:8bd9ce0ae2df 77 float RFM95W::CalculateRandomTime()
lukas_formanek 2:8bd9ce0ae2df 78 {
lukas_formanek 5:6e899f5db65e 79 uint8_t number = rand() % 1500;;
lukas_formanek 6:531b8dccca06 80 while(number == 0) {
lukas_formanek 6:531b8dccca06 81 number = rand() % 1500;
lukas_formanek 6:531b8dccca06 82 }
lukas_formanek 9:bc6233d6a997 83 return (timeOnAirSec * (number / 500.0));
lukas_formanek 2:8bd9ce0ae2df 84 };
lukas_formanek 2:8bd9ce0ae2df 85
lukas_formanek 2:8bd9ce0ae2df 86 void RFM95W::OnCheckAck()
lukas_formanek 2:8bd9ce0ae2df 87 {
lukas_formanek 9:bc6233d6a997 88 if((receivedAck == false) && (sendCounter < MAX_RESENDS)) {
lukas_formanek 9:bc6233d6a997 89 sendTicker.detach();
lukas_formanek 5:6e899f5db65e 90 sendTicker.attach(this,&RFM95W::OnSendAgain, CalculateRandomTime());
lukas_formanek 9:bc6233d6a997 91 } else if((receivedAck == false) && (sendCounter >= MAX_RESENDS)) {
lukas_formanek 5:6e899f5db65e 92 messageNumber++;
lukas_formanek 5:6e899f5db65e 93 if(messageNumber>255)
lukas_formanek 5:6e899f5db65e 94 messageNumber = 0;
lukas_formanek 9:bc6233d6a997 95 radio.Sleep();
lukas_formanek 2:8bd9ce0ae2df 96 }
lukas_formanek 2:8bd9ce0ae2df 97 ackTicker.detach();
lukas_formanek 2:8bd9ce0ae2df 98 };
lukas_formanek 2:8bd9ce0ae2df 99
lukas_formanek 2:8bd9ce0ae2df 100 void RFM95W::OnSendAgain()
lukas_formanek 2:8bd9ce0ae2df 101 {
lukas_formanek 2:8bd9ce0ae2df 102 SendMessage();
lukas_formanek 2:8bd9ce0ae2df 103 sendCounter++;
lukas_formanek 2:8bd9ce0ae2df 104 sendTicker.detach();
lukas_formanek 2:8bd9ce0ae2df 105 };
lukas_formanek 2:8bd9ce0ae2df 106
lukas_formanek 0:cc04364f049a 107 void RFM95W::OnTxDone( void )
lukas_formanek 0:cc04364f049a 108 {
lukas_formanek 4:a8853c148f2a 109 if(sendingAck)
lukas_formanek 4:a8853c148f2a 110 sendingAck = false;
lukas_formanek 6:531b8dccca06 111 else {
lukas_formanek 4:a8853c148f2a 112 receivedAck = false;
lukas_formanek 9:bc6233d6a997 113 ackTicker.detach();
lukas_formanek 9:bc6233d6a997 114 ackTicker.attach(this,&RFM95W::OnCheckAck,timeOnAirSec*2);
lukas_formanek 4:a8853c148f2a 115 }
lukas_formanek 0:cc04364f049a 116 radio.Rx(0);
lukas_formanek 0:cc04364f049a 117 };
lukas_formanek 0:cc04364f049a 118
lukas_formanek 0:cc04364f049a 119 void RFM95W::OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
lukas_formanek 0:cc04364f049a 120 {
lukas_formanek 0:cc04364f049a 121 radio.Sleep();
lukas_formanek 4:a8853c148f2a 122 if(payload[0] == NODE_ID) {
lukas_formanek 9:bc6233d6a997 123 indicationLed = 1;
lukas_formanek 9:bc6233d6a997 124 // #if LED_SIGNALIZE == 1
lukas_formanek 9:bc6233d6a997 125 // ledTicker.detach();
lukas_formanek 9:bc6233d6a997 126 // ledTicker.attach(this,&RFM95W::OnLedTick, LED_BLIK_PERIOD);
lukas_formanek 9:bc6233d6a997 127 // #endif
lukas_formanek 6:531b8dccca06 128 if((size == 3) && (strncmp( ( const char* )payload, ( const char* )ack, 3 ) == 0) ) {
lukas_formanek 3:369546c57dc7 129 receivedAck = true;
lukas_formanek 8:978eb43296ae 130 // PC.printf("Received Ack : %s \r\n",ack);
lukas_formanek 1:a54ff5e2c2f3 131 messageNumber++;
lukas_formanek 1:a54ff5e2c2f3 132 if(messageNumber>255)
lukas_formanek 1:a54ff5e2c2f3 133 messageNumber = 0;
lukas_formanek 9:bc6233d6a997 134 // radio.Rx(0);
lukas_formanek 9:bc6233d6a997 135 // radio.Sleep();
lukas_formanek 9:bc6233d6a997 136 radio.Rx(1500); // 1,5 s este cakam
lukas_formanek 1:a54ff5e2c2f3 137 return;
lukas_formanek 6:531b8dccca06 138 }
lukas_formanek 6:531b8dccca06 139 sendingAck = true;
lukas_formanek 7:1aa5c96a8b9f 140 uint8_t MsgFrom = payload[1];
lukas_formanek 0:cc04364f049a 141 SendAck(MsgFrom,payload[2]);
lukas_formanek 8:978eb43296ae 142 // PC.printf("MSG from : %c , message number received= %d \r\n",MsgFrom,payload[2]);
lukas_formanek 6:531b8dccca06 143 if(payload[2] == messageNumbers[MsgFrom]) {
lukas_formanek 9:bc6233d6a997 144 // PC.printf("--------------------- Ta ista sprava -------------------- \r\n");
lukas_formanek 0:cc04364f049a 145 return;
lukas_formanek 0:cc04364f049a 146 }
lukas_formanek 0:cc04364f049a 147 messageNumbers[MsgFrom] = payload[2];
lukas_formanek 4:a8853c148f2a 148 payload[2] = 48; // ASCII hodnota cisla 0
lukas_formanek 4:a8853c148f2a 149 memmove(payload, payload+4, size - 4 + 1);
lukas_formanek 8:978eb43296ae 150 // PC.printf("Upraveny payload : %s\r\n",payload);
lukas_formanek 4:a8853c148f2a 151 snprintf((char *)receivedMessage, BUFF_SIZE, "%s", payload);
lukas_formanek 5:6e899f5db65e 152 ProcessReceivedMessage();
lukas_formanek 0:cc04364f049a 153 return;
lukas_formanek 0:cc04364f049a 154 }
lukas_formanek 7:1aa5c96a8b9f 155 radio.Rx(0);
lukas_formanek 0:cc04364f049a 156 };
lukas_formanek 0:cc04364f049a 157
lukas_formanek 5:6e899f5db65e 158 void RFM95W::ProcessReceivedMessage()
lukas_formanek 5:6e899f5db65e 159 {
lukas_formanek 9:bc6233d6a997 160 int time = atoi((const char*)receivedMessage);
lukas_formanek 9:bc6233d6a997 161 thermometer.StopPeriodicMeassure();
lukas_formanek 9:bc6233d6a997 162 thermometer.StartPeriodicMeassure(time);
lukas_formanek 8:978eb43296ae 163 // PC.printf("Skonvertovane cislo : %d \r\n",time);
lukas_formanek 5:6e899f5db65e 164 };
lukas_formanek 5:6e899f5db65e 165
lukas_formanek 0:cc04364f049a 166 void RFM95W::OnTxTimeout( void )
lukas_formanek 0:cc04364f049a 167 {
lukas_formanek 0:cc04364f049a 168 radio.Sleep();
lukas_formanek 0:cc04364f049a 169 Init();
lukas_formanek 0:cc04364f049a 170 };
lukas_formanek 0:cc04364f049a 171
lukas_formanek 0:cc04364f049a 172 void RFM95W::OnRxTimeout( void )
lukas_formanek 0:cc04364f049a 173 {
lukas_formanek 0:cc04364f049a 174 radio.Sleep();
lukas_formanek 9:bc6233d6a997 175 // radio.Rx(0);
lukas_formanek 0:cc04364f049a 176 };
lukas_formanek 0:cc04364f049a 177
lukas_formanek 0:cc04364f049a 178 void RFM95W::OnRxError( void )
lukas_formanek 0:cc04364f049a 179 {
lukas_formanek 0:cc04364f049a 180 radio.Sleep();
lukas_formanek 8:978eb43296ae 181 // PC.printf("Chyba prijatia ! \r\n");
lukas_formanek 9:bc6233d6a997 182 // radio.Rx(0);
lukas_formanek 0:cc04364f049a 183 };
lukas_formanek 0:cc04364f049a 184
lukas_formanek 6:531b8dccca06 185 void RFM95W::OnCadDone( bool channelActivityDetected ) {};
lukas_formanek 0:cc04364f049a 186
lukas_formanek 9:bc6233d6a997 187 void RFM95W::SendValue(uint8_t addr, float tempValue, uint16_t fotoValue, float batteryValue)
lukas_formanek 0:cc04364f049a 188 {
lukas_formanek 9:bc6233d6a997 189 snprintf((char *)sendBuffer, BUFF_SIZE, "%c%c%c|%.2f|%d|%.3f|",addr, NODE_ID, messageNumber, tempValue, fotoValue, batteryValue);
lukas_formanek 2:8bd9ce0ae2df 190 sendCounter = 0;
lukas_formanek 2:8bd9ce0ae2df 191 receivedAck = false;
lukas_formanek 1:a54ff5e2c2f3 192 SendMessage();
lukas_formanek 0:cc04364f049a 193 };
lukas_formanek 0:cc04364f049a 194
lukas_formanek 0:cc04364f049a 195 void RFM95W::Init( void )
lukas_formanek 0:cc04364f049a 196 {
lukas_formanek 9:bc6233d6a997 197 // PC.printf( "\n\n\r------- RFM95W GATEWAY -------\n\r" );
lukas_formanek 0:cc04364f049a 198 // Initialize Radio driver
lukas_formanek 0:cc04364f049a 199 radioEvents.TxDone = TxDone;
lukas_formanek 0:cc04364f049a 200 radioEvents.RxDone = RxDone;
lukas_formanek 0:cc04364f049a 201 radioEvents.RxError = RxError;
lukas_formanek 0:cc04364f049a 202 radioEvents.TxTimeout = TxTimeout;
lukas_formanek 0:cc04364f049a 203 radioEvents.RxTimeout = RxTimeout;
lukas_formanek 0:cc04364f049a 204 radioEvents.CadDone = CadDone;
lukas_formanek 0:cc04364f049a 205 radio.Init( &radioEvents );
lukas_formanek 0:cc04364f049a 206 // verify the connection with the board
lukas_formanek 0:cc04364f049a 207 while( radio.Read( REG_VERSION ) == 0x00 ) {
lukas_formanek 9:bc6233d6a997 208 // PC.printf( "Radiovy modul nie je pripojeny!\n\r", NULL );
lukas_formanek 0:cc04364f049a 209 wait(1);
lukas_formanek 0:cc04364f049a 210 }
lukas_formanek 0:cc04364f049a 211 radio.SetChannel( RF_FREQUENCY );
lukas_formanek 0:cc04364f049a 212 #if USE_MODEM_LORA == 1
lukas_formanek 9:bc6233d6a997 213 // PC.printf("\n\r > LORA Mod < \n\n\r");
lukas_formanek 0:cc04364f049a 214 radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
lukas_formanek 0:cc04364f049a 215 LORA_SPREADING_FACTOR, LORA_CODINGRATE,
lukas_formanek 0:cc04364f049a 216 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
lukas_formanek 0:cc04364f049a 217 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
lukas_formanek 0:cc04364f049a 218 LORA_IQ_INVERSION_ON, 2000000 );
lukas_formanek 0:cc04364f049a 219
lukas_formanek 0:cc04364f049a 220 radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
lukas_formanek 0:cc04364f049a 221 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
lukas_formanek 0:cc04364f049a 222 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
lukas_formanek 0:cc04364f049a 223 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
lukas_formanek 0:cc04364f049a 224 LORA_IQ_INVERSION_ON, true );
lukas_formanek 0:cc04364f049a 225
lukas_formanek 0:cc04364f049a 226 #elif USE_MODEM_FSK == 1
lukas_formanek 0:cc04364f049a 227
lukas_formanek 9:bc6233d6a997 228 // PC.printf("\n\r > FSK Mod < \n\n\r");
lukas_formanek 0:cc04364f049a 229 radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
lukas_formanek 0:cc04364f049a 230 FSK_DATARATE, 0,
lukas_formanek 0:cc04364f049a 231 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
lukas_formanek 0:cc04364f049a 232 FSK_CRC_ENABLED, 0, 0, 0, 2000000 );
lukas_formanek 0:cc04364f049a 233
lukas_formanek 0:cc04364f049a 234 radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
lukas_formanek 0:cc04364f049a 235 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
lukas_formanek 0:cc04364f049a 236 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
lukas_formanek 0:cc04364f049a 237 0, 0, false, true );
lukas_formanek 0:cc04364f049a 238
lukas_formanek 0:cc04364f049a 239 #else
lukas_formanek 0:cc04364f049a 240
lukas_formanek 0:cc04364f049a 241 #error "Nie je definovany typ modemu."
lukas_formanek 0:cc04364f049a 242
lukas_formanek 0:cc04364f049a 243 #endif
lukas_formanek 0:cc04364f049a 244 // Konfiguracia pre moznost max. vysielacieho vykonu
lukas_formanek 0:cc04364f049a 245 uint8_t paConfig;
lukas_formanek 0:cc04364f049a 246 paConfig = radio.Read( REG_PACONFIG );
lukas_formanek 0:cc04364f049a 247 paConfig |= RF_PACONFIG_PASELECT_PABOOST;
lukas_formanek 0:cc04364f049a 248 radio.Write( REG_PACONFIG, paConfig );
lukas_formanek 6:531b8dccca06 249
lukas_formanek 9:bc6233d6a997 250 // PC.printf("________Start aplikacie________\r\n" );
lukas_formanek 9:bc6233d6a997 251 timeOnAirSec = (radio.TimeOnAir( MODEM_LORA, 30)/1000.0); // time on air v ms
lukas_formanek 9:bc6233d6a997 252 // PC.printf( "\n\n\r------- Time on air : %f sec. -------\n\r", timeOnAirSec);
lukas_formanek 0:cc04364f049a 253 indicationLed = 1;
lukas_formanek 0:cc04364f049a 254 InitRandom();
lukas_formanek 0:cc04364f049a 255 messageNumber = rand();
lukas_formanek 6:531b8dccca06 256 for(uint16_t i = 0; i < MAX_DEVICES; i++)
lukas_formanek 3:369546c57dc7 257 messageNumbers[i]=rand() % 256;
lukas_formanek 9:bc6233d6a997 258 // radio.Rx(0);
lukas_formanek 9:bc6233d6a997 259 radio.Sleep();
lukas_formanek 0:cc04364f049a 260 };
lukas_formanek 0:cc04364f049a 261
lukas_formanek 0:cc04364f049a 262 void RFM95W::InitRandom()
lukas_formanek 0:cc04364f049a 263 {
lukas_formanek 0:cc04364f049a 264 uint32_t seed;
lukas_formanek 0:cc04364f049a 265 uint8_t loops = 3;
lukas_formanek 0:cc04364f049a 266 for (int i=0; i<(32*loops); i++) {
lukas_formanek 0:cc04364f049a 267 seed ^= noise.read_u16();
lukas_formanek 6:531b8dccca06 268 if (seed & 1<31) {
lukas_formanek 0:cc04364f049a 269 seed <<= 1;
lukas_formanek 0:cc04364f049a 270 seed |= 1;
lukas_formanek 0:cc04364f049a 271 } else
lukas_formanek 0:cc04364f049a 272 seed <<= 1;
lukas_formanek 0:cc04364f049a 273 }
lukas_formanek 0:cc04364f049a 274 srand(seed);
lukas_formanek 0:cc04364f049a 275 };