LoRa Access Point 1.5.2018

Dependencies:   mbed ds3231 SX1276Lib_LoRa_Access_Point

Committer:
lukas_formanek
Date:
Mon Apr 23 21:28:36 2018 +0000
Revision:
3:7a3ddda464bf
Parent:
2:0499e1d037a5
Child:
4:e20eb5efd859
23.4.2018 ver 2

Who changed what in which revision?

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