LoRa_Node_STM32F103C8T6

Dependencies:   mbed mbed-STM32F103C8T6 OneWireCRC_LoRa_Node SX1276Lib_LoRa_Node

Committer:
lukas_formanek
Date:
Mon Apr 23 21:28:49 2018 +0000
Revision:
4:a8853c148f2a
Parent:
3:369546c57dc7
Child:
5:6e899f5db65e
23.4.2018 ver 2

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