int main( void ) { HAL_EnableDBGStopMode(); LowPowerConfiguration(); pc.baud(115200); // print banner pc.printf("\r\n============== DEBUG STARTED ==============\r\n"); /** User button triggers the ultrasonic sensor */ //PinDetect button(PC_13,PullUp); //button.attach_asserted(&sensor, &UltraSonic::triggerSample); // callback routine to trigger usonic //button.setSampleFrequency(); LoRaMacPrimitives_t LoRaMacPrimitives; LoRaMacCallback_t LoRaMacCallbacks; MibRequestConfirm_t mibReq; //BoardInitMcu( ); //BoardInitPeriph( ); BoardInit( ); TimerInit( &mainLoopTimeout, onMainLoopTimeoutEvent ); DeviceState = DEVICE_STATE_INIT; while( 1 ) { wait(0.5); // This is a kind of watchdog on the main loop, if the timer isn't cancelled in x seconds then loop will enter INIT state TimerSetValue( &mainLoopTimeout, 3000000 ); TimerStart( &mainLoopTimeout ); switch( DeviceState ) { case DEVICE_STATE_INIT: { pc.printf("DEVICE_STATE_INIT\r\n"); LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; LoRaMacPrimitives.MacMcpsIndication = McpsIndication; LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); TimerInit( &ultrasonicTimer, OnUltrasonicTimeout ); mibReq.Type = MIB_ADR; mibReq.Param.AdrEnable = LORAWAN_ADR_ON; LoRaMacMibSetRequestConfirm( &mibReq ); // MAC information base service to set attributes of LoRaMac layer mibReq.Type = MIB_PUBLIC_NETWORK; mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; LoRaMacMibSetRequestConfirm( &mibReq ); sensor.distanceAvailable = false; // Ensure initialised to false after power up DeviceState = DEVICE_STATE_JOIN; break; } case DEVICE_STATE_JOIN: { pc.printf("DEVICE_STATE_JOIN\r\n"); #if( OVER_THE_AIR_ACTIVATION != 0 ) pc.printf("OTA\r\n"); MlmeReq_t mlmeReq; // Initialize LoRaMac device unique ID //BoardGetUniqueId( DevEui ); mlmeReq.Type = MLME_JOIN; // MAC management service types are MLME_JOIN or MLME_LINK_CHECK mlmeReq.Req.Join.DevEui = DevEui; mlmeReq.Req.Join.AppEui = AppEui; mlmeReq.Req.Join.AppKey = AppKey; if( NextTx == true ) { LoRaMacMlmeRequest( &mlmeReq ); // Sends a join request } // Schedule next packet transmission //TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE; //DeviceState = DEVICE_STATE_CYCLE; DeviceState = DEVICE_STATE_CYCLE; #else pc.printf("ABP\r\n"); // Choose a random device address if not already defined in Comissioning.h if( DevAddr == 0 ) { // Random seed initialization // srand1( BoardGetRandomSeed( ) ); // Choose a random device address DevAddr = randr( 0, 0x01FFFFFF ); } mibReq.Type = MIB_NET_ID; mibReq.Param.NetID = LORAWAN_NETWORK_ID; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_DEV_ADDR; mibReq.Param.DevAddr = DevAddr; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NWK_SKEY; mibReq.Param.NwkSKey = NwkSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_APP_SKEY; mibReq.Param.AppSKey = AppSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NETWORK_JOINED; mibReq.Param.IsNetworkJoined = true; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_SEND; #endif break; } case DEVICE_STATE_SEND: { pc.printf("DEVICE_STATE_SEND\r\n"); if( NextTx == true ) { pc.printf("Sending\r\n"); PrepareTxFrame( AppPort ); NextTx = SendFrame( ); } } case DEVICE_STATE_CYCLE: { pc.printf("DEVICE_STATE_CYCLE\r\n"); pc.printf("SensorState = %d, distanceAvailable = ",SensorState); if (sensor.distanceAvailable) pc.printf("true\r\n"); else pc.printf("false\r\n"); pc.printf("LoRaMacState = %d\r\n",GetMacStatus()); if ((SensorState == SENT) || (SensorState == INIT)) { /** Range and Temperature readings have been sent so we can sleep */ TimerStop( &TxNextPacketTimer ); // Wait for MAC state to become idle before deep sleeping if (GetMacStatus() == 0) { // Ensure MAC state is idle before sleeping pc.printf("DeepSleep ..zzz.\r\n"); TimerStop(&mainLoopTimeout); // cancel main loop guard timeout WakeUp::set(DEEPSLEEP_SECONDS); // Set RTC alarm to wake up from deep sleep LowPowerPrep(); deepsleep(); // Deep sleep until wake up alarm from RTC LowPowerRestore(); SensorState = TRIGGERED; /* Trigger ultrasonic sensor and start sensor read failure timer */ sensor.triggerSample(); // Get Ultrasonic reading TimerSetValue( &ultrasonicTimer, 2000000 ); // 2s timeout TimerStart( &ultrasonicTimer ); DeviceState = DEVICE_STATE_SLEEP; // Cycle in sleep until sensor readings ready } else { // Cycle around until MAC state is idle DeviceState = DEVICE_STATE_CYCLE; } } else { // Error shouldn't get here pc.printf("Error State!!\r\n"); //TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); //TimerStart( &TxNextPacketTimer ); SensorState = INIT; DeviceState = DEVICE_STATE_SLEEP; } break; } case DEVICE_STATE_SLEEP: { pc.printf("DEVICE_STATE_SLEEP\r\n"); // Loop until sensor ready if ((SensorState == TRIGGERED) && (sensor.distanceAvailable)) { pc.printf("Xmit Reading..!\r\n"); TimerStop( &ultrasonicTimer ); // stop the sensor failure timer SensorState = SENDING; TimerSetValue( &TxNextPacketTimer, 10 ); // Schedule immediate transmission TimerStart( &TxNextPacketTimer ); } break; } default: { DeviceState = DEVICE_STATE_INIT; break; } } } }
/** * Main application entry point. */ int main( void ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) uint8_t sendFrameStatus = 0; #endif bool trySendingFrameAgain = false; // float tempLightValue = 0; // LightMode = 0; // 0: manual, 1: automatic buzzer = 0; // 0: OFF, 1: ON bar.setLevel(0); debug( "\n\n\r LoRaWAN Class A Demo code \n\n\r" ); BoardInitMcu( ); BoardInitPeriph( ); // Initialize LoRaMac device unique ID BoardGetUniqueId( DevEui ); LoRaMacEvents.MacEvent = OnMacEvent; LoRaMacInit( &LoRaMacEvents ); IsNetworkJoined = false; #if( OVER_THE_AIR_ACTIVATION == 0 ) // Random seed initialization srand( RAND_SEED ); // Choose a random device address // NwkID = 0 // NwkAddr rand [0, 33554431] if( ( DevAddr == 0 ) || ( DevAddr == 0xFFFFFFFF ) ) { // Generate random DevAddr if it does not exist debug("Generate random DevAddr\n\r"); DevAddr = randr( 0, 0x01FFFFFF ); } debug( "- DevAddr = 0x%x\n\r" , DevAddr); LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey ); IsNetworkJoined = true; #endif TxNextPacket = true; LoRaMacSetAdrOn( false ); LoRaMacSetDutyCycleOn( false ); while( 1 ) { while( IsNetworkJoined == false ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) if( TxNextPacket == true ) { TxNextPacket = false; sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey ); debug("Req Sent\n\r"); switch( sendFrameStatus ) { case 1: // BUSY break; case 0: // OK case 2: // NO_NETWORK_JOINED case 3: // LENGTH_PORT_ERROR case 4: // MAC_CMD_ERROR case 6: // DEVICE_OFF default: // Relaunch timer for next trial JoinReqTimer.attach_us( &OnJoinReqTimerEvent, OVER_THE_AIR_ACTIVATION_DUTYCYCLE ); break; } } // TimerLowPowerHandler( ); #endif } if( TxDone == true ) { TxDone = false; debug( "TxDone \n\n\r" ); // Schedule next packet transmission TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); TxNextPacketTimer.attach_us( &OnTxNextPacketTimerEvent, TxDutyCycleTime ); } if( trySendingFrameAgain == true ) { trySendingFrameAgain = SendFrame( ); } if( TxNextPacket == true ) { TxNextPacketTimer.detach( ); TxNextPacket = false; PrepareTxFrame( AppPort ); trySendingFrameAgain = SendFrame( ); } /* Read light sensor tempLightValue = LightSens.read( ) * 1.65; LightValue = ( 1 - tempLightValue ); // Set automatic RGB from light sensor if( LightMode == 0 ) { color_led.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) ); }*/ // TimerLowPowerHandler( ); } }
/** * Main application entry point. */ int main( void ) { LoRaMacPrimitives_t LoRaMacPrimitives; LoRaMacCallback_t LoRaMacCallbacks; MibRequestConfirm_t mibReq; BoardInitMcu( ); BoardInitPeriph( ); DeviceState = DEVICE_STATE_INIT; while( 1 ) { switch( DeviceState ) { case DEVICE_STATE_INIT: { LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; LoRaMacPrimitives.MacMcpsIndication = McpsIndication; LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; LoRaMacPrimitives.MacMlmeIndication = MlmeIndication; LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, ACTIVE_REGION ); 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 ); mibReq.Type = MIB_PUBLIC_NETWORK; mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; LoRaMacMibSetRequestConfirm( &mibReq ); #if defined( REGION_EU868 ) LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); #endif mibReq.Type = MIB_DEVICE_CLASS; mibReq.Param.Class = CLASS_C; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_JOIN; break; } case DEVICE_STATE_JOIN: { #if( OVER_THE_AIR_ACTIVATION != 0 ) MlmeReq_t mlmeReq; // Initialize LoRaMac device unique ID BoardGetUniqueId( DevEui ); mlmeReq.Type = MLME_JOIN; mlmeReq.Req.Join.DevEui = DevEui; mlmeReq.Req.Join.AppEui = AppEui; mlmeReq.Req.Join.AppKey = AppKey; mlmeReq.Req.Join.Datarate = LORAWAN_DEFAULT_DATARATE; if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK ) { DeviceState = DEVICE_STATE_SLEEP; } else { DeviceState = DEVICE_STATE_CYCLE; } #else // Choose a random device address if not already defined in Commissioning.h if( DevAddr == 0 ) { // Random seed initialization srand1( BoardGetRandomSeed( ) ); // Choose a random device address DevAddr = randr( 0, 0x01FFFFFF ); } mibReq.Type = MIB_NET_ID; mibReq.Param.NetID = LORAWAN_NETWORK_ID; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_DEV_ADDR; mibReq.Param.DevAddr = DevAddr; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NWK_SKEY; mibReq.Param.NwkSKey = NwkSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_APP_SKEY; mibReq.Param.AppSKey = AppSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NETWORK_JOINED; mibReq.Param.IsNetworkJoined = true; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_SEND; #endif break; } case DEVICE_STATE_SEND: { if( NextTx == true ) { 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; // Schedule next packet transmission TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); TimerStart( &TxNextPacketTimer ); break; } case DEVICE_STATE_SLEEP: { // Wake up through events TimerLowPowerHandler( ); // Process Radio IRQ Radio.IrqProcess( ); break; } default: { DeviceState = DEVICE_STATE_INIT; break; } } } }