Demonstration of Class-A LoRaWAN device using NAMote-72

Dependencies:   LoRaWAN-lib mbed lib_mpl3115a2 lib_mma8451q lib_gps SX1272Lib

Dependents:   LoRaWAN-NAMote72-BVS-confirmed-tester-0-7v1_copy

LoRaWAN-NAMote72 Application Demo is a Class-A device example project using LoRaWAN-lib and SX1272Lib libraries.

This project is compliant with LoRaWAN V1.0.1 specification.

Comissioning.h (LoRaWAN Network Configuration)

The end-device can be activated in one of the two ways:

Over the Air (OTA) activation can be enabled as shown in the figure below. /media/uploads/ubhat/ota_enable.png

The end-device must be configured with the following parameters:

  • LORAWAN_DEVICE_EUI (8 Bytes) : Fist 3 Bytes is the Organizationally Unique Identifier (OUI) followed by 5 bytes of unique ID. If not defined by user, then the firmware automatically assigns one to the end-device
  • LORAWAN_APPLICATION_EUI (8 Bytes)
  • LORAWAN_APPLICATION_KEY (or DEVKEY) (16 Bytes)

/media/uploads/ubhat/ota_eui.png

Activation by Personalization (ABP) can be enabled as shown in the figure below. /media/uploads/ubhat/abp_enable.png

The end-device must be configured with the following parameters:

  • LORAWAN_DEVICE_ADDRESS (4 Bytes) : If not defined by user, then the firmware automatically assigns one to the end-device
  • LORAWAN_NWKSKEY (16 Bytes)
  • LORAWAN_APPSKEY (16 Bytes)

/media/uploads/ubhat/abp_key.png

Config.h (LoRaWAN Communication Parameters)

  • Mode of Operation : Hybrid If the end-device needs to be configured to operate over 8-channels, then Hybrid Mode needs to be enabled /media/uploads/ubhat/hybridenable.png
  • Mode of Operation : Frequency Hop If the end-device needs to be configured to operate over 64-channels, then Hybrid Mode needs to be disabled
  • Delay between successive JOIN REQUESTs : The delay between successive Join Requests (until the end-device joins the network) can be configured using the parameter OVER_THE_AIR_ACTIVATION_DUTYCYCLE
  • Inter-Frame Delay : One can change the delay between each frame transmission using APP_TX_DUTYCYCLE It is advisable that APP_TX_DUTYCYCLE is greater than or equal to 3sec.
  • Data Rate : The data rate can be configured as per LoRaWAN specification using the paramter LORAWAN_DEFAULT_DATARATE. The range of values are DR_0, DR_1, DR_2, DR_3 and DR_4
  • Confirmed/Unconfirmed Messages : The uplink message or payload can be chosen to be confirmed or unconfirmed using the parameter LORAWAN_CONFIRMED_MSG_ON. When set to 1, the transmitted messages need to be confirmed with an ACK by the network server in the subsequent RX window. When set to 0, no ACK is requested.
  • ADR ON/OFF : The ADR can be enabled or disabled using the parameter LORAWAN_ADR_ON. When set to 1, ADR is enabled and disabled when set to 0.
  • Application Port : The application port can be set using parameter LORAWAN_APP_PORT.
  • Payload Length : The lenght of the payload (in bytes) to be transmitted can be configured using LORAWAN_APP_DATA_SIZE
  • Transmit Power : The transmit power can be configured using LORAWAN_TX_POWER (LoRaMAC verifies if the set power is compliant with the LoRaWAN spec and FCC guidelines)

/media/uploads/ubhat/loraconfig.png

Main.cpp (Device State Machine)

The end-device state machine is defined.

  • Initial State : Device is initialized.
  • Join State : For OTA, Join Request is transmitted to the network until Join Accept is received by the end-device. Join event function is called that sets Red LED ON.
  • Send State : Transmit payload frame is prepared. Tx event is called that blinks the Red LED indicating uplink transmission.
  • Cycle State : Next packet transmission is scheduled

LoRaEventProc.cpp (Events and On-board Application)

