Workshop demo program
Dependencies: PinDetect mbed LoRaWAN-lib SX1272Lib
app/app.cpp@19:31fc997c460b, 2017-05-03 (annotated)
- Committer:
- Brandond200
- Date:
- Wed May 03 16:51:28 2017 +0000
- Revision:
- 19:31fc997c460b
- Parent:
- 18:326069443137
added a new timer to make sure the sending bool never gets stuck in the transmitting position. changed the uint8_t counting cycles for checkAlarm to a uint16_t
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sergei11522 | 7:d7cdd6804277 | 1 | #include "main.h" |
sergei11522 | 7:d7cdd6804277 | 2 | #include "mbed.h" |
sergei11522 | 7:d7cdd6804277 | 3 | #include "DebounceIn.h" |
sergei11522 | 7:d7cdd6804277 | 4 | #include "PinNames.h" |
Brandond200 | 8:fb8b53c490e1 | 5 | #include "timer.h" |
Brandond200 | 10:2eb7b1614bb8 | 6 | #include <math.h> |
Brandond200 | 8:fb8b53c490e1 | 7 | #include "app.h" |
Brandond200 | 8:fb8b53c490e1 | 8 | #include "SerialDisplay.h" |
sergei11522 | 7:d7cdd6804277 | 9 | |
sergei11522 | 7:d7cdd6804277 | 10 | //initialize our sensors |
sergei11522 | 7:d7cdd6804277 | 11 | DebounceIn button(D6); |
sergei11522 | 7:d7cdd6804277 | 12 | DigitalOut led(A1); |
sergei11522 | 7:d7cdd6804277 | 13 | AnalogIn rotary(A3); //the potentiometer/rotary sensor |
sergei11522 | 7:d7cdd6804277 | 14 | |
Brandond200 | 12:67fcab1e915a | 15 | //changable alarm threashold |
Brandond200 | 12:67fcab1e915a | 16 | #define ALARM_THRESHOLD 100 /*alarm triggered over this percentage*/ |
Brandond200 | 10:2eb7b1614bb8 | 17 | |
Brandond200 | 12:67fcab1e915a | 18 | //constatnts |
Brandond200 | 10:2eb7b1614bb8 | 19 | #define BYTE_TO_PERCENT 655.35/*divisor to convert 2 byte number into number between 0 and 100*/ |
Brandond200 | 10:2eb7b1614bb8 | 20 | #define TWO_HUNDRED_MILLISECONDS 200 * 1000 /*200 miliseconds in microseconds */ |
Brandond200 | 12:67fcab1e915a | 21 | |
Brandond200 | 12:67fcab1e915a | 22 | //myDevies codes |
Brandond200 | 12:67fcab1e915a | 23 | #define ROTATION_DATA_CHANNEL 0 /* myDevices channel to send rotation position on*/ |
Brandond200 | 10:2eb7b1614bb8 | 24 | #define ROTATION_DATA_TYPE 2 /*2 = Analog Input */ |
Brandond200 | 12:67fcab1e915a | 25 | #define ALARM_DATA_CHANNEL 1 /* myDevices channel to send alarm status on*/ |
Brandond200 | 10:2eb7b1614bb8 | 26 | #define ALARM_DATA_TYPE 0 /*0 = Digital Input */ |
Brandond200 | 12:67fcab1e915a | 27 | |
Brandond200 | 12:67fcab1e915a | 28 | //settings to not change |
Brandond200 | 10:2eb7b1614bb8 | 29 | #define MAX_DATA_LENGTH 64 |
Brandond200 | 10:2eb7b1614bb8 | 30 | #define BLINK_COUNT_EVENT_TRANSMIT 1 |
Brandond200 | 10:2eb7b1614bb8 | 31 | #define BLINK_COUNT_TIMER_TRANSMIT 2 |
Brandond200 | 10:2eb7b1614bb8 | 32 | #define BLINK_COUNT_DOWNLINK_CONFIRMATION 3 |
Brandond200 | 12:67fcab1e915a | 33 | #define BLINK_COUNT_JOINED 5 |
Brandond200 | 10:2eb7b1614bb8 | 34 | |
Brandond200 | 10:2eb7b1614bb8 | 35 | //network variables |
Brandond200 | 10:2eb7b1614bb8 | 36 | bool just_joined = true; //used to determine if this is the first time through the loop |
Brandond200 | 18:326069443137 | 37 | volatile bool sending = false; |
Brandond200 | 10:2eb7b1614bb8 | 38 | uint8_t data[MAX_DATA_LENGTH] = {0}; //data that will be transmitted |
Brandond200 | 10:2eb7b1614bb8 | 39 | uint8_t dataLength = 0; //length of data that will be transmitted |
Brandond200 | 10:2eb7b1614bb8 | 40 | |
Brandond200 | 10:2eb7b1614bb8 | 41 | //application variables |
Brandond200 | 10:2eb7b1614bb8 | 42 | bool button_pressed = false; //last state of the button |
Brandond200 | 12:67fcab1e915a | 43 | bool alarmThresholdTriggered = false; //last state on the alarm |
Brandond200 | 10:2eb7b1614bb8 | 44 | uint8_t flashCount = 0; //how many more times to flash the LED |
Brandond200 | 19:31fc997c460b | 45 | uint16_t checkCount = 0; |
Brandond200 | 10:2eb7b1614bb8 | 46 | |
Brandond200 | 10:2eb7b1614bb8 | 47 | //timers |
Brandond200 | 19:31fc997c460b | 48 | TimerEvent_t heartbeatTimer; //timer so schedule heartbeat transmissions |
Brandond200 | 10:2eb7b1614bb8 | 49 | TimerEvent_t ledTimer; //timer to blink LED |
Brandond200 | 19:31fc997c460b | 50 | TimerEvent_t txEndTimer; |
Brandond200 | 8:fb8b53c490e1 | 51 | |
sergei11522 | 7:d7cdd6804277 | 52 | |
sergei11522 | 7:d7cdd6804277 | 53 | void onDownlinkConfirmation(){ |
Brandond200 | 10:2eb7b1614bb8 | 54 | flashLED(BLINK_COUNT_DOWNLINK_CONFIRMATION); |
Brandond200 | 19:31fc997c460b | 55 | TimerStop(&txEndTimer); |
Brandond200 | 18:326069443137 | 56 | sending = false; |
Brandond200 | 18:326069443137 | 57 | } |
Brandond200 | 18:326069443137 | 58 | |
Brandond200 | 18:326069443137 | 59 | void onDownlinkUnconfirmed(){ |
Brandond200 | 19:31fc997c460b | 60 | TimerStop(&txEndTimer); |
Brandond200 | 18:326069443137 | 61 | sending = false; |
sergei11522 | 7:d7cdd6804277 | 62 | } |
sergei11522 | 7:d7cdd6804277 | 63 | |
sergei11522 | 7:d7cdd6804277 | 64 | void start(){ |
Brandond200 | 8:fb8b53c490e1 | 65 | //any initialization here |
Brandond200 | 18:326069443137 | 66 | |
Brandond200 | 10:2eb7b1614bb8 | 67 | //initilize LED flash timer |
Brandond200 | 8:fb8b53c490e1 | 68 | TimerInit(&ledTimer, flashLEDCallback); |
Brandond200 | 10:2eb7b1614bb8 | 69 | TimerSetValue( &ledTimer, TWO_HUNDRED_MILLISECONDS ); |
Brandond200 | 19:31fc997c460b | 70 | |
Brandond200 | 19:31fc997c460b | 71 | //initilize txTimeout timer |
Brandond200 | 19:31fc997c460b | 72 | TimerInit(&txEndTimer, txTimeoutCallback); |
Brandond200 | 19:31fc997c460b | 73 | TimerSetValue( &txEndTimer, 1000*1000*15 ); |
Brandond200 | 19:31fc997c460b | 74 | |
sergei11522 | 7:d7cdd6804277 | 75 | } |
sergei11522 | 7:d7cdd6804277 | 76 | |
sergei11522 | 7:d7cdd6804277 | 77 | //this loop will start to be called as soon as the device successfully joins the network |
sergei11522 | 7:d7cdd6804277 | 78 | void loop(){ |
sergei11522 | 7:d7cdd6804277 | 79 | //the loop is called as soon as the device joins. Flash the led 10 times when this happens |
sergei11522 | 7:d7cdd6804277 | 80 | if (just_joined){ |
sergei11522 | 7:d7cdd6804277 | 81 | just_joined = false; |
Brandond200 | 10:2eb7b1614bb8 | 82 | flashLED(BLINK_COUNT_JOINED); |
sergei11522 | 7:d7cdd6804277 | 83 | } |
sergei11522 | 7:d7cdd6804277 | 84 | |
Brandond200 | 12:67fcab1e915a | 85 | //check if button was just pressed |
Brandond200 | 12:67fcab1e915a | 86 | checkButton(); |
Brandond200 | 18:326069443137 | 87 | |
Brandond200 | 12:67fcab1e915a | 88 | } |
Brandond200 | 12:67fcab1e915a | 89 | |
Brandond200 | 12:67fcab1e915a | 90 | void checkButton(void){ |
sergei11522 | 7:d7cdd6804277 | 91 | //button is pressed. Trigger once so that if we hold the button this block doesnt continously execute |
Brandond200 | 10:2eb7b1614bb8 | 92 | if (button == 1 && button_pressed == false){ |
sergei11522 | 7:d7cdd6804277 | 93 | button_pressed = true; |
Brandond200 | 10:2eb7b1614bb8 | 94 | flashLED(BLINK_COUNT_EVENT_TRANSMIT); |
Brandond200 | 10:2eb7b1614bb8 | 95 | transmitData(rotary.read_u16()); |
sergei11522 | 7:d7cdd6804277 | 96 | } else if (button == 0){ |
sergei11522 | 7:d7cdd6804277 | 97 | button_pressed = false; |
sergei11522 | 7:d7cdd6804277 | 98 | } |
Brandond200 | 12:67fcab1e915a | 99 | } |
Brandond200 | 12:67fcab1e915a | 100 | |
Brandond200 | 12:67fcab1e915a | 101 | //check if value passed in should trigger the alarm, if so, transmit |
Brandond200 | 12:67fcab1e915a | 102 | void checkAlarm(void){ |
Brandond200 | 18:326069443137 | 103 | checkCount++; |
Brandond200 | 18:326069443137 | 104 | if(checkCount > 5000){ |
Brandond200 | 18:326069443137 | 105 | checkCount = 0; |
Brandond200 | 18:326069443137 | 106 | uint16_t position = rotary.read_u16(); |
Brandond200 | 18:326069443137 | 107 | //check if should trigger alarm |
Brandond200 | 18:326069443137 | 108 | if(position / BYTE_TO_PERCENT > (ALARM_THRESHOLD)){ |
Brandond200 | 18:326069443137 | 109 | //if the alarm has not already been triggered |
Brandond200 | 18:326069443137 | 110 | if(!alarmThresholdTriggered){ |
Brandond200 | 18:326069443137 | 111 | alarmThresholdTriggered = true;//set the alarm to triggered |
Brandond200 | 18:326069443137 | 112 | flashLED(BLINK_COUNT_EVENT_TRANSMIT); |
Brandond200 | 18:326069443137 | 113 | transmitData(position);//transmit data |
Brandond200 | 18:326069443137 | 114 | } |
Brandond200 | 12:67fcab1e915a | 115 | } |
Brandond200 | 18:326069443137 | 116 | else if(position / BYTE_TO_PERCENT < (ALARM_THRESHOLD - 1)){ |
Brandond200 | 18:326069443137 | 117 | if(alarmThresholdTriggered){ |
Brandond200 | 18:326069443137 | 118 | //alarm just changed state to not triggered |
Brandond200 | 18:326069443137 | 119 | flashLED(BLINK_COUNT_EVENT_TRANSMIT); |
Brandond200 | 18:326069443137 | 120 | transmitData(position);//transmit data |
Brandond200 | 18:326069443137 | 121 | alarmThresholdTriggered = false; |
Brandond200 | 18:326069443137 | 122 | } |
Brandond200 | 15:07f7e9ce7e21 | 123 | } |
Brandond200 | 12:67fcab1e915a | 124 | } |
Brandond200 | 12:67fcab1e915a | 125 | } |
Brandond200 | 12:67fcab1e915a | 126 | |
Brandond200 | 12:67fcab1e915a | 127 | //start heartbeat timer. pass in how often in seconds it should transmit |
Brandond200 | 12:67fcab1e915a | 128 | void startHeartbeat(uint8_t time){ |
Brandond200 | 19:31fc997c460b | 129 | TimerInit(&heartbeatTimer, timerCallback); |
Brandond200 | 19:31fc997c460b | 130 | TimerSetValue( &heartbeatTimer, time * 1000 * 1000); |
Brandond200 | 19:31fc997c460b | 131 | TimerStart(&heartbeatTimer); |
Brandond200 | 10:2eb7b1614bb8 | 132 | } |
Brandond200 | 10:2eb7b1614bb8 | 133 | |
Brandond200 | 10:2eb7b1614bb8 | 134 | //Transmit rotory position and alarm status |
Brandond200 | 12:67fcab1e915a | 135 | void transmitData(uint16_t position){ |
Brandond200 | 18:326069443137 | 136 | if(!sending){ |
Brandond200 | 18:326069443137 | 137 | sending = true; |
Brandond200 | 18:326069443137 | 138 | addRotaryData(position); //add the rotary position to data |
Brandond200 | 15:07f7e9ce7e21 | 139 | |
Brandond200 | 18:326069443137 | 140 | setDataToSend(data, dataLength); //set data to be transmitted |
Brandond200 | 18:326069443137 | 141 | sendLoraTransmission(); //queue transmission |
Brandond200 | 18:326069443137 | 142 | dataLength = 0; //reset data length so new data starts back at begining |
Brandond200 | 19:31fc997c460b | 143 | TimerStart(&txEndTimer); |
Brandond200 | 18:326069443137 | 144 | } |
Brandond200 | 10:2eb7b1614bb8 | 145 | } |
Brandond200 | 10:2eb7b1614bb8 | 146 | |
Brandond200 | 10:2eb7b1614bb8 | 147 | //read the rotory position and add to data to transmit |
Brandond200 | 10:2eb7b1614bb8 | 148 | void addRotaryData(uint16_t positionArg){ |
Brandond200 | 10:2eb7b1614bb8 | 149 | uint16_t position = positionArg / (BYTE_TO_PERCENT / 100); |
Brandond200 | 10:2eb7b1614bb8 | 150 | |
Brandond200 | 10:2eb7b1614bb8 | 151 | data[dataLength++] = ROTATION_DATA_CHANNEL; |
Brandond200 | 10:2eb7b1614bb8 | 152 | data[dataLength++] = ROTATION_DATA_TYPE; |
Brandond200 | 11:88afd7663dc4 | 153 | data[dataLength++] = position >> 8; //add the upper byte of the rotory position |
Brandond200 | 10:2eb7b1614bb8 | 154 | data[dataLength++] = position & 0xFF; //add the lower byte of the rotory position |
Brandond200 | 10:2eb7b1614bb8 | 155 | } |
Brandond200 | 10:2eb7b1614bb8 | 156 | |
Brandond200 | 10:2eb7b1614bb8 | 157 | //read the rotory position and add alarm status to data to transmit |
Brandond200 | 10:2eb7b1614bb8 | 158 | void addAlarmData(uint16_t positionArg){ |
Brandond200 | 10:2eb7b1614bb8 | 159 | int16_t position = positionArg / BYTE_TO_PERCENT; |
Brandond200 | 10:2eb7b1614bb8 | 160 | |
Brandond200 | 10:2eb7b1614bb8 | 161 | data[dataLength++] = ALARM_DATA_CHANNEL; |
Brandond200 | 10:2eb7b1614bb8 | 162 | data[dataLength++] = ALARM_DATA_TYPE; |
Brandond200 | 15:07f7e9ce7e21 | 163 | data[dataLength++] = (uint8_t)position >= ALARM_THRESHOLD; //add binary for it alarm triggered or not |
Brandond200 | 10:2eb7b1614bb8 | 164 | } |
Brandond200 | 10:2eb7b1614bb8 | 165 | |
Brandond200 | 10:2eb7b1614bb8 | 166 | //start flash LED |
Brandond200 | 10:2eb7b1614bb8 | 167 | void flashLED(uint8_t times){ |
Brandond200 | 11:88afd7663dc4 | 168 | if(flashCount == 0){ //if it is not currently flashing |
Brandond200 | 13:d2cccfdb615c | 169 | TimerStart(&ledTimer); //start timer to toggle LED state |
Brandond200 | 11:88afd7663dc4 | 170 | } |
Brandond200 | 11:88afd7663dc4 | 171 | flashCount += times; //set the number of times to flash |
Brandond200 | 15:07f7e9ce7e21 | 172 | //make sure it is not set to high |
Brandond200 | 15:07f7e9ce7e21 | 173 | if(flashCount > 10){ |
Brandond200 | 15:07f7e9ce7e21 | 174 | flashCount = 10; |
Brandond200 | 15:07f7e9ce7e21 | 175 | } |
Brandond200 | 13:d2cccfdb615c | 176 | led.write(1); //turn on LED |
Brandond200 | 10:2eb7b1614bb8 | 177 | } |
Brandond200 | 10:2eb7b1614bb8 | 178 | |
Brandond200 | 10:2eb7b1614bb8 | 179 | //callback to change state of LED for blinking |
Brandond200 | 10:2eb7b1614bb8 | 180 | void flashLEDCallback(){ |
Brandond200 | 10:2eb7b1614bb8 | 181 | //if the LED is on, turn it off |
Brandond200 | 10:2eb7b1614bb8 | 182 | if(led.read() == 1){ |
Brandond200 | 10:2eb7b1614bb8 | 183 | led.write(0); |
Brandond200 | 10:2eb7b1614bb8 | 184 | flashCount--; |
Brandond200 | 10:2eb7b1614bb8 | 185 | //if done flashing turn off the timer |
Brandond200 | 10:2eb7b1614bb8 | 186 | if(flashCount <= 0){ |
Brandond200 | 10:2eb7b1614bb8 | 187 | TimerStop(&ledTimer); |
Brandond200 | 10:2eb7b1614bb8 | 188 | } |
Brandond200 | 10:2eb7b1614bb8 | 189 | } |
Brandond200 | 10:2eb7b1614bb8 | 190 | //if LED is off, turn it on |
Brandond200 | 10:2eb7b1614bb8 | 191 | else{ |
Brandond200 | 10:2eb7b1614bb8 | 192 | led.write(1); |
Brandond200 | 10:2eb7b1614bb8 | 193 | } |
Brandond200 | 10:2eb7b1614bb8 | 194 | } |
Brandond200 | 10:2eb7b1614bb8 | 195 | |
Brandond200 | 12:67fcab1e915a | 196 | |
Brandond200 | 12:67fcab1e915a | 197 | //callback for transmission timer |
Brandond200 | 12:67fcab1e915a | 198 | void timerCallback(){ |
Brandond200 | 12:67fcab1e915a | 199 | flashLED(BLINK_COUNT_TIMER_TRANSMIT); |
Brandond200 | 12:67fcab1e915a | 200 | transmitData(rotary.read_u16()); |
Brandond200 | 19:31fc997c460b | 201 | } |
Brandond200 | 19:31fc997c460b | 202 | |
Brandond200 | 19:31fc997c460b | 203 | void txTimeoutCallback(){ |
Brandond200 | 19:31fc997c460b | 204 | sending = false; |
Brandond200 | 19:31fc997c460b | 205 | TimerStop(&txEndTimer); |
Brandond200 | 8:fb8b53c490e1 | 206 | } |