RX

Dependencies:   mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* Includes */
00002 #include "mbed.h" /* Mbed include */
00003 
00004 /* Lora includes */
00005 #include "PinMap.h"
00006 #include "sx1276-mbed-hal.h"
00007 
00008 /* Serial communication include */
00009 #include "BufferedSerial.h"
00010 
00011 /* Set this flag to '1' to display debug messages on the console */
00012 #define DEBUG_MESSAGE   1
00013 
00014 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
00015 #define USE_MODEM_LORA  1
00016 #define USE_MODEM_FSK   !USE_MODEM_LORA
00017 #define RF_FREQUENCY            RF_FREQUENCY_915_0 // Hz
00018 #define TX_OUTPUT_POWER         14                  // 14 dBm
00019 
00020 #if USE_MODEM_LORA == 1
00021 
00022 #define LORA_BANDWIDTH          125000  // LoRa default, details in SX1276::BandwidthMap
00023 #define LORA_SPREADING_FACTOR   LORA_SF7
00024 #define LORA_CODINGRATE         LORA_ERROR_CODING_RATE_4_5
00025 
00026 #define LORA_PREAMBLE_LENGTH    8       // Same for Tx and Rx
00027 #define LORA_SYMBOL_TIMEOUT     5       // Symbols
00028 #define LORA_FIX_LENGTH_PAYLOAD_ON  false
00029 #define LORA_FHSS_ENABLED       false  
00030 #define LORA_NB_SYMB_HOP        4     
00031 #define LORA_IQ_INVERSION_ON    false
00032 #define LORA_CRC_ENABLED        true
00033     
00034 #endif 
00035 
00036 #define RX_TIMEOUT_VALUE    0       // In ms
00037 #define TX_TIMEOUT_VALUE    1000000 // In ms
00038 
00039 //#define BUFFER_SIZE       32        // Define the payload size here
00040 #define BUFFER_SIZE         64      // Define the payload size here
00041 
00042 typedef struct {
00043     /* Header for identification of updated informations */
00044     bool header [8];
00045     int time; // Time between transmissions
00046     int32_t ag[3]; // Acceleration of the accelerometer and gyroscope LSM6DSL 
00047     int32_t w[3]; // Angular velocity of LSM6DSL
00048     int32_t a[3]; // Acceleration of the accelerometer LSM303AGR
00049     int32_t m [3]; // Heading of LSM303AGR
00050     float p;  // Pressure of LPS22HB
00051     float temperatureLPS22HB; // Temperature from LPS22HB
00052     float humidity; // Humidity of HTS221 
00053     float temperatureHTS221; // Temperature from HTS221
00054     unsigned long timeOfWeek; //GPS time of week
00055     long timeOfWeekFracPart; // GPS time of week fractional part
00056     unsigned char gpsFix; // GPS fix
00057     long ecefx; // GPS X posiition
00058     long ecefy; // GPS Y posistion
00059     long ecefz; // GPS Z postion
00060     unsigned long positionAcc3D; // GPS 3D position accuracy
00061     long ecefvx; // GPS X velocity
00062     long ecefvy; // GPS Y velocity
00063     long ecefvz; // GPS Z velocity
00064     unsigned long speedAcc; // GPS speed accuracy
00065     unsigned char numbSat; // GPS number of satellites conected
00066     bool drogueStatus; // Drogue parachute status provided by Avionics
00067     bool mainStatus; //Main parachute status provided by Avionics
00068     float pressureBar; // Pressure by COTS Altimeter
00069     float temperature; // Temperature by COTS Altimeter
00070     bool mainStatusCOTS; // Main parachute status provided by COTS Altimeter
00071     bool drogueStatusCOTS; // Drogue status provided by COTS Altimeter
00072     int16_t timeStamp; //Timestamp from COTS Altimeter
00073     int16_t aglAlt; //AGL Altitude from COTS Altimeter
00074     int8_t battery; //Battery voltage reading from COTS Altimeter
00075 }Data; // Data struct
00076 
00077 Data data;
00078 
00079 /* LoRa modem instances and configurations */
00080 
00081 static RadioEvents_t RadioEvents; // Calback functions struct
00082 
00083 SX1276Generic *Radio; // Definition of a Radio object
00084 
00085 bool received = false; // Flag to indicate the end of reception
00086 
00087 /* Configuration function */
00088 void SystemClock_Config(void);
00089 
00090 /* Callback functions prototypes */
00091 
00092 // Brief Function to be executed on Radio Tx Done event
00093 void OnTxDone(void *radio, void *userThisPtr, void *userData);
00094 
00095 // Brief Function to be executed on Radio Rx Done event
00096 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
00097 
00098 // Brief Function executed on Radio Tx Timeout event
00099 void OnTxTimeout(void *radio, void *userThisPtr, void *userData);
00100 
00101 // Brief Function executed on Radio Rx Timeout event
00102 void OnRxTimeout(void *radio, void *userThisPtr, void *userData);
00103 
00104 // Brief Function executed on Radio Rx Error event
00105 void OnRxError(void *radio, void *userThisPtr, void *userData);
00106 
00107 // Brief Function executed on Radio Fhss Change Channel event
00108 void OnFhssChangeChannel(void *radio, void *userThisPtr, void *userData, uint8_t channelIndex);
00109 
00110 // Brief Function executed on CAD Done event
00111 void OnCadDone(void *radio, void *userThisPtr, void *userData);
00112 
00113 /* Serial communication to debug program */
00114 BufferedSerial *ser;
00115 
00116 int main() {
00117     SystemClock_Config(); /* Synchronize clock for TX and RX boards */
00118     
00119     /* Serial configuration */
00120     if (DEBUG_MESSAGE) {
00121         ser = new BufferedSerial(USBTX, USBRX);
00122         ser->baud(115200);
00123         ser->format(8);
00124     }
00125     
00126     /* General Header*/
00127     if (DEBUG_MESSAGE)
00128         ser->printf("Telemetry Rx inicial version program\r\n\r\n");
00129     
00130     Radio = new SX1276Generic(NULL, MURATA_SX1276,
00131             LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
00132             LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5,
00133             LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO);
00134     
00135     if (DEBUG_MESSAGE) {        
00136         ser->printf("SX1276 Simple receiver aplication\r\n" );
00137         ser->printf("Frequency: %.1f\r\n", (double)RF_FREQUENCY/1000000.0);
00138         ser->printf("TXPower: %d dBm\r\n",  TX_OUTPUT_POWER);
00139         ser->printf("Bandwidth: %d Hz\r\n", LORA_BANDWIDTH);
00140         ser->printf("Spreading factor: SF%d\r\n", LORA_SPREADING_FACTOR);
00141     }
00142     
00143     // Initialize Radio driver
00144     RadioEvents.TxDone = OnTxDone;
00145     RadioEvents.RxDone = OnRxDone;
00146     RadioEvents.RxError = OnRxError;
00147     RadioEvents.TxTimeout = OnTxTimeout;
00148     RadioEvents.RxTimeout = OnRxTimeout; 
00149     
00150     // Initializes the radio    
00151     while (Radio->Init( &RadioEvents ) == false) {
00152         if (DEBUG_MESSAGE)
00153             ser->printf("Radio could not be detected!\r\n");
00154         wait( 1 );
00155     }
00156     
00157     // Display the board type
00158     switch(Radio->DetectBoardType()) {
00159         case SX1276MB1LAS:
00160             if (DEBUG_MESSAGE)
00161                 ser->printf(" > Board Type: SX1276MB1LAS <\r\n");
00162             break;
00163         case SX1276MB1MAS:
00164             if (DEBUG_MESSAGE)
00165                 ser->printf(" > Board Type: SX1276MB1LAS <\r\n");
00166         case MURATA_SX1276:
00167             if (DEBUG_MESSAGE)
00168                 ser->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n");
00169             break;
00170         case RFM95_SX1276:
00171             if (DEBUG_MESSAGE) 
00172                 ser->printf(" > HopeRF RFM95xx <\r\n");
00173             break;
00174         default:
00175             if (DEBUG_MESSAGE)
00176                 ser->printf(" > Board Type: unknown <\r\n");
00177     }
00178     
00179     Radio->SetChannel(RF_FREQUENCY ); // Sets the frequency of the communication
00180     
00181     // Debug message of the state of fhss
00182     if (LORA_FHSS_ENABLED) {
00183         if (DEBUG_MESSAGE)
00184             ser->printf("             > LORA FHSS Mode <\r\n");
00185     }    
00186     if (!LORA_FHSS_ENABLED) {
00187         if (DEBUG_MESSAGE)
00188             ser->printf("             > LORA Mode <\r\n");
00189     }
00190     // Sets the configuration of the transmission     
00191     Radio->SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
00192                          LORA_SPREADING_FACTOR, LORA_CODINGRATE,
00193                          LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
00194                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00195                          LORA_IQ_INVERSION_ON, 2000 );
00196     
00197     // Sets the configuration of the reception
00198     Radio->SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
00199                          LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
00200                          LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
00201                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00202                          LORA_IQ_INVERSION_ON, true );
00203     if (DEBUG_MESSAGE)
00204         ser->printf("Starting Receive loop\r\n"); 
00205         
00206     Radio->Rx(RX_TIMEOUT_VALUE); // Puts the device in reception mode continuously
00207     
00208     while( 1 )
00209     {   
00210         //After the receiving, puts the device again in receive mode 
00211         if (received == true) {
00212             received = false;
00213             Radio->Rx(RX_TIMEOUT_VALUE); 
00214         }
00215     }
00216     
00217 }
00218 
00219 
00220 void SystemClock_Config(void)
00221 {
00222 #ifdef B_L072Z_LRWAN1_LORA
00223     /* 
00224      * The L072Z_LRWAN1_LORA clock setup is somewhat differnt from the Nucleo board.
00225      * It has no LSE.
00226      */
00227     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
00228     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
00229 
00230     /* Enable HSE Oscillator and Activate PLL with HSE as source */
00231     RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI;
00232     RCC_OscInitStruct.HSEState            = RCC_HSE_OFF;
00233     RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
00234     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
00235     RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
00236     RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSI;
00237     RCC_OscInitStruct.PLL.PLLMUL          = RCC_PLLMUL_6;
00238     RCC_OscInitStruct.PLL.PLLDIV          = RCC_PLLDIV_3;
00239 
00240     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
00241         // Error_Handler();
00242     }
00243 
00244     /* Set Voltage scale1 as MCU will run at 32MHz */
00245     __HAL_RCC_PWR_CLK_ENABLE();
00246     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
00247 
00248     /* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */
00249     while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
00250 
00251     /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
00252     clocks dividers */
00253     RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
00254     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
00255     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
00256     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
00257     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
00258     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
00259         // Error_Handler();
00260     }
00261 #endif
00262 }
00263 
00264 void OnTxDone(void *radio, void *userThisPtr, void *userData)
00265 {
00266     Radio->Sleep( );
00267     if (DEBUG_MESSAGE)
00268         ser->printf("> OnTxDone\r\n");
00269 }
00270 
00271 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
00272 {
00273     Radio->Sleep( );
00274     received = true;
00275     memcpy(&data, payload, sizeof(data));
00276     if (DEBUG_MESSAGE) {
00277         /*
00278         ser->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\r\n", rssi, snr);
00279         ser->printf("I recieved %d mg, %d mg, %d mg, %d mg, %d mg, %d mg, %d mdps, %d mdps, %d mdps\r\n", data.a[0], data.a[1], data.a[2], data.ag[0], data.ag[1], data.ag[2], data.w[0], data.w[1], data.w[2]);
00280         ser->printf("and %d mG, %d mG, %d mG, %g %%, %g C, %g C, %g mBar\r\n", data.m[0], data.m[1], data.m[2], data.humidity, data.temperatureHTS221, data.temperatureLPS22HB, data.p);
00281         ser->printf("and time - %d ms, time of the week - %d ms, time of week frac part - %d ns\r\n",data.time, data.timeOfWeek, data.timeOfWeekFracPart);
00282         ser->printf("and GPS fix %c, ECEFX %d cm, ECEFY %d cm, ECEFZ %d cm\r\n", data.gpsFix, data.ecefx, data.ecefy, data.ecefz);
00283         ser->printf("and 3D Position accuracy %d cm, ECEFVX %d cm/s, ECEFVY %d cm/s, ECEFVZ %d cm/s, Speed accuracy %d cm/s\r\n", data.positionAcc3D, data.ecefvx, data.ecefvy, data.ecefvz, data.speedAcc);    
00284         ser->printf("and Number of satelites %x, Drogue Status %x, Main status %x, BMP280 %f bar, temperature %f C\r\n", data.numbSat, data.drogueStatus, data.mainStatus, data.pressureBar, data.temperature);
00285         ser->printf("Main Status COTS %x, Drogue Status COTS %x, Time Stamp %d s, AGL altitude %d m, Battery voltage %d V\r\n",data.mainStatusCOTS, data.drogueStatusCOTS, data.timeStamp, data.aglAlt, data.battery);
00286         ser->printf("Header: %d, %d, %d, %d, %d, %d, %d, %d\r\n",data.header[0], data.header[1], data.header[2], data.header[3], data.header[4], data.header[5], data.header[6], data.header[7]);
00287         */
00288         ser->printf("%d\r\n", sizeof(payload));
00289         ser->printf("%x\r\n", payload);
00290         
00291     }
00292         
00293 
00294 }
00295 
00296 void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
00297 {
00298     Radio->Sleep( );
00299     if(DEBUG_MESSAGE)
00300         ser->printf("> OnTxTimeout\r\n");
00301 }
00302 
00303 void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
00304 {
00305     Radio->Sleep( );
00306     if (DEBUG_MESSAGE)
00307         ser->printf("> OnRxTimeout\r\n");
00308 }
00309 
00310 void OnRxError(void *radio, void *userThisPtr, void *userData)
00311 {
00312     Radio->Sleep( );
00313     received = true;
00314     if (DEBUG_MESSAGE)
00315         ser->printf("> OnRxError\r\n");
00316 }