Define events during Join, Tx & Rx. Prepare TX packet by appending with appropriate application data.

/media/uploads/ubhat/lora_events.png

  • PrepareLoRaFrame(uint8_t port ) : Prepare LoRa payload frame with on-board application data such as GPS, Temperature, Battery, etc. LoRa.ApplicationCall(AppType ) calls application AppType defined in LoRaApp.cpp. AppType is defined in LoRaApp.h

/media/uploads/ubhat/lora_app.png

LoRaApp.cpp

User-defined applications such as GPS, Temp, Accelerometer, LED indications etc. Event based actions such as LED blink on Tx, LED toggle on downlink etc /media/uploads/ubhat/apptype.png

LoRaDeviceStateProc.cpp

Process function calls corresponding to different Device states /media/uploads/ubhat/device_state.png

LoRaMacLayerService.cpp

Define MAC Layer Services: MLME & MCPS

Serial Terminal Display

By using a serial port connection using applications such as teraterm or putty, one can view the status of the End-Device. Once the End-Device Joins the network, transmission parameters such as payload data, application port, message type etc. are displayed on the terminal.

/media/uploads/ubhat/serial.png

Default Application Payload

This application defaults to sending uplink data to logical port 5. The application payload consists of: /media/uploads/jknapp_smtc/payload.png

Sample Application Payload Calculation for Longitude/Latitude

Payload => 00 19 F6 352BBA A94C20 FFFF

Temperature Calculation

19H => 2510

Temp = 25/2 = 12.5 oC

Battery Level

FFH => 100 %

F6H => 96.5 %

Longitude Calculation

longitude = A94C20H => 1109507210

longitudinal coordinate = -360 + (longitude10 x 180/(223))

longitudinal coordinate = -121.93

Latitude Calculation

latitude = 352BBAH = 348460210

latitude coordinate = (latitude10 x 90/(223-1))

latitude coordinate = 37.39

