Workshop demo program

Dependencies:   PinDetect mbed LoRaWAN-lib SX1272Lib

app/app.cpp

Committer:
Brandond200
Date:
2017-05-03
Revision:
19:31fc997c460b
Parent:
18:326069443137

File content as of revision 19:31fc997c460b:

#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
volatile bool sending = false;
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
uint16_t checkCount = 0; 

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


void onDownlinkConfirmation(){
    flashLED(BLINK_COUNT_DOWNLINK_CONFIRMATION);
    TimerStop(&txEndTimer);
    sending = false;
}

void onDownlinkUnconfirmed(){
    TimerStop(&txEndTimer);
    sending = false;
}

void start(){
    //any initialization here

    //initilize LED flash timer
    TimerInit(&ledTimer, flashLEDCallback); 
    TimerSetValue( &ledTimer, TWO_HUNDRED_MILLISECONDS );
 
     //initilize txTimeout timer
    TimerInit(&txEndTimer, txTimeoutCallback); 
    TimerSetValue( &txEndTimer, 1000*1000*15 );   
    
}

//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){
    checkCount++;
    if(checkCount > 5000){
        checkCount = 0;
        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(position / BYTE_TO_PERCENT < (ALARM_THRESHOLD - 1)){
            if(alarmThresholdTriggered){
                //alarm just changed state to not triggered
                flashLED(BLINK_COUNT_EVENT_TRANSMIT);
                transmitData(position);//transmit data
                alarmThresholdTriggered = false;
            }
        }
    }
}

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

//Transmit rotory position and alarm status
void transmitData(uint16_t position){  
    if(!sending){
        sending = true;
        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
        TimerStart(&txEndTimer);
    }
}

//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 alarm 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
    //make sure it is not set to high
    if(flashCount > 10){
            flashCount = 10;
    }
    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());
}

void txTimeoutCallback(){
    sending = false;
    TimerStop(&txEndTimer);
}