LoRa Access Point 1.5.2018
Dependencies: mbed ds3231 SX1276Lib_LoRa_Access_Point
RFM95W.cpp
- Committer:
- lukas_formanek
- Date:
- 2018-04-23
- Revision:
- 3:7a3ddda464bf
- Parent:
- 2:0499e1d037a5
- Child:
- 4:e20eb5efd859
File content as of revision 3:7a3ddda464bf:
#include "RFM95W.h" RFM95W rfm; // Globalna instancia //--------------------------- Callback funkcie --------------------------------- void TxDone(void){rfm.OnTxDone();}; void RxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ){rfm.OnRxDone(payload,size,rssi,snr);}; void TxTimeout(void){rfm.OnTxTimeout();}; void RxTimeout(void){rfm.OnRxTimeout();}; void RxError(void){rfm.OnRxError();}; void CadDone(bool channelActivityDetected){rfm.OnCadDone(channelActivityDetected);}; //------------------------------------------------------------------------------ RFM95W::RFM95W() : radio(NULL), indicationLed(LED_PIN), noise(NOISE_PIN) { for(uint16_t i=0; i<MAX_DEVICES;i++) messageNumbers[i]=NULL; memset(receivedMessage, '\0', sizeof(receivedMessage)); ledState = 0; timeOnAirSec = 0.3; indicationLed = 1; messageNumber = GATEWAY_ID; sendCounter = 0; receivedAck = false; }; void RFM95W::OnLedTick() { if(ledState<6) { indicationLed = !indicationLed; } else { ledState = 0; indicationLed = 1; ledTicker.detach(); } ledState++; } void RFM95W::SendMessage() { snprintf((char *)ack, 3, "%c%c%c",GATEWAY_ID, sendBuffer[0], messageNumber); radio.Send( sendBuffer, 10 ); // poslem len 10 bajtov } void RFM95W::SendAck(uint8_t addr, uint8_t messageNumber) { uint8_t ack[3]; snprintf((char *)ack, sizeof(ack), "%c%c%c", addr, GATEWAY_ID, messageNumber); pc.printf("Sending Ack : %s \r\n",ack); radio.Send(ack, 3); }; float RFM95W::CalculateRandomTime() { uint8_t number; while(number == 0) {number = rand() % 1200;} return (timeOnAirSec * (number / 200.0)); }; void RFM95W::OnCheckAck() { if((receivedAck == false) && (sendCounter < MAX_RESENDS)) { sendTicker.attach(callback(this,&RFM95W::OnSendAgain), CalculateRandomTime()); /* NumberOfFailSends++; if(NumberOfFailSends >=3 ) { // MessageAlter = !MessageAlter; // ???????????????????????????????????????????????????????????????????????????????????????????????????????? NumberOfFailSends = 0; sampleTicker.detach(); sampleTicker.attach(&onSampleTick,15.0); // kazdych 15s } */ } ackTicker.detach(); }; void RFM95W::OnSendAgain() { SendMessage(); sendCounter++; sendTicker.detach(); }; void RFM95W::OnTxDone( void ) { radio.Sleep(); if(sendingAck) sendingAck = false; else { receivedAck = false; ackTicker.attach(callback(this,&RFM95W::OnCheckAck),timeOnAirSec*3); } radio.Rx(0); }; void RFM95W::OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { radio.Sleep(); // debug("%d \r\n", payload[0]); if(payload[0] == GATEWAY_ID) { indicationLed=0; ledTicker.attach(callback(this,&RFM95W::OnLedTick), LED_BLIK_PERIOD); if((size == 3) && (strncmp( ( const char* )payload, ( const char* )ack, 3 ) == 0) ) { receivedAck = true; pc.printf("Received Ack : %s \r\n",ack); messageNumber++; if(messageNumber>255) messageNumber = 0; radio.Rx(0); return; } sendingAck = true; // moje ID - adresa brany, konverzia na cislo uint8_t msgFrom = payload[1]; // konverzia na cislo SendAck(msgFrom,payload[2]); pc.printf("MSG from : %c , message number received= %d \r\n",msgFrom,payload[2]); if(payload[2] == messageNumbers[msgFrom]) { pc.printf("--------------------- Ta ista sprava -------------------- \r\n"); // radio.Rx(0); return; } messageNumbers[msgFrom] = payload[2]; payload[2] = 48; // ASCII hodnota cisla 0 // pc.printf("Message number saved= %d \r\n",messageNumbers[MsgFrom]); memmove(payload, payload+4, size - 4 + 1); // orezem prve styri bajty snprintf((char *)receivedMessage, BUFF_SIZE, "%d|%d|%d|%d|%s|\r\n", rssi, snr, GATEWAY_ID, msgFrom, payload); wifi.SendMessage((char *)receivedMessage); // debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" ); return; } radio.Rx(0); // som zakomentil :P }; void RFM95W::OnTxTimeout( void ) { radio.Sleep(); Init(); // radio.Rx(0); }; void RFM95W::OnRxTimeout( void ) { radio.Sleep(); radio.Rx(0); }; void RFM95W::OnRxError( void ) { radio.Sleep(); pc.printf("Chyba prijatia ! \r\n"); radio.Rx(0); }; void RFM95W::OnCadDone( bool channelActivityDetected ){}; void RFM95W::SendValue(uint8_t addr, float value) { snprintf((char *)sendBuffer, BUFF_SIZE, "%c%c%c|%.2f|",addr, GATEWAY_ID, messageNumber, value); sendCounter = 0; receivedAck = false; SendMessage(); }; void RFM95W::Init( void ) { pc.printf( "\n\n\r------- RFM95W GATEWAY -------\n\r" ); // Initialize Radio driver radioEvents.TxDone = TxDone; radioEvents.RxDone = RxDone; radioEvents.RxError = RxError; radioEvents.TxTimeout = TxTimeout; radioEvents.RxTimeout = RxTimeout; radioEvents.CadDone = CadDone; radio.Init( &radioEvents ); // verify the connection with the board while( radio.Read( REG_VERSION ) == 0x00 ) { pc.printf( "Radiovy modul nie je pripojeny!\n\r", NULL ); wait(1); } // debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1LAS ) ) , "\n\r > TYP: RFM95W < \n\r" ); // debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "\n\r > TYP: RFM95W < \n\r" ); radio.SetChannel( RF_FREQUENCY ); #if USE_MODEM_LORA == 1 // debug_if( LORA_FHSS_ENABLED, "\n\r > LORA FHSS Mod < \n\n\r"); // debug_if( !LORA_FHSS_ENABLED, "\n\r > LORA Mod < \n\n\r"); pc.printf("\n\r > LORA Mod < \n\n\r"); radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, LORA_IQ_INVERSION_ON, 2000000 ); radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, LORA_IQ_INVERSION_ON, true ); #elif USE_MODEM_FSK == 1 pc.printf("\n\r > FSK Mod < \n\n\r"); radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, FSK_DATARATE, 0, FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, FSK_CRC_ENABLED, 0, 0, 0, 2000000 ); radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, 0, 0, false, true ); #else #error "Nie je definovany typ modemu." #endif // Konfiguracia pre moznost max. vysielacieho vykonu uint8_t paConfig; paConfig = radio.Read( REG_PACONFIG ); paConfig |= RF_PACONFIG_PASELECT_PABOOST; radio.Write( REG_PACONFIG, paConfig ); pc.printf("________Start aplikacie________\r\n" ); timeOnAirSec = (radio.TimeOnAir( MODEM_LORA, 10)/1000.0); // time on air v ms pc.printf( "\n\n\r------- Time on air : %f sec. -------\n\r", timeOnAirSec); indicationLed = 1; InitRandom(); messageNumber = rand(); radio.Rx(0); }; void RFM95W::InitRandom() { uint32_t seed; uint8_t loops = 3; for (int i=0; i<(32*loops); i++) { seed ^= noise.read_u16(); if (seed & 1<31) { // shift left and wrap. seed <<= 1; seed |= 1; } else seed <<= 1; } srand(seed); };