Level 2 Project Range Device
Dependencies: N5110 SDFileSystem SRF02 TMP102 mbed
Fork of Ranger by
main.h
- Committer:
- el15pjt
- Date:
- 2016-05-05
- Revision:
- 14:204562d1fac8
- Parent:
- 12:0171e8723d9d
File content as of revision 14:204562d1fac8:
/**
@file main.h
@brief Header file containing functions prototypes, defines and global variables.
@brief Ranger Project
@brief Revision 1.3.
@author Philip Thompson
@date 05 May 2016
@brief The following code has been writen for the University of Leeds ELEC264501 embedded system project and is intended to
create a programe that can read a distance from an SRF02 sensor and then based aponn the reading disply the distance on the screen
and increment the LEDs and buzzer according the provision of a temperature sensor is also provied as a secondary function when no
object is detected with in range.
@brief The Libarys N5110, TMP102,SRF02 and have been imported from the mbed libary wizard from user Craig evans are are not of my
own work.
@breif The SRF02 libary has been edited by my self so as to include a function to read the distance from the imperial distance registers
*/
#ifndef MAIN_H
#define MAIN_H
#include "mbed.h"
#include "mbed.h"
#include "SRF02.h"
#include "N5110.h"
#include "TMP102.h"
#include "SDFileSystem.h"
#define LOW 0 /// No output
#define HIGH 1 /// High output
/// for PC debug
Serial serial(USBTX, USBRX);
/**
@namespace LEDs
@brief Output for Alert LEDs
*/
DigitalOut rr_led (PTA1);
DigitalOut a_led (PTC2);
DigitalOut gg_led(PTB23);
/**
@namespace BOARDLEDs
@brief On board LEDs
*/
DigitalOut r_led(LED_RED);
DigitalOut g_led(LED_GREEN);
DigitalOut b_led(LED_BLUE);
/**
@namespace Buzzer
@brief PWM output for Buzzer
*/
PwmOut buzzer(PTA2);
/**
@namespace Buttons
@brief Button triggered Interrupts
*/
InterruptIn sw1(PTB19);
InterruptIn sw2(PTB18);
/**
@namespace Timers
@brief Tickers and Timeouts
*/
Ticker ticker; // Ticker to control LED flash
Ticker ticker_srf02; //Ticker to get distance reading
Ticker ticker_standby; //Ticker to control standby
Timeout buzzoff; //Buzzer off duratuion
Timeout buzzon; // buzzer on duration
// Create TMP102 object
TMP102 tmp102(I2C_SDA,I2C_SCL);
/**
@namespace Ranger
@brief Creat the Ranger object
*/
SRF02 srf02(I2C_SDA,I2C_SCL);
/**
@namespace LCD
@brief Creats the LCD object
*/
N5110 lcd(PTE26,PTA0,PTC4,PTD0,PTD2,PTD1,PTC3);
/// Connections to SD card holder on K64F (SPI interface)
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS
FILE *fp;
//FLAGS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/**
@namespace TimerFlags
@brief Flags for use with timed interupts
*/
volatile int g_timer_flag_led = 0, g_timer_flag_srf02 = 0; /** Flag rised by interupts*/
volatile int g_timer_flag_standby = 0;
volatile int buzz_flag = 0;
/**
@namespace ButtonFlages
@brief Flags for use with button interupts
*/
volatile int g_sw1_flag = 0, g_sw2_flag = 0;
//VERIABLES\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/// Upper limit of alert 1
int r1 = 03;
/// Upper limit of alert 2
int r2 = 10;
/// Upper limit of alert 3
int r3 = 20;
/// Upper limit of alert 4
int r4 = 30;
/// Upper limit of alert 5
int r5 = 40;
/// Upper limit of alert 6
int r6 = 50;
/// Upper limit of alert 7
int r7 = 70;
/// Veriable to hold sumation of distance readings for mean vale calculation
int totaldistance;
///< veriable to hold the page being viewed with in the submenu
int subpage;
/// veriable to hold the page being viewed with in the menu
int page;
/// veriable to hold the offset and adjust the 0 Range point
int offset = 0;
/// veriable to hold the current alert level
int alert;
/// veriable to hold the distance read from the srf02 sensor
int distance;
/// veriable to hold the current unit type set to 1 = METRIC as default
int units = 1;
///standby state 1. path clear 2. Temp 3.Temp no backlight
int standby = 0;
///flag raised is there is a collision
int check_flag = 0;
/// Temp reading return from TMP120 sensor
float Traw;
/// veriable to hold the current LED backlight of the 5110 LCD
float bright = 1.0;
/// Temperature value retured from TMP102 sensor
float T;
/// Veriable to hold the distance across the screen the distance bar should go
float distbar;
/// Averaged Distance vale from ten previous readings
float avgdistance =0;
/// convertion factor from Cm to inch 1 = metric no convertion
float c =1;
// each character is 6 pixels wide, screen is 84 pixels (84/6 = 14) not needed to be globle but reused frquently throuhout
char buffer[14], buffer1[14], buffer2[14], buffer3[14], buffer4[14],buffer5[14];
/*!< Stucture to hold all outputs. Steady LEDs, Flashing LEDs, Tone on, Tonne off*/
struct Alertlevel {
char srr_led; /// stead RED LED state
char sa_led; /// stead AMBER LED state
char sgg_led; /// stead GREEN LED state
char frr_led;///FLASHING RED LED state
char fa_led; ///FLASHING AMBER LED state
char fgg_led; ///FLASHING GREEN LED state
float toneon; ///Tone on time
float toneoff; ///Tone off time
};
typedef const struct Alertlevel STyp;
/*!< Array contaning structures for diffent outputs */
STyp Alertlevel[8] = {
{LOW,LOW,LOW,LOW,LOW,LOW,0,1}, // no output
{LOW,LOW,LOW,LOW,LOW,HIGH,0.1,1.0}, //flash green
{LOW,LOW,HIGH,LOW,LOW,LOW,0.1,0.5}, //steady green
{LOW,LOW,HIGH,LOW,HIGH,LOW,0.1,0.25}, //flash amber
{LOW,HIGH,HIGH,LOW,LOW,LOW,0.1,0.1}, //steady amber
{LOW,HIGH,HIGH,HIGH,LOW,LOW,0.2,0.1}, //flash red
{HIGH,HIGH,HIGH,LOW,LOW,LOW,0.1,0.05},// steady red
{LOW,LOW,LOW,HIGH,HIGH,HIGH,1,0} // all flash
};/*!< Array contaning structures for diffent outputs */
//FUNCTIONS/////////////////////////////////////////////
/**
Function called to stop buzzer at end of on period and then make buzzer avilable again after off period
@param buzz_flag 1 or 0
@param buzzer = 0.0 buzzer off
@code
{
buzz_flag = 1;
buzzer = 0.0;
buzzon.attach(&buzzflag,Alertlevel[alert].toneoff);
}
@endcode
*/
void flip();
/** Flag used it indicate if buzzer is avilable or on a off period
@param buzz_flag zero
@code
{
buzz_flag = 0;
return;
}
@endcode
*/
void buzzflag();
/** Controls the LCD while not in a Menu
@param i used to scale the max distaance to the width of the screen
@param distance Distance read from sensor to be dispayed
@param distbar used to adjust how far along the screen the bar is to go acorrding to distance
@code
if (alert == 0) {
if (g_timer_flag_standby) {
g_timer_flag_standby = 0;
T = tmp102.get_temperature();
standby++;
if (standby >3) {
standby = 3;
}
}
switch (standby) {
case 1:
if (check_flag == 1) {
sprintf(buffer4,"COLLISIONCHECK");
}
lcd.clear();
sprintf(buffer,"**PATH CLEAR**");
lcd.printString(buffer,0,0);
lcd.printString(buffer4,0,5);
lcd.refresh();
break;
case 2:
if (check_flag == 1) {
sprintf(buffer4,"COLLISIONCHECK");
lcd.clear();
sprintf(buffer3,"TEMP = %.2f",T);
sprintf(buffer2,"TEMPERATER");
lcd.printString(buffer3,4,2);
lcd.printString(buffer2,12,1);
lcd.printString(buffer4,0,5);
break;
case 3:
if (check_flag == 1) {
sprintf(buffer4,"COLLISIONCHECK");
lcd.clear();
sprintf(buffer3,"TEMP = %.2f",T);
sprintf(buffer2,"TEMPERATER");
lcd.refresh();
lcd.printString(buffer3,4,2);
lcd.printString(buffer2,12,1);
lcd.printString(buffer4,0,5);
lcd.setBrightness(0);
break;
}
}
//If alert isn't 0 then the distance is to be dispayed alonng with the the distance bar
else {
lcd.setBrightness(bright);
standby =0;
lcd.clear();
if (units == 1) {
sprintf(buffer,"%0.2f Cm",avgdistance);
sprintf(buffer1,"****RANGE!****");
sprintf(buffer2,"DISTANCE");
sprintf(buffer4,"Menu");
} else {
sprintf(buffer,"%0.2f Inches",avgdistance);
sprintf(buffer1,"****RANGE!****");
sprintf(buffer2,"***DISTANCE***");
sprintf(buffer4,"Menu");
}
lcd.printString(buffer,25,2);
lcd.printString(buffer1,0,0);
lcd.printString(buffer2,16,1);
lcd.printString(buffer4,0,5);
float h = (r7/84);
float distbar = (avgdistance*h);
//drawRect(int x0,int y0,int width,int height,int fill);
lcd.drawRect(0,29,distbar,7,1); //
lcd.refresh();
@endcode
*/
void lcdoutput();
/** Called to increment to brightness by 0.2 each time when at 1 resets back to 0.0
@param bright 0.0-1
@returns lcd.setbrightness
@code
if (bright == 1.0) {
bright = 0;
} else {
bright += 0.2;
}
lcd.setBrightness(bright);
@endcode
*/
void backlight();
/**
Sets up and initalizies switches, LEDs, Tickers and serial connection
@code
{
serial.baud(115200); // full-speed!
ticker.attach(&timer_isr_led,0.35); /// Attach the ticker for the flashig LEDs
ticker_srf02.attach(&timer_isr_srf02,0.2);/// Attach the ticker for collecting a range reading
ticker_standby.attach(&timer_isr_standby,5.0);
sw1.rise(&sw1_isr); /// sw1_isr called when button presed on the rising edge
sw2.rise(&sw2_isr); /// sw2_isr called when button presed on the rising edge
r_led = 1; //Onboard leds
b_led = 1; //Onboard leds
g_led = 1; //Onboard leds
rr_led = 0; //PCB LEDS
a_led = 0; //PCB LEDS
gg_led = 0; //PCB LEDS
sw2.mode(PullDown); //Turns on use of the pulldown resistors for use with the PCB buttons
sw1.mode(PullDown); //Turns on use of the pulldown resistors for use with the PCB buttons
}
@endcode
*/
void setup();
/** A fuction used to determin the alert level given a range with the use of IF statments
@param distance The distance read from sensor
@param alert The level that distance falls with in 0 -7
@returns alert
@code
if (distance >= r6 && distance < r7) { // r6 150 and r7 200
alert = 1; /// alert 1 distance between preset 150Cm to 200Cm
} else if (distance >= r5 && distance < r6) {
alert = 2; /// alert 2 when between preset 90Cm to 150Cm
} else if (distance >= r4 && distance < r5) {
alert = 3; /// alert 3 when distance between 60Cm to 90Cm
} else if (distance >= r3 && distance < r4) {
alert = 4; /// alert 4 when distance between 40Cm and 60Cm
} else if ( distance > r2 && distance < r3) {
alert = 5; ///alert 5 when distance between 20Cm and 40m
} else if (distance > r1 && distance <= r2) { //r1 3 and r2 20
alert = 6; ///alert 6 when distance between 1 and 20
} else if (distance <=r1) {
alert = 7; ///alert 7 when distance below 1Cm
} else {
alert = 0; /// alert 0 all else
}
}
@endcode
*/
void setalert();
/** Function for controlling the LED outputs
@para alert changes to element array and so output controlls
@code
{
int flash = 0; ///Variable to toggle LEDs high low
if (g_timer_flag_led) {
g_timer_flag_led = 0;
flash = !flash; // if it has, clear the flag
}
if(Alertlevel[alert].fa_led == HIGH) {
a_led = flash;
} else {
a_led = Alertlevel[alert].sa_led;
}
if (Alertlevel[alert].frr_led == HIGH) {
rr_led = flash;
} else {
rr_led = Alertlevel[alert].srr_led;
}
if(Alertlevel[alert].fgg_led == HIGH) {
gg_led = flash;
} else {
gg_led = Alertlevel[alert].sgg_led;
}
}
@endcode
*/
void setleds();
/**
@code
{
control the PWM to drive the buzzer
@param buzzer.period frequncy 1KHz
@param buzzer duty cycle equal on/off max volume
@param Alertlevel[alert].toneon controls how long the tone will last depending on alert
buzzer.period (1.0/1000.0);
buzzer = 0.5;
buzzoff.attach(&flip, Alertlevel[alert].toneon);
}
@endcode
*/
void setbuzzer();
/**
Function used to call and navigate Main menu and change settings
@code
{
while(1) {
if (g_sw1_flag) {
g_sw1_flag = 0;
page++; // Moves page
lcd.clear();
}
switch (page) {
case 0:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
backlight();
lcd.clear();
}
int lightbar = bright*84;
sprintf(buffer2,"%.0f%%",bright*100);
lcd.drawRect(0,26,lightbar,7,1); // move bar up!!!!!!!!!!!!!!!!
lcd.printString("BACKLIGHT",0,1);
lcd.printString(buffer2,0,2);
lcd.printString("NEXT ADJ",0,5);
lcd.refresh();
break;
case 1:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (offset == 20) {
offset = 0;
lcd.clear();
} else {
offset += 1;
}
}
sprintf(buffer2,"%i",offset);
lcd.printString("OFFSET",0,1);
sprintf(buffer4,"NEXT ADJ");
lcd.printString(buffer4,0,5);
break;
case 2:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (units == 1) {
units = 0;
c = 0.3937;
} else {
units = 1;
c = 1;
lcd.clear();
}
}
if (units == 0) {
sprintf(buffer2,"IMPERIAL");
} else {
sprintf(buffer2,"METRIC");
}
lcd.printString("NEXT ADJ",0,5);
lcd.printString("UNITS",0,1);
break;
case 3:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
check_flag =0;
lcd.clear();
}
if (check_flag == 0) {
sprintf(buffer2,"COLLISION");
lcd.printString("NO",0,1);
sprintf(buffer4,"NEXT ");
} else {
sprintf(buffer2,"COLLISION");
lcd.printString("CLEAR",0,1);
sprintf(buffer4,"NEXT CLEAR");
}
lcd.printString(buffer4,0,5);
break;
case 4:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
bright = 1.0;
offset = 0;
units = 1;
r1 = 03;// Upper limit of alert 1
r2 = 10;// Upper limit of alert 2
r3 = 20;// Upper limit of alert 3
r4 = 30;// Upper limit of alert 4
r5 = 50;// Upper limit of alert 5
r6 = 60;// Upper limit of alert 6
r7 = 80;// Upper limit of alert 7
lcd.clear();
lcd.printString("SETTINGS",0,1);
lcd.printString("RESET",0,2);
wait(1);
return;
}
sprintf(buffer2,"SETTINGS");
lcd.printString("RESET",0,1);
lcd.printString("NEXT RESET",0,5);
break;
case 5:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
submenu();
}
sprintf(buffer2,"PARAMETERS");
lcd.printString("RANGE",0,1);
lcd.printString("EXIT ADJ",0,5);
break;
default:
lcd.clear();
save ();
lcd.printString(" SAVING ",0,2);
lcd.printString(" SETTINGS ",0,3);
wait (1);
return;
}// switch bracket
lcd.printString(buffer2,0,2);
lcd.printString("*****MENU*****",0,0);
lcd.refresh();
}//while braket
}//functon bracket
@endcode
*/
void menu();
/**
Function for submenu Controlling the range peramiters
@code
{
while(1) {
/// interupt used to shift page
if (g_sw1_flag) {
g_sw1_flag = 0;
subpage++;
}
switch (subpage) { ///interupt used to adjust range
case 0:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r2 == r3) {
r2 = 3;
} else {
r2 = r2+1;
}
}
sprintf(buffer4,"1Cm to %iCm",r2);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("NEXT ADJ",0,5);
break;
case 1:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r3 == r4) {
r3 = r2;
} else {
r3 += 1;
}
}
sprintf(buffer4,"%iCm to %iCm",r2,r3);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("NEXT ADJ",0,5);
break;
case 2:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r4 == r5) {
r4 = r3;
} else {
r4 += 1;
}
}
sprintf(buffer4,"%iCm to %iCm",r3,r4);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("NEXT ADJ",0,5);
break;
case 3:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r5 == r6) {
r5 = r4;
} else {
r5 += 1;
}
}
sprintf(buffer4,"%iCm to %iCm",r4,r5);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("NEXT ADJ",0,5);
break;
case 4:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r6 == r7) {
r6 = r5;
} else {
r6 += 1;
}
}
sprintf(buffer4,"%iCm to %iCm",r5,r6);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("NEXT ADJ",0,5);
break;
case 5:
if (g_sw2_flag) {
g_sw2_flag = 0; // if it has, clear the flag
if (r7 == 300) {
r7 = r6;
} else {
r7 += 1;
}
}
sprintf(buffer4,"%iCm to %iCm",r6,r7);
lcd.printString("*****MENU*****",0,0);
lcd.printString("RANGE",0,1);
lcd.printString("PARAMETERS",0,2);
lcd.printString(buffer4,0,3);
lcd.printString("EXIT ADJ",0,5);
break;
default:
lcd.clear();
return;
}//switch breaket
}//while bracket
}//function bracket
@endcode
*/
void submenu();
/**
Save function saving settings
@param bright - Backlight setting
@param units - Metric or Imperial settings
@param offset - offest distance setting
@param check_flag - Saves a collision alert
@param r1 - upper limit for alert 1
@param r2 - upper limit for alert 2
@param r3 - upper limit for alert 3
@param r4 - upper limit for alert 4
@param r5 - upper limit for alert 5
@param r6 - upper limit for alert 6
@param r7 - upper limit for alert 7
@code
{
fp = fopen("/sd/settings.txt", "w");
if (fp == NULL) { // if it can't open the file then print error message
serial.printf("Error! Unable to open file!\n");
} else { // opened file so can write
serial.printf("Writing to file....");
fprintf(fp, "%f,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",bright,units,offset,check_flag,r1,r2,r3,r4,r5,r6,r7); // ensure data type matches
serial.printf("Done.\n");
fclose(fp); // ensure you close the file after writing
}
}
@endcode
*/
void save();
/**
Inturupt flag for button 2
@code
{
g_sw2_flag = 1; //set flag in ISR by button 2 @param g_sw2_flag 0 or 1
}
@endcode
*/
void sw2_isr();
/**
Inturupt flag for button 1
@code
{
g_sw1_flag = 1; //set flag in ISR by button 2 @param g_sw1_flag 0 or 1
}
@endcode
*/
void sw1_isr();
/**
Flag used with ticker for flashing of LEDs
@code
{
g_timer_flag_led = 1; // set flag in ISR by timer_isr_led @param g_timer_flag_led 0 or 1
}
@endcode
*/
void timer_isr_led();
/**
Flag used for Ticker controlling SRF02 sensor reading
@code
{
g_timer_flag_srf02 = 1; // set flag in ISR by ticker_srf02 @param g_timer_flag_srf02 0 or 1
}
@endcode
*/
void timer_isr_srf02();
/**
Flag raised for incrementing standby level
@code
{
g_timer_flag_standby = 1; // set flag in ISR by ticker_tone @param g_timer_flag_tone 0 or 1
}#
@endcode
*/
void timer_isr_standby();
#endif
