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:
mluis
Date:
Mon Apr 24 13:47:27 2017 +0000
Revision:
18:18408c3c2d0c
Parent:
15:39a23f5affd1
WARNING: Radio API timings changed from micro-seconds to milliseconds; ; Synchronized with https://github.com/Lora-net/LoRaMac-node git revision e506c246652fa44c3f24cecb89d0707b49ece739; Updated all libraries to the latest versions

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 );
mluis 18:18408c3c2d0c 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 {
mluis 18:18408c3c2d0c 49 memcpy( BuffAddr + BuffPtr, pData, len );
mluis 18:18408c3c2d0c 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 )
mluis 18:18408c3c2d0c 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
mluis 18:18408c3c2d0c 84 case AppTemp:
mluis 18:18408c3c2d0c 85 {
mluis 18:18408c3c2d0c 86 Mpl3115a2.ReadTemperature( );
mluis 18:18408c3c2d0c 87 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE )
mluis 18:18408c3c2d0c 88 {
mluis 18:18408c3c2d0c 89 BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 °C
ubhat 13:6b6f4be13633 90 }
ubhat 13:6b6f4be13633 91 break;
ubhat 13:6b6f4be13633 92 }
ubhat 13:6b6f4be13633 93
ubhat 13:6b6f4be13633 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
mluis 18:18408c3c2d0c 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 */
mluis 18:18408c3c2d0c 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
mluis 18:18408c3c2d0c 156 }
mluis 18:18408c3c2d0c 157 }
mluis 18:18408c3c2d0c 158
ubhat 0:69f2e28d12c1 159 break;
mluis 18:18408c3c2d0c 160 }
ubhat 0:69f2e28d12c1 161
ubhat 0:69f2e28d12c1 162 case AppAcclSenet:
mluis 18:18408c3c2d0c 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
mluis 18:18408c3c2d0c 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 13:6b6f4be13633 184 }
ubhat 13:6b6f4be13633 185 break;
ubhat 13:6b6f4be13633 186 }
ubhat 13:6b6f4be13633 187
ubhat 6:f8194e691dd4 188 case AppPushButton:
mluis 18:18408c3c2d0c 189 {
ubhat 6:f8194e691dd4 190 uint16_t PushButtonCnt;
mluis 18:18408c3c2d0c 191 uint8_t *p = ( uint8_t * )&PushButtonCnt;
ubhat 6:f8194e691dd4 192
ubhat 6:f8194e691dd4 193 PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter;
mluis 18:18408c3c2d0c 194
mluis 18:18408c3c2d0c 195 memcpy( &BuffAddr[BuffPtr], p, sizeof( uint16_t ) );
ubhat 6:f8194e691dd4 196 break;
ubhat 6:f8194e691dd4 197 }
ubhat 6:f8194e691dd4 198
ubhat 0:69f2e28d12c1 199 default:
mluis 18:18408c3c2d0c 200 {
ubhat 0:69f2e28d12c1 201 break;
ubhat 0:69f2e28d12c1 202 }
ubhat 0:69f2e28d12c1 203 }
ubhat 0:69f2e28d12c1 204 }
ubhat 0:69f2e28d12c1 205
ubhat 0:69f2e28d12c1 206 static void OnRedLedTimerEvent( void )
ubhat 0:69f2e28d12c1 207 {
ubhat 0:69f2e28d12c1 208 TimerStop( &RedLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 209
ubhat 0:69f2e28d12c1 210 if( RedLed == LED_OFF )
ubhat 0:69f2e28d12c1 211 {
ubhat 0:69f2e28d12c1 212 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 213 }
ubhat 0:69f2e28d12c1 214 else
ubhat 0:69f2e28d12c1 215 {
ubhat 0:69f2e28d12c1 216 RedLed = LED_OFF;
ubhat 0:69f2e28d12c1 217 }
ubhat 0:69f2e28d12c1 218 }
ubhat 0:69f2e28d12c1 219
ubhat 0:69f2e28d12c1 220 static void OnYellowLedTimerEvent( void )
ubhat 0:69f2e28d12c1 221 {
ubhat 0:69f2e28d12c1 222 TimerStop( &YellowLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 223
ubhat 0:69f2e28d12c1 224 if( YellowLed == LED_OFF )
ubhat 0:69f2e28d12c1 225 {
ubhat 0:69f2e28d12c1 226 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 227 }
ubhat 0:69f2e28d12c1 228 else
ubhat 0:69f2e28d12c1 229 {
ubhat 0:69f2e28d12c1 230 YellowLed = LED_OFF;
ubhat 0:69f2e28d12c1 231 }
ubhat 0:69f2e28d12c1 232 }
ubhat 0:69f2e28d12c1 233
ubhat 0:69f2e28d12c1 234 static void OnGreenLedTimerEvent( void )
ubhat 0:69f2e28d12c1 235 {
ubhat 0:69f2e28d12c1 236 TimerStop( &GreenLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 237
ubhat 0:69f2e28d12c1 238 if( GreenLed == LED_OFF )
ubhat 0:69f2e28d12c1 239 {
ubhat 0:69f2e28d12c1 240 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 241 }
ubhat 0:69f2e28d12c1 242 else
ubhat 0:69f2e28d12c1 243 {
ubhat 0:69f2e28d12c1 244 GreenLed = LED_OFF;
ubhat 0:69f2e28d12c1 245 }
ubhat 0:69f2e28d12c1 246 }
ubhat 0:69f2e28d12c1 247
ubhat 0:69f2e28d12c1 248 TimerLed::TimerLed( eLedType led )
ubhat 0:69f2e28d12c1 249 {
ubhat 0:69f2e28d12c1 250 switch( led )
ubhat 0:69f2e28d12c1 251 {
ubhat 0:69f2e28d12c1 252 case Red:
ubhat 0:69f2e28d12c1 253 {
ubhat 0:69f2e28d12c1 254 TimerInit( &LedTimer, OnRedLedTimerEvent );
ubhat 0:69f2e28d12c1 255 break;
ubhat 0:69f2e28d12c1 256 }
ubhat 0:69f2e28d12c1 257
ubhat 0:69f2e28d12c1 258 case Yellow:
ubhat 0:69f2e28d12c1 259 {
ubhat 0:69f2e28d12c1 260 TimerInit( &LedTimer, OnYellowLedTimerEvent );
ubhat 0:69f2e28d12c1 261 break;
ubhat 0:69f2e28d12c1 262 }
ubhat 0:69f2e28d12c1 263
ubhat 0:69f2e28d12c1 264 case Green:
ubhat 0:69f2e28d12c1 265 {
ubhat 0:69f2e28d12c1 266 TimerInit( &LedTimer, OnGreenLedTimerEvent );
ubhat 0:69f2e28d12c1 267 break;
ubhat 0:69f2e28d12c1 268 }
mluis 18:18408c3c2d0c 269 default:
mluis 18:18408c3c2d0c 270 {
mluis 18:18408c3c2d0c 271 break;
mluis 18:18408c3c2d0c 272 }
ubhat 0:69f2e28d12c1 273 }
ubhat 0:69f2e28d12c1 274
ubhat 0:69f2e28d12c1 275 }
ubhat 0:69f2e28d12c1 276
ubhat 0:69f2e28d12c1 277 TimerLed::~TimerLed( )
ubhat 0:69f2e28d12c1 278 {
ubhat 0:69f2e28d12c1 279 }
ubhat 0:69f2e28d12c1 280
ubhat 0:69f2e28d12c1 281 void BlinkLED( eLedType led, uint32_t time )
ubhat 0:69f2e28d12c1 282 {
ubhat 0:69f2e28d12c1 283 switch( led )
ubhat 0:69f2e28d12c1 284 {
ubhat 0:69f2e28d12c1 285 case Red:
ubhat 0:69f2e28d12c1 286 {
ubhat 0:69f2e28d12c1 287 TimerSetValue( &RedLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 288 TimerStart( &RedLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 289 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 290 break;
ubhat 0:69f2e28d12c1 291 }
ubhat 0:69f2e28d12c1 292
ubhat 0:69f2e28d12c1 293 case Yellow:
ubhat 0:69f2e28d12c1 294 {
ubhat 0:69f2e28d12c1 295 TimerSetValue( &YellowLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 296 TimerStart( &YellowLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 297 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 298 break;
ubhat 0:69f2e28d12c1 299 }
ubhat 0:69f2e28d12c1 300
ubhat 0:69f2e28d12c1 301 case Green:
ubhat 0:69f2e28d12c1 302 {
ubhat 0:69f2e28d12c1 303 TimerSetValue( &GreenLedTimer.LedTimer, time );
ubhat 0:69f2e28d12c1 304 TimerStart( &GreenLedTimer.LedTimer );
ubhat 0:69f2e28d12c1 305 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 306 break;
ubhat 0:69f2e28d12c1 307 }
mluis 18:18408c3c2d0c 308 default:
mluis 18:18408c3c2d0c 309 {
mluis 18:18408c3c2d0c 310 break;
mluis 18:18408c3c2d0c 311 }
ubhat 0:69f2e28d12c1 312 }
ubhat 0:69f2e28d12c1 313 }
ubhat 0:69f2e28d12c1 314
ubhat 0:69f2e28d12c1 315 void ToggleLED( eLedType led )
ubhat 0:69f2e28d12c1 316 {
ubhat 0:69f2e28d12c1 317 switch( led )
ubhat 0:69f2e28d12c1 318 {
ubhat 0:69f2e28d12c1 319 case Red:
ubhat 0:69f2e28d12c1 320 {
ubhat 0:69f2e28d12c1 321 if( RedLed == LED_OFF )
ubhat 0:69f2e28d12c1 322 {
ubhat 0:69f2e28d12c1 323 RedLed = LED_ON;
ubhat 0:69f2e28d12c1 324 }
ubhat 0:69f2e28d12c1 325 else
ubhat 0:69f2e28d12c1 326 {
ubhat 0:69f2e28d12c1 327 RedLed = LED_OFF;
ubhat 0:69f2e28d12c1 328 }
ubhat 0:69f2e28d12c1 329 break;
ubhat 0:69f2e28d12c1 330 }
ubhat 0:69f2e28d12c1 331
ubhat 0:69f2e28d12c1 332 case Yellow:
ubhat 0:69f2e28d12c1 333 {
ubhat 0:69f2e28d12c1 334 if( YellowLed == LED_OFF )
ubhat 0:69f2e28d12c1 335 {
ubhat 0:69f2e28d12c1 336 YellowLed = LED_ON;
ubhat 0:69f2e28d12c1 337 }
ubhat 0:69f2e28d12c1 338 else
ubhat 0:69f2e28d12c1 339 {
ubhat 0:69f2e28d12c1 340 YellowLed = LED_OFF;
ubhat 0:69f2e28d12c1 341 }
ubhat 0:69f2e28d12c1 342 break;
ubhat 0:69f2e28d12c1 343 }
ubhat 0:69f2e28d12c1 344
ubhat 0:69f2e28d12c1 345 case Green:
ubhat 0:69f2e28d12c1 346 {
ubhat 0:69f2e28d12c1 347 if( GreenLed == LED_OFF )
ubhat 0:69f2e28d12c1 348 {
ubhat 0:69f2e28d12c1 349 GreenLed = LED_ON;
ubhat 0:69f2e28d12c1 350 }
ubhat 0:69f2e28d12c1 351 else
ubhat 0:69f2e28d12c1 352 {
ubhat 0:69f2e28d12c1 353 GreenLed = LED_OFF;
ubhat 0:69f2e28d12c1 354 }
ubhat 0:69f2e28d12c1 355 break;
ubhat 0:69f2e28d12c1 356 }
mluis 18:18408c3c2d0c 357 default:
mluis 18:18408c3c2d0c 358 {
mluis 18:18408c3c2d0c 359 break;
mluis 18:18408c3c2d0c 360 }
ubhat 0:69f2e28d12c1 361 }
ubhat 0:69f2e28d12c1 362 }
ubhat 0:69f2e28d12c1 363
ubhat 0:69f2e28d12c1 364 void CtrlLED( eLedType led, uint8_t state )
ubhat 0:69f2e28d12c1 365 {
ubhat 0:69f2e28d12c1 366 switch( led )
ubhat 0:69f2e28d12c1 367 {
ubhat 0:69f2e28d12c1 368 case Red:
ubhat 0:69f2e28d12c1 369 {
ubhat 0:69f2e28d12c1 370 RedLed = state;
ubhat 0:69f2e28d12c1 371 break;
ubhat 0:69f2e28d12c1 372 }
ubhat 0:69f2e28d12c1 373
ubhat 0:69f2e28d12c1 374 case Yellow:
ubhat 0:69f2e28d12c1 375 {
ubhat 0:69f2e28d12c1 376 YellowLed = state;
ubhat 0:69f2e28d12c1 377 break;
ubhat 0:69f2e28d12c1 378 }
ubhat 0:69f2e28d12c1 379
ubhat 0:69f2e28d12c1 380 case Green:
ubhat 0:69f2e28d12c1 381 {
ubhat 0:69f2e28d12c1 382 GreenLed = state;
ubhat 0:69f2e28d12c1 383 break;
ubhat 0:69f2e28d12c1 384 }
ubhat 0:69f2e28d12c1 385
ubhat 0:69f2e28d12c1 386 case Usr:
ubhat 0:69f2e28d12c1 387 {
ubhat 0:69f2e28d12c1 388 if( state )
ubhat 0:69f2e28d12c1 389 {
ubhat 0:69f2e28d12c1 390 UsrLed = LED_ON;
ubhat 0:69f2e28d12c1 391 }
ubhat 0:69f2e28d12c1 392 else
ubhat 0:69f2e28d12c1 393 {
ubhat 0:69f2e28d12c1 394 UsrLed = LED_OFF;
ubhat 0:69f2e28d12c1 395 }
ubhat 0:69f2e28d12c1 396 break;
ubhat 0:69f2e28d12c1 397 }
ubhat 0:69f2e28d12c1 398 }
ubhat 0:69f2e28d12c1 399 }
ubhat 7:92f4f419f91f 400
ubhat 7:92f4f419f91f 401 void CheckOrientation( void )
ubhat 7:92f4f419f91f 402 {
ubhat 7:92f4f419f91f 403 uint8_t statusReg;
mluis 18:18408c3c2d0c 404
ubhat 7:92f4f419f91f 405 // Read the PS_STATUS register
ubhat 7:92f4f419f91f 406 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS );
ubhat 7:92f4f419f91f 407
mluis 18:18408c3c2d0c 408 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer
ubhat 7:92f4f419f91f 409 if( ( statusReg & 0x40 ) != 0 )
mluis 18:18408c3c2d0c 410 {
ubhat 7:92f4f419f91f 411 CtrlLED( Green, LED_OFF );
ubhat 7:92f4f419f91f 412 VerticalStatus = false; // horizontal
ubhat 7:92f4f419f91f 413 }
ubhat 7:92f4f419f91f 414 else
mluis 18:18408c3c2d0c 415 {
ubhat 7:92f4f419f91f 416 CtrlLED( Green, LED_ON );
ubhat 7:92f4f419f91f 417 VerticalStatus = true; // vertical
mluis 18:18408c3c2d0c 418 }
mluis 18:18408c3c2d0c 419 }