Workshop demo program

Dependencies:   PinDetect mbed LoRaWAN-lib SX1272Lib

app/app.cpp

Committer:
Brandond200
Date:
2017-04-28
Revision:
14:7d092ebf7250
Parent:
13:d2cccfdb615c
Child:
15:07f7e9ce7e21

File content as of revision 14:7d092ebf7250:

#include "main.h"
#include "mbed.h"
#include "DebounceIn.h"
#include "PinNames.h"
#include "timer.h"
#include <math.h>
#include "app.h"
#include "SerialDisplay.h"

//initialize our sensors
DebounceIn button(D6);
DigitalOut led(A1);
AnalogIn rotary(A3); //the potentiometer/rotary sensor

//changable alarm threashold
#define ALARM_THRESHOLD 100 /*alarm triggered over this percentage*/

//constatnts
#define BYTE_TO_PERCENT 655.35/*divisor to convert 2 byte number into number between 0 and 100*/
#define TWO_HUNDRED_MILLISECONDS 200 * 1000  /*200 miliseconds in microseconds */

//myDevies codes
#define ROTATION_DATA_CHANNEL 0 /* myDevices channel to send rotation position on*/
#define ROTATION_DATA_TYPE 2 /*2 = Analog Input */
#define ALARM_DATA_CHANNEL 1 /* myDevices channel to send alarm status on*/
#define ALARM_DATA_TYPE 0 /*0 = Digital Input */

//settings to not change
#define MAX_DATA_LENGTH 64
#define BLINK_COUNT_EVENT_TRANSMIT 1
#define BLINK_COUNT_TIMER_TRANSMIT 2
#define BLINK_COUNT_DOWNLINK_CONFIRMATION 3
#define BLINK_COUNT_JOINED 5

//network variables
bool just_joined = true; //used to determine if this is the first time through the loop
uint8_t data[MAX_DATA_LENGTH] = {0}; //data that will be transmitted
uint8_t dataLength = 0; //length of data that will be transmitted

//application variables
bool button_pressed = false; //last state of the button
bool alarmThresholdTriggered = false; //last state on the alarm
uint8_t flashCount = 0; //how many more times to flash the LED

//timers
TimerEvent_t txTimer; //timer so schedule heartbeat transmissions 
TimerEvent_t ledTimer; //timer to blink LED


void onDownlinkConfirmation(){
    flashLED(BLINK_COUNT_DOWNLINK_CONFIRMATION);
}

void start(){
    //any initialization here
    
    //initilize LED flash timer
    TimerInit(&ledTimer, flashLEDCallback); 
    TimerSetValue( &ledTimer, TWO_HUNDRED_MILLISECONDS );
}

//this loop will start to be called as soon as the device successfully joins the network
void loop(){
    //the loop is called as soon as the device joins. Flash the led 10 times when this happens
    if (just_joined){
        just_joined = false;
        flashLED(BLINK_COUNT_JOINED);
    }
    
    //check if button was just pressed
    checkButton();
}

void checkButton(void){
    //button is pressed. Trigger once so that if we hold the button this block doesnt continously execute
    if (button == 1 && button_pressed == false){
        button_pressed = true;
        flashLED(BLINK_COUNT_EVENT_TRANSMIT);
        transmitData(rotary.read_u16());
    } else if (button == 0){
        button_pressed = false;
    }
}

//check if value passed in should trigger the alarm, if so, transmit
void checkAlarm(void){
    uint16_t position = rotary.read_u16();
    //check if should trigger alarm
    if(position / BYTE_TO_PERCENT > ALARM_THRESHOLD){
        //if the alarm has not already been triggered
        if(!alarmThresholdTriggered){
            alarmThresholdTriggered = true;//set the alarm to triggered
            flashLED(BLINK_COUNT_EVENT_TRANSMIT);
            transmitData(position);//transmit data
        }
    }
    else if(alarmThresholdTriggered){
        alarmThresholdTriggered = false;
    }
}

//start heartbeat timer. pass in how often in seconds it should transmit
void startHeartbeat(uint8_t time){
    TimerInit(&txTimer, timerCallback); 
    TimerSetValue( &txTimer,  time * 1000 * 1000);
    TimerStart(&txTimer);
}

//Transmit rotory position and alarm status
void transmitData(uint16_t position){  
    addRotaryData(position);            //add the rotary position to data
    
    setDataToSend(data, dataLength);    //set data to be transmitted
    sendLoraTransmission();             //queue transmission
    dataLength = 0;                     //reset data length so new data starts back at begining
}

//read the rotory position and add to data to transmit
void addRotaryData(uint16_t positionArg){
    uint16_t position = positionArg / (BYTE_TO_PERCENT / 100);
    
    data[dataLength++] = ROTATION_DATA_CHANNEL;
    data[dataLength++] = ROTATION_DATA_TYPE;
    data[dataLength++] = position >> 8;   //add the upper byte of the rotory position
    data[dataLength++] = position & 0xFF; //add the lower byte of the rotory position
}

//read the rotory position and add alarm status to data to transmit
void addAlarmData(uint16_t positionArg){
    int16_t position = positionArg / BYTE_TO_PERCENT;
    
    data[dataLength++] = ALARM_DATA_CHANNEL;
    data[dataLength++] = ALARM_DATA_TYPE;
    data[dataLength++] = (uint8_t)position >= ALARM_THRESHOLD; //add binary for it allar triggered or not
}

//start flash LED
void flashLED(uint8_t times){   
    if(flashCount == 0){             //if it is not currently flashing
        TimerStart(&ledTimer);      //start timer to toggle LED state
    }
    flashCount += times;            //set the number of times to flash
    led.write(1);                   //turn on LED 
}

//callback to change state of LED for blinking
void flashLEDCallback(){
    //if the LED is on, turn it off
    if(led.read() == 1){
        led.write(0);
        flashCount--;
        //if done flashing turn off the timer
        if(flashCount <= 0){
            TimerStop(&ledTimer);
        }
    }
    //if LED is off, turn it on
    else{
        led.write(1);
    }
}


//callback for transmission timer
void timerCallback(){
    flashLED(BLINK_COUNT_TIMER_TRANSMIT);
    transmitData(rotary.read_u16());
}