Committer:
ubhat
Date:
Wed Jun 08 22:39:27 2016 +0000
Revision:
7:92f4f419f91f
Parent:
6:f8194e691dd4
Child:
13:6b6f4be13633
Added transmit-on-orientation demo (App Port 12)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ubhat 0:69f2e28d12c1 1 /*
ubhat 0:69f2e28d12c1 2 / _____) _ | |
ubhat 0:69f2e28d12c1 3 ( (____ _____ ____ _| |_ _____ ____| |__
ubhat 0:69f2e28d12c1 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
ubhat 0:69f2e28d12c1 5 _____) ) ____| | | || |_| ____( (___| | | |
ubhat 0:69f2e28d12c1 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
ubhat 0:69f2e28d12c1 7 (C)2015 Semtech
ubhat 0:69f2e28d12c1 8
ubhat 0:69f2e28d12c1 9 Description: User-defined applications such as GPS, Temp, Accelerometer, LED indications etc.
ubhat 0:69f2e28d12c1 10 Event based actions such as LED blink on Tx, LED toggle on downlink etc
ubhat 0:69f2e28d12c1 11
ubhat 0:69f2e28d12c1 12 License: Revised BSD License, see LICENSE.TXT file include in the project
ubhat 0:69f2e28d12c1 13
ubhat 0:69f2e28d12c1 14 Maintainer: Uttam Bhat
ubhat 0:69f2e28d12c1 15 */
ubhat 0:69f2e28d12c1 16
ubhat 0:69f2e28d12c1 17 #include "LoRaApp.h"
ubhat 0:69f2e28d12c1 18
ubhat 7:92f4f419f91f 19 bool VerticalStatus = false;
ubhat 7:92f4f419f91f 20
ubhat 0:69f2e28d12c1 21 /*!
ubhat 0:69f2e28d12c1 22 * Red LED timer event
ubhat 0:69f2e28d12c1 23 */
ubhat 0:69f2e28d12c1 24 TimerLed RedLedTimer( Red );
ubhat 0:69f2e28d12c1 25
ubhat 0:69f2e28d12c1 26 /*!
ubhat 0:69f2e28d12c1 27 * Yellow LED timer event
ubhat 0:69f2e28d12c1 28 */
ubhat 0:69f2e28d12c1 29 TimerLed YellowLedTimer( Yellow );
ubhat 0:69f2e28d12c1 30
ubhat 0:69f2e28d12c1 31 /*!
ubhat 0:69f2e28d12c1 32 * Green LED timer event
ubhat 0:69f2e28d12c1 33 */
ubhat 0:69f2e28d12c1 34 TimerLed GreenLedTimer( Green );
ubhat 0:69f2e28d12c1 35
ubhat 0:69f2e28d12c1 36 Application::Application( uint8_t * memptr )
ubhat 0:69f2e28d12c1 37 {
ubhat 0:69f2e28d12c1 38 BuffAddr = memptr;
ubhat 0:69f2e28d12c1 39 memset( BuffAddr, 0, LORAWAN_APP_DATA_MAX_SIZE );
ubhat 6:f8194e691dd4 40 BuffPtr = 0;
ubhat 0:69f2e28d12c1 41 }
ubhat 0:69f2e28d12c1 42
ubhat 0:69f2e28d12c1 43 Application::~Application( )
ubhat 0:69f2e28d12c1 44 {
ubhat 0:69f2e28d12c1 45 }
ubhat 0:69f2e28d12c1 46
ubhat 0:69f2e28d12c1 47 void Application::ApplicationAppendData( uint8_t *pData, uint8_t len )
ubhat 0:69f2e28d12c1 48 {
ubhat 0:69f2e28d12c1 49 memcpy( BuffAddr + BuffPtr, pData, len );
ubhat 0:69f2e28d12c1 50 BuffPtr += len;
ubhat 0:69f2e28d12c1 51 }
ubhat 0:69f2e28d12c1 52
ubhat 0:69f2e28d12c1 53 void Application::ApplicationPtrPos( uint8_t ptrPos )
ubhat 0:69f2e28d12c1 54 {
ubhat 0:69f2e28d12c1 55 BuffPtr = ptrPos;
ubhat 0:69f2e28d12c1 56 }
ubhat 0:69f2e28d12c1 57
ubhat 0:69f2e28d12c1 58 void Application::ApplicationCall( eAppType App )
ubhat 0:69f2e28d12c1 59 {
ubhat 0:69f2e28d12c1 60 switch( App )
ubhat 0:69f2e28d12c1 61 {
ubhat 0:69f2e28d12c1 62 // Appends 8 Bytes (3 bytes longitude, 3 bytes latitude, 2 bytes altitude) to TX buffer
ubhat 0:69f2e28d12c1 63 case AppGps:
ubhat 0:69f2e28d12c1 64 {
ubhat 0:69f2e28d12c1 65 Gps.service( );
ubhat 0:69f2e28d12c1 66
ubhat 0:69f2e28d12c1 67 uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude );
ubhat 0:69f2e28d12c1 68
ubhat 0:69f2e28d12c1 69 if( ( BuffPtr + 8 ) <= LORAWAN_APP_DATA_SIZE )
ubhat 0:69f2e28d12c1 70 {
ubhat 0:69f2e28d12c1 71 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 16 ) & 0xFF;
ubhat 0:69f2e28d12c1 72 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 8 ) & 0xFF;
ubhat 0:69f2e28d12c1 73 BuffAddr[BuffPtr++] = Gps.LatitudeBinary & 0xFF;
ubhat 0:69f2e28d12c1 74 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 16 ) & 0xFF;
ubhat 0:69f2e28d12c1 75 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 8 ) & 0xFF;
ubhat 0:69f2e28d12c1 76 BuffAddr[BuffPtr++] = Gps.LongitudeBinary & 0xFF;
ubhat 0:69f2e28d12c1 77 BuffAddr[BuffPtr++] = ( altitudeGps >> 8 ) & 0xFF;
ubhat 0:69f2e28d12c1 78 BuffAddr[BuffPtr++] = altitudeGps & 0xFF;
ubhat 0:69f2e28d12c1 79 }
ubhat 0:69f2e28d12c1 80 break;
ubhat 0:69f2e28d12c1 81 }
ubhat 0:69f2e28d12c1 82
ubhat 0:69f2e28d12c1 83 // Appends 1 Byte to TX buffer
ubhat 0:69f2e28d12c1 84 case AppTemp:
ubhat 0:69f2e28d12c1 85 {
ubhat 0:69f2e28d12c1 86 Mpl3115a2.ReadTemperature( );
ubhat 0:69f2e28d12c1 87 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE )
ubhat 0:69f2e28d12c1 88 {
ubhat 7:92f4f419f91f 89 BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 °C
ubhat 0:69f2e28d12c1 90 }
ubhat 0:69f2e28d12c1 91 break;
ubhat 0:69f2e28d12c1 92 }
ubhat 0:69f2e28d12c1 93
ubhat 0:69f2e28d12c1 94 // Appends 1 Byte to TX buffer
ubhat 0:69f2e28d12c1 95 case AppBat:
ubhat 0:69f2e28d12c1 96 {
ubhat 0:69f2e28d12c1 97 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE )
ubhat 0:69f2e28d12c1 98 {
ubhat 0:69f2e28d12c1 99 BuffAddr[BuffPtr++] = BoardGetBatteryLevel( ); // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A
ubhat 0:69f2e28d12c1 100 }
ubhat 0:69f2e28d12c1 101 break;
ubhat 0:69f2e28d12c1 102 }
ubhat 0:69f2e28d12c1 103
ubhat 0:69f2e28d12c1 104 // Appends incremental values of 1 Byte each to TX buffer until Full
ubhat 0:69f2e28d12c1 105 case AppRamp:
ubhat 0:69f2e28d12c1 106 {
ubhat 0:69f2e28d12c1 107 int32_t i, j;
ubhat 0:69f2e28d12c1 108
ubhat 0:69f2e28d12c1 109 // Populate Tx Buffer with increasing byte values starting from 0x00, 0x01, 0x02 ...
ubhat 0:69f2e28d12c1 110 for( i = BuffPtr, j = 0; i < LORAWAN_APP_DATA_SIZE; i++ )
ubhat 0:69f2e28d12c1 111 {
ubhat 0:69f2e28d12c1 112 BuffAddr[i] = j++;
ubhat 0:69f2e28d12c1 113 }
ubhat 0:69f2e28d12c1 114 BuffPtr = LORAWAN_APP_DATA_SIZE;
ubhat 0:69f2e28d12c1 115 break;
ubhat 0:69f2e28d12c1 116 }
ubhat 0:69f2e28d12c1 117
ubhat 0:69f2e28d12c1 118 // Appends 2 Bytes to TX buffer
ubhat 0:69f2e28d12c1 119 case AppAccl:
ubhat 0:69f2e28d12c1 120 {
ubhat 0:69f2e28d12c1 121 uint8_t statusReg;
ubhat 0:69f2e28d12c1 122
ubhat 0:69f2e28d12c1 123 // Read the PS_STATUS register
ubhat 0:69f2e28d12c1 124 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
ubhat 0:69f2e28d12c1 125
ubhat 0:69f2e28d12c1 126 /* Display Orientation of NAMote on Serial Port */
ubhat 0:69f2e28d12c1 127 SerialAcclMetrDisplay( statusReg );
ubhat 0:69f2e28d12c1 128
ubhat 0:69f2e28d12c1 129 // If Orientation of the Mote changed then let Green LED ON
ubhat 0:69f2e28d12c1 130 if( ( statusReg & 0x80 ) != 0 )
ubhat 0:69f2e28d12c1 131 {
ubhat 0:69f2e28d12c1 132 AppLed = 1;
ubhat 0:69f2e28d12c1 133 CtrlLED( Green, LED_ON );
ubhat 0:69f2e28d12c1 134 }
ubhat 0:69f2e28d12c1 135
ubhat 0:69f2e28d12c1 136 // Read and populate device orientation in Tx Buffer
ubhat 0:69f2e28d12c1 137 if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE )
ubhat 0:69f2e28d12c1 138 {
ubhat 0:69f2e28d12c1 139 if( statusReg & 0x40 )
ubhat 0:69f2e28d12c1 140 {
ubhat 0:69f2e28d12c1 141 if( statusReg & 0x01 )
ubhat 0:69f2e28d12c1 142 {
ubhat 0:69f2e28d12c1 143 BuffAddr[BuffPtr++] = 0x66; // horizontal + faceup
ubhat 0:69f2e28d12c1 144 }
ubhat 0:69f2e28d12c1 145 else
ubhat 0:69f2e28d12c1 146 {
ubhat 0:69f2e28d12c1 147 BuffAddr[BuffPtr++] = 0x99; // horizontal + facedown
ubhat 0:69f2e28d12c1 148 }
ubhat 0:69f2e28d12c1 149
ubhat 0:69f2e28d12c1 150 BuffAddr[BuffPtr++] = 0; // vertical = false
ubhat 0:69f2e28d12c1 151 }
ubhat 0:69f2e28d12c1 152 else
ubhat 0:69f2e28d12c1 153 {
ubhat 0:69f2e28d12c1 154 BuffAddr[BuffPtr++] = 0; // horizontal = false
ubhat 0:69f2e28d12c1 155 BuffAddr[BuffPtr++] = 0x11; // vertical = true
ubhat 0:69f2e28d12c1 156 }
ubhat 0:69f2e28d12c1 157 }
ubhat 0:69f2e28d12c1 158
ubhat 0:69f2e28d12c1 159 break;
ubhat 6:f8194e691dd4 160 }
ubhat 0:69f2e28d12c1 161
ubhat 0:69f2e28d12c1 162 case AppAcclSenet:
ubhat 0:69f2e28d12c1 163 {
ubhat 0:69f2e28d12c1 164 uint8_t statusReg;
ubhat 0:69f2e28d12c1 165
ubhat 0:69f2e28d12c1 166 // Read the PS_STATUS register
ubhat 0:69f2e28d12c1 167 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
ubhat 0:69f2e28d12c1 168
ubhat 0:69f2e28d12c1 169 /* Display Orientation of NAMote on Serial Port */
ubhat 0:69f2e28d12c1 170 SerialAcclMetrDisplay( statusReg );
ubhat 0:69f2e28d12c1 171
ubhat 0:69f2e28d12c1 172 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer
ubhat 0:69f2e28d12c1 173 if( ( statusReg & 0x40 ) != 0 )
ubhat 0:69f2e28d12c1 174 {
ubhat 0:69f2e28d12c1 175 AppLed = 0;
ubhat 0:69f2e28d12c1 176 CtrlLED( Green, LED_OFF );
ubhat 0:69f2e28d12c1 177 BuffAddr[BuffPtr++] = 0; // horizontal
ubhat 0:69f2e28d12c1 178 }
ubhat 0:69f2e28d12c1 179 else
ubhat 0:69f2e28d12c1 180 {
ubhat 0:69f2e28d12c1 181 AppLed = 1;
ubhat 0:69f2e28d12c1 182 CtrlLED( Green, LED_ON );
ubhat 0:69f2e28d12c1 183 BuffAddr[BuffPtr++] = 10; // vertical
ubhat 0:69f2e28d12c1 184 }
ubhat 0:69f2e28d12c1 185
ubhat 0:69f2e28d12c1 186 break;
ubhat 0:69f2e28d12c1 187 }
ubhat 0:69f2e28d12c1 188
ubhat 6:f8194e691dd4 189 case AppPushButton:
ubhat 6:f8194e691dd4 190 {
ubhat 6:f8194e691dd4 191 uint16_t PushButtonCnt;
ubhat 6:f8194e691dd4 192 uint8_t *p = (uint8_t *) &PushButtonCnt;
ubhat 6:f8194e691dd4 193
ubhat 6:f8194e691dd4 194 PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter;
ubhat 6:f8194e691dd4 195
ubhat 6:f8194e691dd4 196 memcpy( &BuffAddr[BuffPtr], p, sizeof(uint16_t) );
ubhat 6:f8194e691dd4 197
ubhat 6:f8194e691dd4 198 break;
ubhat 6:f8194e691dd4 199 }
ubhat 6:f8194e691dd4 200
ubhat 0:69f2e28d12c1 201 default:
ubhat 0:69f2e28d12c1 202 {
ubhat 0:69f2e28d12c1 203 break;
ubhat 0:69f2e28d12c1 204 }
ubhat 0:69f2e28d12c1 205 }
ubhat 0:69f2e28d12c1 206 }
ubhat 0:69f2e28d12c1 207
ubhat 0:69f2e28d12c1 208 static void OnRedLedTimerEvent( void )
ubhat 0:69f2e28d12c1 209 {
ubhat 0:69f2e28d12c1 210 TimerStop( &RedLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 211
ubhat 0:69f2e28d12c1 212 if( RedLed == LED_OFF )
ubhat 0:69f2e28d12c1 213 {
ubhat 0:69f2e28d12c1 214 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 215 }
ubhat 0:69f2e28d12c1 216 else
ubhat 0:69f2e28d12c1 217 {
ubhat 0:69f2e28d12c1 218 RedLed = LED_OFF;
ubhat 0:69f2e28d12c1 219 }
ubhat 0:69f2e28d12c1 220 }
ubhat 0:69f2e28d12c1 221
ubhat 0:69f2e28d12c1 222 static void OnYellowLedTimerEvent( void )
ubhat 0:69f2e28d12c1 223 {
ubhat 0:69f2e28d12c1 224 TimerStop( &YellowLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 225
ubhat 0:69f2e28d12c1 226 if( YellowLed == LED_OFF )
ubhat 0:69f2e28d12c1 227 {
ubhat 0:69f2e28d12c1 228 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 229 }
ubhat 0:69f2e28d12c1 230 else
ubhat 0:69f2e28d12c1 231 {
ubhat 0:69f2e28d12c1 232 YellowLed = LED_OFF;
ubhat 0:69f2e28d12c1 233 }
ubhat 0:69f2e28d12c1 234 }
ubhat 0:69f2e28d12c1 235
ubhat 0:69f2e28d12c1 236 static void OnGreenLedTimerEvent( void )
ubhat 0:69f2e28d12c1 237 {
ubhat 0:69f2e28d12c1 238 TimerStop( &GreenLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 239
ubhat 0:69f2e28d12c1 240 if( GreenLed == LED_OFF )
ubhat 0:69f2e28d12c1 241 {
ubhat 0:69f2e28d12c1 242 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 243 }
ubhat 0:69f2e28d12c1 244 else
ubhat 0:69f2e28d12c1 245 {
ubhat 0:69f2e28d12c1 246 GreenLed = LED_OFF;
ubhat 0:69f2e28d12c1 247 }
ubhat 0:69f2e28d12c1 248 }
ubhat 0:69f2e28d12c1 249
ubhat 0:69f2e28d12c1 250 TimerLed::TimerLed( eLedType led )
ubhat 0:69f2e28d12c1 251 {
ubhat 0:69f2e28d12c1 252 switch( led )
ubhat 0:69f2e28d12c1 253 {
ubhat 0:69f2e28d12c1 254 case Red:
ubhat 0:69f2e28d12c1 255 {
ubhat 0:69f2e28d12c1 256 TimerInit( &LedTimer, OnRedLedTimerEvent );
ubhat 0:69f2e28d12c1 257 break;
ubhat 0:69f2e28d12c1 258 }
ubhat 0:69f2e28d12c1 259
ubhat 0:69f2e28d12c1 260 case Yellow:
ubhat 0:69f2e28d12c1 261 {
ubhat 0:69f2e28d12c1 262 TimerInit( &LedTimer, OnYellowLedTimerEvent );
ubhat 0:69f2e28d12c1 263 break;
ubhat 0:69f2e28d12c1 264 }
ubhat 0:69f2e28d12c1 265
ubhat 0:69f2e28d12c1 266 case Green:
ubhat 0:69f2e28d12c1 267 {
ubhat 0:69f2e28d12c1 268 TimerInit( &LedTimer, OnGreenLedTimerEvent );
ubhat 0:69f2e28d12c1 269 break;
ubhat 0:69f2e28d12c1 270 }
ubhat 0:69f2e28d12c1 271 }
ubhat 0:69f2e28d12c1 272
ubhat 0:69f2e28d12c1 273 }
ubhat 0:69f2e28d12c1 274
ubhat 0:69f2e28d12c1 275 TimerLed::~TimerLed( )
ubhat 0:69f2e28d12c1 276 {
ubhat 0:69f2e28d12c1 277 }
ubhat 0:69f2e28d12c1 278
ubhat 0:69f2e28d12c1 279 void BlinkLED( eLedType led, uint32_t time )
ubhat 0:69f2e28d12c1 280 {
ubhat 0:69f2e28d12c1 281 switch( led )
ubhat 0:69f2e28d12c1 282 {
ubhat 0:69f2e28d12c1 283 case Red:
ubhat 0:69f2e28d12c1 284 {
ubhat 0:69f2e28d12c1 285 TimerSetValue( &RedLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 286 TimerStart( &RedLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 287 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 288 break;
ubhat 0:69f2e28d12c1 289 }
ubhat 0:69f2e28d12c1 290
ubhat 0:69f2e28d12c1 291 case Yellow:
ubhat 0:69f2e28d12c1 292 {
ubhat 0:69f2e28d12c1 293 TimerSetValue( &YellowLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 294 TimerStart( &YellowLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 295 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 296 break;
ubhat 0:69f2e28d12c1 297 }
ubhat 0:69f2e28d12c1 298
ubhat 0:69f2e28d12c1 299 case Green:
ubhat 0:69f2e28d12c1 300 {
ubhat 0:69f2e28d12c1 301 TimerSetValue( &GreenLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 302 TimerStart( &GreenLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 303 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 304 break;
ubhat 0:69f2e28d12c1 305 }
ubhat 0:69f2e28d12c1 306 }
ubhat 0:69f2e28d12c1 307 }
ubhat 0:69f2e28d12c1 308
ubhat 0:69f2e28d12c1 309 void ToggleLED( eLedType led )
ubhat 0:69f2e28d12c1 310 {
ubhat 0:69f2e28d12c1 311 switch( led )
ubhat 0:69f2e28d12c1 312 {
ubhat 0:69f2e28d12c1 313 case Red:
ubhat 0:69f2e28d12c1 314 {
ubhat 0:69f2e28d12c1 315 if( RedLed == LED_OFF )
ubhat 0:69f2e28d12c1 316 {
ubhat 0:69f2e28d12c1 317 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 318 }
ubhat 0:69f2e28d12c1 319 else
ubhat 0:69f2e28d12c1 320 {
ubhat 0:69f2e28d12c1 321 RedLed = LED_OFF;
ubhat 0:69f2e28d12c1 322 }
ubhat 0:69f2e28d12c1 323 break;
ubhat 0:69f2e28d12c1 324 }
ubhat 0:69f2e28d12c1 325
ubhat 0:69f2e28d12c1 326 case Yellow:
ubhat 0:69f2e28d12c1 327 {
ubhat 0:69f2e28d12c1 328 if( YellowLed == LED_OFF )
ubhat 0:69f2e28d12c1 329 {
ubhat 0:69f2e28d12c1 330 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 331 }
ubhat 0:69f2e28d12c1 332 else
ubhat 0:69f2e28d12c1 333 {
ubhat 0:69f2e28d12c1 334 YellowLed = LED_OFF;
ubhat 0:69f2e28d12c1 335 }
ubhat 0:69f2e28d12c1 336 break;
ubhat 0:69f2e28d12c1 337 }
ubhat 0:69f2e28d12c1 338
ubhat 0:69f2e28d12c1 339 case Green:
ubhat 0:69f2e28d12c1 340 {
ubhat 0:69f2e28d12c1 341 if( GreenLed == LED_OFF )
ubhat 0:69f2e28d12c1 342 {
ubhat 0:69f2e28d12c1 343 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 344 }
ubhat 0:69f2e28d12c1 345 else
ubhat 0:69f2e28d12c1 346 {
ubhat 0:69f2e28d12c1 347 GreenLed = LED_OFF;
ubhat 0:69f2e28d12c1 348 }
ubhat 0:69f2e28d12c1 349 break;
ubhat 0:69f2e28d12c1 350 }
ubhat 0:69f2e28d12c1 351 }
ubhat 0:69f2e28d12c1 352 }
ubhat 0:69f2e28d12c1 353
ubhat 0:69f2e28d12c1 354 void CtrlLED( eLedType led, uint8_t state )
ubhat 0:69f2e28d12c1 355 {
ubhat 0:69f2e28d12c1 356 switch( led )
ubhat 0:69f2e28d12c1 357 {
ubhat 0:69f2e28d12c1 358 case Red:
ubhat 0:69f2e28d12c1 359 {
ubhat 0:69f2e28d12c1 360 RedLed = state;
ubhat 0:69f2e28d12c1 361 break;
ubhat 0:69f2e28d12c1 362 }
ubhat 0:69f2e28d12c1 363
ubhat 0:69f2e28d12c1 364 case Yellow:
ubhat 0:69f2e28d12c1 365 {
ubhat 0:69f2e28d12c1 366 YellowLed = state;
ubhat 0:69f2e28d12c1 367 break;
ubhat 0:69f2e28d12c1 368 }
ubhat 0:69f2e28d12c1 369
ubhat 0:69f2e28d12c1 370 case Green:
ubhat 0:69f2e28d12c1 371 {
ubhat 0:69f2e28d12c1 372 GreenLed = state;
ubhat 0:69f2e28d12c1 373 break;
ubhat 0:69f2e28d12c1 374 }
ubhat 0:69f2e28d12c1 375
ubhat 0:69f2e28d12c1 376 case Usr:
ubhat 0:69f2e28d12c1 377 {
ubhat 0:69f2e28d12c1 378 if( state )
ubhat 0:69f2e28d12c1 379 {
ubhat 0:69f2e28d12c1 380 UsrLed = LED_ON;
ubhat 0:69f2e28d12c1 381 }
ubhat 0:69f2e28d12c1 382 else
ubhat 0:69f2e28d12c1 383 {
ubhat 0:69f2e28d12c1 384 UsrLed = LED_OFF;
ubhat 0:69f2e28d12c1 385 }
ubhat 0:69f2e28d12c1 386 break;
ubhat 0:69f2e28d12c1 387 }
ubhat 0:69f2e28d12c1 388 }
ubhat 0:69f2e28d12c1 389 }
ubhat 7:92f4f419f91f 390
ubhat 7:92f4f419f91f 391 void CheckOrientation( void )
ubhat 7:92f4f419f91f 392 {
ubhat 7:92f4f419f91f 393 uint8_t statusReg;
ubhat 7:92f4f419f91f 394
ubhat 7:92f4f419f91f 395 // Read the PS_STATUS register
ubhat 7:92f4f419f91f 396 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
ubhat 7:92f4f419f91f 397
ubhat 7:92f4f419f91f 398 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer
ubhat 7:92f4f419f91f 399 if( ( statusReg & 0x40 ) != 0 )
ubhat 7:92f4f419f91f 400 {
ubhat 7:92f4f419f91f 401 CtrlLED( Green, LED_OFF );
ubhat 7:92f4f419f91f 402 VerticalStatus = false; // horizontal
ubhat 7:92f4f419f91f 403 }
ubhat 7:92f4f419f91f 404 else
ubhat 7:92f4f419f91f 405 {
ubhat 7:92f4f419f91f 406 CtrlLED( Green, LED_ON );
ubhat 7:92f4f419f91f 407 VerticalStatus = true; // vertical
ubhat 7:92f4f419f91f 408 }
ubhat 7:92f4f419f91f 409 }