RX
Dependencies: mbed BufferedSerial SX1276GenericLib X_NUCLEO_IKS01A2
Diff: main.cpp
- Revision:
- 0:fb7bf6d81e5f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jun 05 00:25:53 2019 +0000 @@ -0,0 +1,316 @@ +/* Includes */ +#include "mbed.h" /* Mbed include */ + +/* Lora includes */ +#include "PinMap.h" +#include "sx1276-mbed-hal.h" + +/* Serial communication include */ +#include "BufferedSerial.h" + +/* Set this flag to '1' to display debug messages on the console */ +#define DEBUG_MESSAGE 1 + +/* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK 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 // 14 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 + +//#define BUFFER_SIZE 32 // Define the payload size here +#define BUFFER_SIZE 64 // Define the payload size here + +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 + +bool received = false; // Flag to indicate the end of reception + +/* Configuration function */ +void SystemClock_Config(void); + +/* 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); + +// Brief Function executed on CAD Done event +void OnCadDone(void *radio, void *userThisPtr, void *userData); + +/* Serial communication to debug program */ +BufferedSerial *ser; + +int main() { + SystemClock_Config(); /* Synchronize clock for TX and RX boards */ + + /* Serial configuration */ + if (DEBUG_MESSAGE) { + ser = new BufferedSerial(USBTX, USBRX); + ser->baud(115200); + ser->format(8); + } + + /* General Header*/ + if (DEBUG_MESSAGE) + ser->printf("Telemetry Rx inicial version program\r\n\r\n"); + + 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); + + if (DEBUG_MESSAGE) { + ser->printf("SX1276 Simple receiver 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); + } + + // Initialize Radio driver + RadioEvents.TxDone = OnTxDone; + RadioEvents.RxDone = OnRxDone; + RadioEvents.RxError = OnRxError; + RadioEvents.TxTimeout = OnTxTimeout; + RadioEvents.RxTimeout = OnRxTimeout; + + // Initializes the radio + while (Radio->Init( &RadioEvents ) == false) { + if (DEBUG_MESSAGE) + ser->printf("Radio could not be detected!\r\n"); + wait( 1 ); + } + + // Display the board type + switch(Radio->DetectBoardType()) { + case SX1276MB1LAS: + if (DEBUG_MESSAGE) + ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); + break; + case SX1276MB1MAS: + if (DEBUG_MESSAGE) + ser->printf(" > Board Type: SX1276MB1LAS <\r\n"); + case MURATA_SX1276: + if (DEBUG_MESSAGE) + ser->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n"); + break; + case RFM95_SX1276: + if (DEBUG_MESSAGE) + ser->printf(" > HopeRF RFM95xx <\r\n"); + break; + default: + if (DEBUG_MESSAGE) + ser->printf(" > Board Type: unknown <\r\n"); + } + + Radio->SetChannel(RF_FREQUENCY ); // Sets the frequency of the communication + + // Debug message of the state of fhss + if (LORA_FHSS_ENABLED) { + if (DEBUG_MESSAGE) + ser->printf(" > LORA FHSS Mode <\r\n"); + } + if (!LORA_FHSS_ENABLED) { + if (DEBUG_MESSAGE) + ser->printf(" > LORA Mode <\r\n"); + } + // 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 ); + if (DEBUG_MESSAGE) + ser->printf("Starting Receive loop\r\n"); + + 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) { + 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( ); + if (DEBUG_MESSAGE) + ser->printf("> OnTxDone\r\n"); +} + +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)); + if (DEBUG_MESSAGE) { + /* + ser->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\r\n", rssi, snr); + 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]); + 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]); + */ + ser->printf("%d\r\n", sizeof(payload)); + ser->printf("%x\r\n", payload); + + } + + +} + +void OnTxTimeout(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + if(DEBUG_MESSAGE) + ser->printf("> OnTxTimeout\r\n"); +} + +void OnRxTimeout(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + if (DEBUG_MESSAGE) + ser->printf("> OnRxTimeout\r\n"); +} + +void OnRxError(void *radio, void *userThisPtr, void *userData) +{ + Radio->Sleep( ); + received = true; + if (DEBUG_MESSAGE) + ser->printf("> OnRxError\r\n"); +} \ No newline at end of file