Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed LoRaWAN-lib SX1276Lib
Diff: app/main.cpp
- Revision:
- 10:f3b1186fc0b0
- Parent:
- 9:ee9dcbb9708d
- Child:
- 11:7a7913d47ca6
--- a/app/main.cpp Mon Apr 24 13:38:31 2017 +0000 +++ b/app/main.cpp Mon Oct 25 18:00:03 2021 +0000 @@ -18,7 +18,9 @@ #include "LoRaMac.h" #include "Commissioning.h" -#include "SerialDisplay.h" + +#include "Si7021.h" +#include "stm32l0xx_hal_iwdg.h" /*! * Defines the application data transmission duty cycle. 5s, value in [ms]. @@ -83,13 +85,7 @@ /*! * User application data buffer size */ -#if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) -#define LORAWAN_APP_DATA_SIZE 6 - -#else -#define LORAWAN_APP_DATA_SIZE 1 - -#endif +#define LORAWAN_APP_DATA_SIZE 7 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; @@ -143,28 +139,43 @@ static TimerEvent_t TxNextPacketTimer; /*! - * Specifies the state of the application LED - */ -static bool AppLedStateOn = false; -volatile bool Led3StateChanged = false; -/*! - * Timer to handle the state of LED1 - */ -static TimerEvent_t Led1Timer; -volatile bool Led1State = false; -volatile bool Led1StateChanged = false; -/*! - * Timer to handle the state of LED2 - */ -static TimerEvent_t Led2Timer; -volatile bool Led2State = false; -volatile bool Led2StateChanged = false; - -/*! * Indicates if a new packet can be sent */ static bool NextTx = true; +// Serial +Serial pc(SERIAL_TX, SERIAL_RX,115200); + +// Humidty&Temp Sensor +DigitalOut si7021_power_pin(PB_2); +Si7021 *si7021; + + +// I2C Definition +I2C i2c(PB_9, PB_8); //sda, scl + +IWDG_HandleTypeDef wd; +bool joining; +time_t current_time; +time_t last_rx; + +// Pressure + +// The amount of time between measurements (seconds) +#define MEASUREMENT_GAP_SECONDS 30 + +#define RAW_MEASUREMENT_BUFFER_SIZE 10 + +// The moving average of the avg measurement data +float average_pressure; + +// The raw pressure data of a single standard measurement +float raw_pressure_measurements[RAW_MEASUREMENT_BUFFER_SIZE] = {0}; +int raw_measurement_counter = 0; + +char single_measure_command[2] = {0x36, 0x2F}; +char reset_command[1] = {0x06}; + /*! * Device states */ @@ -177,6 +188,12 @@ DEVICE_STATE_SLEEP }DeviceState; +static enum eMessageType +{ + MESSAGE_TYPE_ACK, + MESSAGE_TYPE_READING +}MessageType; + /*! * LoRaWAN compliance tests support data */ @@ -232,54 +249,6 @@ }LoRaMacDownlinkStatus; volatile bool DownlinkStatusUpdated = false; -void SerialDisplayRefresh( void ) -{ - MibRequestConfirm_t mibReq; - - SerialDisplayInit( ); - SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); - -#if( OVER_THE_AIR_ACTIVATION == 0 ) - SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); - SerialDisplayUpdateDevAddr( DevAddr ); - SerialDisplayUpdateKey( 12, NwkSKey ); - SerialDisplayUpdateKey( 13, AppSKey ); -#endif - SerialDisplayUpdateEui( 5, DevEui ); - SerialDisplayUpdateEui( 6, AppEui ); - SerialDisplayUpdateKey( 7, AppKey ); - - mibReq.Type = MIB_NETWORK_JOINED; - LoRaMacMibGetRequestConfirm( &mibReq ); - SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); - - SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); -#if defined( USE_BAND_868 ) - SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); -#else - SerialDisplayUpdateDutyCycle( false ); -#endif - SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); - - SerialDisplayUpdateLedState( 3, AppLedStateOn ); -} - -void SerialRxProcess( void ) -{ - if( SerialDisplayReadable( ) == true ) - { - switch( SerialDisplayGetChar( ) ) - { - case 'R': - case 'r': - // Refresh Serial screen - SerialDisplayRefresh( ); - break; - default: - break; - } - } -} /*! * \brief Prepares the payload of the frame @@ -289,17 +258,40 @@ switch( port ) { case 15: - { - AppData[0] = AppLedStateOn; - if( IsTxConfirmed == true ) - { - AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8; - AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter; - AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8; - AppData[4] = LoRaMacDownlinkStatus.Rssi; - AppData[5] = LoRaMacDownlinkStatus.Snr; - } - } + { + switch ( MessageType ) + { + case MESSAGE_TYPE_ACK: + { + AppDataSize = 0; + IsTxConfirmed = false; + break; + } + case MESSAGE_TYPE_READING: + default: + { + AppDataSize = 7; + IsTxConfirmed = true; + + // Maximum +- 300 Pa + int16_t extended_pressure = (int16_t)(average_pressure * 100); + int16_t extended_humidity = (int16_t)(si7021->get_humidity() / 10); + int16_t extended_temp = (int16_t)(si7021->get_temperature() / 10); + pc.printf("Sending Pressure: %i\r\n", extended_pressure); + pc.printf("Sending Humidity: %i\r\n", extended_humidity); + pc.printf("Sending Temp: %i\r\n", extended_temp); + + AppData[0] = 0xA0; + AppData[1] = extended_pressure >> 8; + AppData[2] = extended_pressure; + AppData[3] = extended_humidity >> 8; + AppData[4] = extended_humidity; + AppData[5] = extended_temp >> 8; + AppData[6] = extended_temp; + break; + } + } + } break; case 224: if( ComplianceTest.LinkCheck == true ) @@ -353,7 +345,6 @@ LoRaMacUplinkStatus.Port = 0; LoRaMacUplinkStatus.Buffer = NULL; LoRaMacUplinkStatus.BufferSize = 0; - SerialDisplayUpdateFrameType( false ); } else { @@ -361,7 +352,6 @@ LoRaMacUplinkStatus.Port = AppPort; LoRaMacUplinkStatus.Buffer = AppData; LoRaMacUplinkStatus.BufferSize = AppDataSize; - SerialDisplayUpdateFrameType( IsTxConfirmed ); if( IsTxConfirmed == false ) { @@ -393,7 +383,7 @@ * \brief Function executed on TxNextPacket Timeout event */ static void OnTxNextPacketTimerEvent( void ) -{ +{ MibRequestConfirm_t mibReq; LoRaMacStatus_t status; @@ -417,28 +407,6 @@ } /*! - * \brief Function executed on Led 1 Timeout event - */ -static void OnLed1TimerEvent( void ) -{ - TimerStop( &Led1Timer ); - // Switch LED 1 OFF - Led1State = false; - Led1StateChanged = true; -} - -/*! - * \brief Function executed on Led 2 Timeout event - */ -static void OnLed2TimerEvent( void ) -{ - TimerStop( &Led2Timer ); - // Switch LED 2 OFF - Led2State = false; - Led2StateChanged = true; -} - -/*! * \brief MCPS-Confirm event function * * \param [IN] mcpsConfirm - Pointer to the confirm structure, @@ -475,11 +443,6 @@ LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate; LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter; - // Switch LED 1 ON - Led1State = true; - Led1StateChanged = true; - TimerStart( &Led1Timer ); - UplinkStatusUpdated = true; } NextTx = true; @@ -551,18 +514,15 @@ { ComplianceTest.DownLinkCounter++; } + + // Update timestamp for last rx + last_rx = current_time; if( mcpsIndication->RxData == true ) { switch( mcpsIndication->Port ) { - case 1: // The application LED can be controlled on port 1 or 2 - case 2: - if( mcpsIndication->BufferSize == 1 ) - { - AppLedStateOn = mcpsIndication->Buffer[0] & 0x01; - Led3StateChanged = true; - } + case 15: break; case 224: if( ComplianceTest.Running == false ) @@ -701,12 +661,6 @@ break; } } - - // Switch LED 2 ON for each received downlink - Led2State = true; - Led2StateChanged = true; - TimerStart( &Led2Timer ); - DownlinkStatusUpdated = true; } /*! @@ -725,7 +679,10 @@ { // Status is OK, node has joined the network IsNetworkJoinedStatusUpdate = true; + pc.printf("--- Joined ---\r\n"); DeviceState = DEVICE_STATE_SEND; + MessageType = MESSAGE_TYPE_READING; + joining = false; } else { @@ -756,66 +713,112 @@ UplinkStatusUpdated = true; } +void reset_pressure_sensor() { + // Reset the sensor + pc.printf("Resetting Sensor...\r\n"); + i2c.write(0x00, reset_command, 1); +} + +void measure_pressure() { + // Take a few manual measurements + pc.printf("Measuring...\r\n"); + i2c.write((0x25 << 1), single_measure_command, 2); +} + +float read_measurement() { + char output[9]; + + // Read measurements + i2c.read((0x25 << 1), output, 9); // read from register + + // Interpret + int16_t diffPressureTicks = (output[0] << 8) | output[1]; + // int16_t temperatureTicks = (output[3] << 8) | output[4]; + uint16_t scaleFactorDiffPressure = (output[6] << 8) | output[7]; + + float diffPressure = (float)diffPressureTicks / (float)scaleFactorDiffPressure; + + return diffPressure; +} + /** * Main application entry point. */ int main( void ) { + pc.printf("mbed-os-rev: %d.%d.%d lib-rev: %d\r\n", \ + MBED_MAJOR_VERSION, MBED_MINOR_VERSION,MBED_PATCH_VERSION,MBED_VERSION); + pc.printf("BUILD= %s, SysClock= %d\r\n", __TIME__, SystemCoreClock); + + pc.printf("CR= %X CSR= %X CFGR= %X PLL_HSE= %d\r\n", \ + RCC->CR, RCC->CSR, RCC->CFGR, (RCC->CFGR>>16)&(1)); + + wait(3); + + wd.Instance = IWDG; + wd.Init.Prescaler = IWDG_PRESCALER_256; //About 32s + wd.Init.Reload = 0x0FFF; + wd.Init.Window = 0x0FFF; + HAL_IWDG_Init(&wd); + + time_t start_time = time(NULL); + current_time = start_time; + last_rx = start_time; + time_t last_measure = start_time; + time_t measure_start = start_time; + joining = true; + + pc.printf("Starting Both Sensors..\r\n"); + + // set up SHT31 + si7021_power_pin = 1; + si7021 = new Si7021(PB_14, PB_13); + wait(1); + + si7021->measure(); + wait(1); + pc.printf("Temp: %d\r\n", si7021->get_temperature()); + pc.printf("Humidity: %d\r\n", si7021->get_humidity()); + + // set up pressure sensors + reset_pressure_sensor(); + + wait(0.1); + + measure_pressure(); + wait(0.1); + average_pressure = read_measurement(); + pc.printf("Pressure: %f\r\n", average_pressure); + + bool measuring = false; + + wait(5); + LoRaMacPrimitives_t LoRaMacPrimitives; LoRaMacCallback_t LoRaMacCallbacks; MibRequestConfirm_t mibReq; BoardInit( ); - SerialDisplayInit( ); - - SerialDisplayUpdateEui( 5, DevEui ); - SerialDisplayUpdateEui( 6, AppEui ); - SerialDisplayUpdateKey( 7, AppKey ); - -#if( OVER_THE_AIR_ACTIVATION == 0 ) - SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID ); - SerialDisplayUpdateDevAddr( DevAddr ); - SerialDisplayUpdateKey( 12, NwkSKey ); - SerialDisplayUpdateKey( 13, AppSKey ); -#endif DeviceState = DEVICE_STATE_INIT; while( 1 ) - { - SerialRxProcess( ); - if( IsNetworkJoinedStatusUpdate == true ) - { - IsNetworkJoinedStatusUpdate = false; - mibReq.Type = MIB_NETWORK_JOINED; - LoRaMacMibGetRequestConfirm( &mibReq ); - SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined ); - } - if( Led1StateChanged == true ) - { - Led1StateChanged = false; - SerialDisplayUpdateLedState( 1, Led1State ); + { + //Call to reset watchdog + HAL_IWDG_Refresh(&wd); + + current_time = time(NULL); // Update Time + + /* ---- Reset if joining for more than 3 hours ----- */ + if ((current_time - start_time > 10800) && joining) { + //Call to reset device + NVIC_SystemReset(); } - if( Led2StateChanged == true ) - { - Led2StateChanged = false; - SerialDisplayUpdateLedState( 2, Led2State ); - } - if( Led3StateChanged == true ) - { - Led3StateChanged = false; - SerialDisplayUpdateLedState( 3, AppLedStateOn ); - } - if( UplinkStatusUpdated == true ) - { - UplinkStatusUpdated = false; - SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize ); - } - if( DownlinkStatusUpdated == true ) - { - DownlinkStatusUpdated = false; - SerialDisplayUpdateLedState( 2, Led2State ); - SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize ); + + /* ---- Reset if no downlinks for more than 36 hours ----- */ + if ((current_time - last_rx > 129600) && !joining) { + //Call to reset device + NVIC_SystemReset(); } switch( DeviceState ) @@ -830,12 +833,6 @@ TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); - TimerInit( &Led1Timer, OnLed1TimerEvent ); - TimerSetValue( &Led1Timer, 25 ); - - TimerInit( &Led2Timer, OnLed2TimerEvent ); - TimerSetValue( &Led2Timer, 25 ); - mibReq.Type = MIB_ADR; mibReq.Param.AdrEnable = LORAWAN_ADR_ON; LoRaMacMibSetRequestConfirm( &mibReq ); @@ -843,10 +840,19 @@ mibReq.Type = MIB_PUBLIC_NETWORK; mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; LoRaMacMibSetRequestConfirm( &mibReq ); + + // Limiting to just 2nd subband of 8 channels + static uint16_t GatewayChannelsMask[] = {0x00FF, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000}; + mibReq.Type = MIB_CHANNELS_DEFAULT_MASK; + mibReq.Param.ChannelsDefaultMask = GatewayChannelsMask; + LoRaMacMibSetRequestConfirm( &mibReq ); + + mibReq.Type = MIB_CHANNELS_MASK; + mibReq.Param.ChannelsMask = GatewayChannelsMask; + LoRaMacMibSetRequestConfirm( &mibReq ); #if defined( USE_BAND_868 ) LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); - SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON ); #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); @@ -867,9 +873,6 @@ #endif #endif - SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION ); - SerialDisplayUpdateAdr( LORAWAN_ADR_ON ); - SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK ); LoRaMacDownlinkStatus.DownlinkCounter = 0; @@ -878,6 +881,8 @@ } case DEVICE_STATE_JOIN: { + pc.printf("--- Joining ---\r\n"); + #if( OVER_THE_AIR_ACTIVATION != 0 ) MlmeReq_t mlmeReq; @@ -922,32 +927,38 @@ { if( NextTx == true ) { - SerialDisplayUpdateUplinkAcked( false ); - SerialDisplayUpdateDonwlinkRxData( false ); PrepareTxFrame( AppPort ); NextTx = SendFrame( ); } - if( ComplianceTest.Running == true ) - { - // Schedule next packet transmission - TxDutyCycleTime = 5000; // 5000 ms - } - else - { - // Schedule next packet transmission - TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); - } DeviceState = DEVICE_STATE_CYCLE; break; } case DEVICE_STATE_CYCLE: { - DeviceState = DEVICE_STATE_SLEEP; + if (measuring) { + /* check if done measuring & swap to send state */ + if (current_time - measure_start > 0) { + average_pressure = read_measurement(); + pc.printf("Pressure: %f\r\n", average_pressure); + pc.printf("Temperature: %d\r\n", si7021->get_temperature()); + pc.printf("Humidity: %d\r\n", si7021->get_humidity()); + measuring = false; + DeviceState = DEVICE_STATE_SEND; + MessageType = MESSAGE_TYPE_READING; + } + } else { + // check if it's time to start measuring + if (current_time - last_measure > MEASUREMENT_GAP_SECONDS) { + // take a measurement + measure_start = current_time; + last_measure = current_time; + measuring = true; + measure_pressure(); + si7021->measure(); + } + } - // Schedule next packet transmission - TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); - TimerStart( &TxNextPacketTimer ); break; } case DEVICE_STATE_SLEEP: