RX
Dependencies: mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2
main.cpp
- Committer:
- TMRL123
- Date:
- 2019-06-05
- Revision:
- 0:674f1e460248
File content as of revision 0:674f1e460248:
#/* Includes */ #include "mbed.h" /* Mbed include */ /* Lora includes */ #include "PinMap.h" #include "sx1276-mbed-hal.h" /* Serial communication include */ #include "BufferedSerial.h" /* SD card includes */ #include "SDCard_Y.hh" /* Set this flag to display debug messages on the console */ #define DEBUG_MESSAGE /* Definition of the SD card */ #define SPI_FREQUENCY 1000000 /* Definition of the SD card */ //#define SD_EN /* LoRa definitions */ /* Set this flag to display debug messages on the console */ #define DEBUG_MESSAGE /* Set this flag to '1' to use the LoRa modulation */ #define USE_MODEM_LORA 1 #define USE_MODEM_FSK !USE_MODEM_LORA #define RF_FREQUENCY RF_FREQUENCY_915_0 // Hz #define TX_OUTPUT_POWER 14 // 20 dBm #if USE_MODEM_LORA == 1 #define LORA_BANDWIDTH 125000 // LoRa default, details in SX1276::BandwidthMap #define LORA_SPREADING_FACTOR LORA_SF7 #define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx #define LORA_SYMBOL_TIMEOUT 5 // Symbols #define LORA_FIX_LENGTH_PAYLOAD_ON false #define LORA_FHSS_ENABLED false #define LORA_NB_SYMB_HOP 4 #define LORA_IQ_INVERSION_ON false #define LORA_CRC_ENABLED true #endif #define RX_TIMEOUT_VALUE 0 // In ms #define TX_TIMEOUT_VALUE 1000000 // In ms typedef struct { /* Header for identification of updated informations */ bool header [8]; int time; // Time between transmissions int32_t ag[3]; // Acceleration of the accelerometer and gyroscope LSM6DSL int32_t w[3]; // Angular velocity of LSM6DSL int32_t a[3]; // Acceleration of the accelerometer LSM303AGR int32_t m [3]; // Heading of LSM303AGR float p; // Pressure of LPS22HB float temperatureLPS22HB; // Temperature from LPS22HB float humidity; // Humidity of HTS221 float temperatureHTS221; // Temperature from HTS221 unsigned long timeOfWeek; //GPS time of week long timeOfWeekFracPart; // GPS time of week fractional part unsigned char gpsFix; // GPS fix long ecefx; // GPS X posiition long ecefy; // GPS Y posistion long ecefz; // GPS Z postion unsigned long positionAcc3D; // GPS 3D position accuracy long ecefvx; // GPS X velocity long ecefvy; // GPS Y velocity long ecefvz; // GPS Z velocity unsigned long speedAcc; // GPS speed accuracy unsigned char numbSat; // GPS number of satellites conected bool drogueStatus; // Drogue parachute status provided by Avionics bool mainStatus; //Main parachute status provided by Avionics float pressureBar; // Pressure by COTS Altimeter float temperature; // Temperature by COTS Altimeter bool mainStatusCOTS; // Main parachute status provided by COTS Altimeter bool drogueStatusCOTS; // Drogue status provided by COTS Altimeter int16_t timeStamp; //Timestamp from COTS Altimeter int16_t aglAlt; //AGL Altitude from COTS Altimeter int8_t battery; //Battery voltage reading from COTS Altimeter }Data; // Data struct Data data; /* LoRa modem instances and configurations */ static RadioEvents_t RadioEvents; // Calback functions struct SX1276Generic *Radio; // Definition of a Radio object /* Configuration function */ void SystemClock_Config(void); bool received = false; // Flag to indicate the end of reception /* Callback functions prototypes */ // Brief Function to be executed on Radio Tx Done event void OnTxDone(void *radio, void *userThisPtr, void *userData); // Brief Function to be executed on Radio Rx Done event void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); // Brief Function executed on Radio Tx Timeout event void OnTxTimeout(void *radio, void *userThisPtr, void *userData); // Brief Function executed on Radio Rx Timeout event void OnRxTimeout(void *radio, void *userThisPtr, void *userData); // Brief Function executed on Radio Rx Error event void OnRxError(void *radio, void *userThisPtr, void *userData); // Brief Function executed on Radio Fhss Change Channel event void OnFhssChangeChannel(void *radio, void *userThisPtr, void *userData, uint8_t channelIndex); #ifdef DEBUG_MESSAGE /* Serial communication to debug program */ BufferedSerial *ser; #endif int main() { data.header [0] = 0; data.header [1] = 0; data.header [2] = 0; data.header [3] = 0; data.header [4] = 0; data.header [5] = 0; data.header [6] = 0; data.header [7] = 0; data.time = 0; data.ag[0] = 0; data.ag[1] = 0; data.ag[2] = 0; data.w[0] = 0; data.w[1] = 0; data.w[2] = 0; data.a[0] = 0; data.a[1] = 0; data.a[2] = 0; data.m [0] = 0; data.m [1] = 0; data.m [2] = 0; data.p = 0; data.temperatureLPS22HB = 0; data.humidity = 0; data.temperatureHTS221 = 0; data.timeOfWeek = 0; data.timeOfWeekFracPart = 0; data.gpsFix = 0; data.ecefx = 0; data.ecefy = 0; data.ecefz = 0; data.positionAcc3D = 0; data.ecefvx = 0; data.ecefvy = 0; data.ecefvz = 0; data.speedAcc = 0; data.numbSat = 0; data.drogueStatus = 0; data.mainStatus = 0; data.pressureBar = 0; data.temperature = 0; data.mainStatusCOTS = 0; data.drogueStatusCOTS = 0; data.timeStamp = 0; data.aglAlt = 0; data.battery = 0; SystemClock_Config(); /* Synchronize clock for TX and RX boards */ /* Serial configuration */ #ifdef DEBUG_MESSAGE ser = new BufferedSerial(USBTX, USBRX); ser->baud(115200); ser->format(8); #endif /* General Header*/ #ifdef DEBUG_MESSAGE ser->printf ("Telemetry Rx inicial version program\r\n\r\n"); #endif /* Radio setup */ #ifdef DEBUG_MESSAGE ser->printf("\r\n--- Starting the modem LoRa ---\r\n"); #endif Radio = new SX1276Generic(NULL, MURATA_SX1276, LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO); #ifdef DEBUG_MESSAGE ser->printf("SX1276 Simple transmission aplication\r\n" ); ser->printf("Frequency: %.1f\r\n", (double)RF_FREQUENCY/1000000.0); ser->printf("TXPower: %d dBm\r\n", TX_OUTPUT_POWER); ser->printf("Bandwidth: %d Hz\r\n", LORA_BANDWIDTH); ser->printf("Spreading factor: SF%d\r\n", LORA_SPREADING_FACTOR); #endif // Initialize Radio driver RadioEvents.TxDone = OnTxDone; RadioEvents.RxDone = OnRxDone; RadioEvents.RxError = OnRxError; RadioEvents.TxTimeout = OnTxTimeout; RadioEvents.RxTimeout = OnRxTimeout; for (int i = 0; Radio->Init( &RadioEvents ) == false && i < 40; i++) { #ifdef DEBUG_MESSAGE ser->printf("Radio could not be detected!\r\n"); #endif wait_ms(500); } // Display the board type #ifdef DEBUG_MESSAGE switch(Radio->DetectBoardType()) { case SX1276MB1LAS: ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); break; case SX1276MB1MAS: ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); break; case MURATA_SX1276: ser->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n"); break; case RFM95_SX1276: ser->printf(" > HopeRF RFM95xx <\r\n"); break; default: ser->printf(" > Board Type: unknown <\r\n"); } #endif Radio->SetChannel(RF_FREQUENCY ); // Sets the frequency of the communication // Debug message of the state of fhss #ifdef DEBUG_MESSAGE if (LORA_FHSS_ENABLED) { ser->printf(" > LORA FHSS Mode <\r\n"); } if (!LORA_FHSS_ENABLED) { ser->printf(" > LORA Mode <\r\n"); } #endif // Sets the configuration of the transmission 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, 2000 ); // Sets the configuration of the reception 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 ); #ifdef SD_EN SPI spi (PA_7, PA_6, PA_5); spi.frequency (SPI_FREQUENCY); SDCard sdCard (&spi, PB_10); uint8_t sdData[sizeof(data)]; int block = 0; #endif Radio->Rx(RX_TIMEOUT_VALUE); // Puts the device in reception mode continuously while( 1 ) { //After the receiving, puts the device again in receive mode if (received == true) { #ifdef SD_EN // Saving the data on SD Card memcpy (sdData, &data, sizeof(data)); while(sdCard.write(&sdData[0],block) == 0); block ++; while (sdCard.write (&sdData[64],block) == 0); block++; while (sdCard.write(&sdData[128],block) == 0); block++; #endif #ifdef DEBUG_MESSAGE ser->printf("I received %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]); 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); 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); 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); 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); 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); 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); 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]); #endif received = false; Radio->Rx(RX_TIMEOUT_VALUE); } } } void SystemClock_Config(void) { #ifdef B_L072Z_LRWAN1_LORA /* * The L072Z_LRWAN1_LORA clock setup is somewhat differnt from the Nucleo board. * It has no LSE. */ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitTypeDef RCC_OscInitStruct = {0}; /* Enable HSE Oscillator and Activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6; RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { // Error_Handler(); } /* Set Voltage scale1 as MCU will run at 32MHz */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */ while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {}; /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { // Error_Handler(); } #endif } void OnTxDone(void *radio, void *userThisPtr, void *userData) { Radio->Sleep( ); #ifdef DEBUG_MESSAGE ser->printf("> OnTxDone\r\n"); #endif } void OnTxTimeout(void *radio, void *userThisPtr, void *userData) { Radio->Sleep( ); #ifdef DEBUG_MESSAGE ser->printf("> OnTxTimeout\r\n"); #endif } void OnRxTimeout(void *radio, void *userThisPtr, void *userData) { Radio->Sleep( ); #ifdef DEBUG_MESSAGE ser->printf("> OnRxTimeout\r\n"); #endif } void OnRxError(void *radio, void *userThisPtr, void *userData) { Radio->Sleep( ); received = true; #ifdef DEBUG_MESSAGE ser->printf("> OnRxError\r\n"); #endif } void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { Radio->Sleep( ); received = true; memcpy(&data, payload, sizeof(data)); /* #ifdef DEBUG_MESSAGE ser->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\r\n", rssi, snr); ser->printf("I received %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]); 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); 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); 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); 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); 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); 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); 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]); #endif */ }