(DA) Internet of Things and Smart Electronics- ELE3006M2122 / Mbed 2 deprecated Final_Project_V18_DLeaming_25574043

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* 
00002 * Prints a string of characters to the screen buffer, string is cut off after the 83rd  pixel.
00003 * @param x - the column number (0 to 83)
00004 * @param y - the row number (0-5) - the display is split into 6 banks - each bank can be considered a row
00005 *
00006 * @ File main.cpp
00007 * @ Author - David Leaming - 25574043
00008 * @ Date - January 2022
00009 *
00010 * Acknowledgements 
00011 * Craig A. Evans, University of Leeds, TMP102 Library, Feb 2016
00012 * Dr Edmond Nurellari, University of Lincoln, Joystick, N5110 Libraries & SD Card Libraries
00013 * Paul Staron, Piezo Buzzer utility, April 2019
00014 */ 
00015 
00016 #include "mbed.h"                                                               // Include the library header, ensure the library has been imported into the project
00017 #include "TMP102.h"                                                             //
00018 #include "N5110.h"                                                              //
00019 #include "Joystick.h"                                                           //
00020 #include "Bitmap.h"                                                             //
00021 #include "SDFileSystem.h"                                                       //
00022                                                                                 //
00023 TMP102 tmp102(I2C_SDA,I2C_SCL);                                                 // Create TMP102 object  
00024                                                                                 //
00025 //        VCC,SCE,RST,D/C,MOSI,SCLK,LED                                         //    
00026 N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);                                      // Create Screen Object - K64F - pwr from 3V3, GND Pin also needs connecting
00027                                                                                 //
00028 //                  y     x     button                                          //    
00029 Joystick joystick(PTB10,PTB11,PTC16);                                           // Define Joystick Object 
00030                                                                                 //        
00031 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");                                  // MOSI, MISO, SCK, CS - Connections to SD card holder on K64F (SPI interface)
00032                                                                                 //
00033 Serial pc(USBTX,USBRX);                                                         // UART connection for PC
00034                                                                                 //
00035 struct State {                                                                  // Struct for state
00036     int output;                                                                 // output value
00037     float time;                                                                 // time in state
00038     int nextState[9];                                                           // array of next states
00039 };                                                                              //
00040                                                                                 //
00041 State fsm[11] = {                                                               //
00042     {15,0.5,{0,1,0,0,0,10,0,0,0}},                                              // State 0 - 15 Degrees
00043     {16,0.5,{1,2,1,1,1,0,1,1,1}},                                               // State 1 - 16 Degrees
00044     {17,0.5,{2,3,2,2,2,1,2,2,2}},                                               // State 2 - 17 Degrees
00045     {18,0.5,{3,4,3,3,3,2,3,3,3}},                                               // State 3 - 18 Degrees
00046     {19,0.5,{4,5,4,4,4,3,4,4,4}},                                               // State 4 - 19 Degrees
00047     {20,0.5,{5,6,5,5,5,4,5,5,5}},                                               // State 5 - 20 Degrees
00048     {21,0.5,{6,7,6,6,6,5,6,6,6}},                                               // State 6 - 21 Degrees
00049     {22,0.5,{7,8,7,7,7,6,7,7,7}},                                               // State 7 - 22 Degrees
00050     {23,0.5,{8,9,8,8,8,7,8,8,8}},                                               // State 8 - 23 Degrees
00051     {24,0.5,{9,10,9,9,9,8,9,9,9}},                                              // State 9 - 24 Degrees
00052     {25,0.5,{10,1,10,10,10,9,10,10,10}}                                         // State 10 - 25 Degrees   
00053 };                                                                              //
00054                                                                                 //
00055 Ticker ticker_menu;                                                             // Create Menu ticker object
00056                                                                                 //        
00057 DigitalOut r_led(LED_RED);                                                      // K64F on-board LEDs 
00058 DigitalOut g_led(LED_GREEN);                                                    // K64F on-board LEDs 
00059 DigitalOut b_led(LED_BLUE);                                                     // K64F on-board LEDs 
00060                                                                                 //
00061 PwmOut LED01 (PTA1);                                                            // PCB Surface Mounted LED's - LED1
00062 PwmOut LED02 (PTA2);                                                            // PCB Surface Mounted LED's - LED2
00063 PwmOut LED03 (PTC2);                                                            // PCB Surface Mounted LED's - LED3
00064 PwmOut LED04 (PTC3);                                                            // PCB Surface Mounted LED's - LED4
00065 PwmOut LED05 (PTC4);                                                            // PCB Surface Mounted LED's - LED5
00066 PwmOut LED06 (PTD3);                                                            // PCB Surface Mounted LED's - LED6
00067                                                                                 //    
00068 PwmOut Buzzer (PTC10);                                                          // PCB Surface Mounted Piezo Buzzer
00069                                                                                 //
00070 InterruptIn sw2(SW2);                                                           // K64F on-board switches
00071 InterruptIn sw3(SW3);                                                           // K64F on-board switches
00072 InterruptIn ButtonA (PTB9);                                                     // PCB Button - A
00073 InterruptIn ButtonB (PTD0);                                                     // PCB Button - B
00074 InterruptIn ButtonBack (PTB10);                                                 // PCB Button - Back
00075                                                                                 //
00076 volatile int g_ButtonA_flag = 0;                                                // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
00077 volatile int g_ButtonB_flag = 0;                                                // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
00078 volatile int g_ButtonBack_flag = 0;                                             // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
00079 volatile int g_sw2_flag = 0;                                                    // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
00080 volatile int g_menu_timer_flag = 0;                                             // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
00081 volatile int option = 0;                                                        // Menu option selection based on joystick direction
00082 volatile int g_state = 0;                                                       // 
00083 volatile int g_StartTemp = 0;                                                   // 
00084 volatile float g_TempReading = 0.0f;                                            //
00085                                                                                 //
00086 void error();                                                                   // error function hangs flashing an LED
00087 void init_serial();                                                             // setup serial port
00088 void init_K64F();                                                               // set-up the on-board LEDs and switches
00089 void init_PCB();                                                                // set-up the PCB LEDs and buttons
00090 void ButtonA_isr();                                                             // 
00091 void ButtonB_isr();                                                             // 
00092 void ButtonBack_isr();                                                          // 
00093 void sw2_isr();                                                                 // 
00094 void menu_timer_isr();                                                          // 
00095 void OnStartup();                                                               // 
00096 void Run();                                                                     // 
00097 void StartTemp();                                                               //
00098 void delete_file(char filename[]);                                              //
00099 void HighTemp();                                                                //
00100 void SuperHighTemp();                                                           //
00101 void UltraHighTemp();                                                           //
00102 void LowTemp();                                                                 //
00103 void SuperLowTemp();                                                            //
00104 void UltraLowTemp();                                                            //
00105 void PeripheralsOffHigh();                                                      //
00106 void PeripheralsOffLow();                                                       // 
00107                                                                                 // 
00108 int main()                                                                      //
00109 {                                                                               //
00110     init_K64F();                                                                // Initialise the board
00111     init_serial();                                                              // initialise the serial port
00112     init_PCB();                                                                 // Initialise the PCB
00113                                                                                 //
00114     tmp102.init();                                                              // Call the sensor init method using dot syntax
00115     lcd.init();                                                                 // Initialise display
00116     joystick.init();                                                            // Initialise joystick
00117                                                                                 //        
00118     ticker_menu.attach(&menu_timer_isr,0.2);                                    // Attach ticker for the Joystick
00119                                                                                 //
00120     sw2.fall(&sw2_isr);                                                         // SW2 has a pull-up resistor, so the pin will be at 3.3 V by default and fall to 0 V when pressed. We therefore need to look for a falling edge on the pin to fire the interrupt
00121     ButtonA.rise(&ButtonA_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
00122     ButtonB.rise(&ButtonB_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
00123                                                                                 //
00124     lcd.setContrast(0.5);                                                       // change set contrast in range 0.0 to 1.0
00125                                                                                 //
00126     OnStartup();                                                                // Call intro screen   
00127     Run();                                                                      // Call main-menu and functions
00128 }                                                                               //
00129                                                                                 //
00130 void init_serial() {                                                            //
00131     pc.baud(115200);                                                            // set to highest baud - ensure terminal software matches
00132 }                                                                               //        
00133                                                                                 //
00134 void init_K64F()                                                                //
00135 {                                                                               // 
00136     r_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00137     g_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00138     b_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00139                                                                                 //
00140     sw2.mode(PullNone);                                                         // since the on-board switches have external pull-ups, we should disable the internal pull-down
00141     sw3.mode(PullNone);                                                         // resistors that are enabled by default using InterruptIn
00142 }                                                                               //
00143                                                                                 //
00144 void init_PCB ()                                                                //        
00145 {                                                                               //        
00146     LED01 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00147     LED02 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00148     LED03 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00149     LED04 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
00150     LED05 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00151     LED06 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
00152                                                                                 //
00153     Buzzer = 0;                                                                 // Ensure Piezo Buzzer is off
00154                                                                                 //
00155     ButtonA.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
00156     ButtonB.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
00157 }                                                                               //        
00158                                                                                 //
00159 void ButtonA_isr()                                                              // ButtonA event-triggered interrupt
00160 {                                                                               //
00161     g_ButtonA_flag = 1;                                                         // set flag in ISR
00162 }                                                                               //        
00163                                                                                 //
00164 void ButtonB_isr()                                                              // ButtonB event-triggered interrupt
00165 {                                                                               //
00166     g_ButtonB_flag = 1;                                                         // set flag in ISR
00167 }                                                                               //
00168                                                                                 //
00169 void ButtonBack_isr()                                                           // ButtonB event-triggered interrupt
00170 {                                                                               //
00171     g_ButtonBack_flag = 1;                                                      // set flag in ISR
00172 }                                                                               //
00173                                                                                 //
00174 void sw2_isr()                                                                  // SW2 event-triggered interrupt
00175 {                                                                               //
00176     g_sw2_flag = 1;                                                             // set flag in ISR
00177 }                                                                               //
00178                                                                                 //    
00179 void menu_timer_isr()                                                           //
00180 {                                                                               //
00181     g_menu_timer_flag = 1;                                                      // set flag in ISR
00182 }                                                                               //
00183                                                                                 //        
00184 void OnStartup()                                                                // Run some start up display 
00185 {                                                                               //
00186     Buzzer.period(1.0/659.0);                                                   // Welcome sounds from Piezo
00187     Buzzer = 0.5;                                                               //                   
00188     wait(0.5);                                                                  // 
00189     Buzzer.period(1.0/494.0);                                                   // 
00190     Buzzer = 0.5;                                                               //    
00191     wait(0.5);                                                                  // 
00192     Buzzer.period(1.0/554.0);                                                   // 
00193     Buzzer = 0.5;                                                               // 
00194     wait(0.5);                                                                  // 
00195     Buzzer = 0;                                                                 // Turn off welcome sounds 
00196     lcd.clear();                                                                // Clear buffer at start of every loop
00197     lcd.printString("--------------",0,0);                                      // Can directly print strings at specified co-ordinates (must be less than 84 pixels to fit on display)
00198     lcd.printString("  Smart Cold",0,1);                                        // Just a welcome message before auto moving to main menu
00199     lcd.printString("   Storage",0,2);                                          //
00200     lcd.printString("  Monitoring",0,3);                                        // 
00201     lcd.printString("V18 - Jan 2022",0,4);                                      //
00202     lcd.printString("--------------",0,5);                                      //
00203     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings 
00204     wait(5.0);                                                                  // Leave welcome screen on for designated amount of time
00205     lcd.clear();                                                                // Clear buffer at start of every loop
00206     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings 
00207     lcd.printString("--------------",0,0);                                      //
00208     lcd.printString(" Use Joystick",0,1);                                       // Instruction for use of menu
00209     lcd.printString(" To Navigate",0,2);                                        //
00210     lcd.printString("",0,3);                                                    // Blank Line
00211     lcd.printString("  A = Select",0,4);                                        //
00212     lcd.printString("--------------",0,5);                                      //
00213     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings
00214     wait(5.0);                                                                  //
00215     init_PCB();                                                                 // Ran again to ensure all LED's etc are turned off
00216     printf("Transition to Temp Selection %i\n",StartTemp);                      // Observe on serial port - ensure transition to correct screen
00217 }                                                                               //
00218                                                                                 //
00219 enum EMenuState                                                                 // An enum controlling the current state of the display.
00220 {                                                                               //
00221     MENUSTATE_StartTemp,                                                        // Defining each menu state to be called upon later (Integer Value of 0)
00222     MENUSTATE_Main,                                                             // Defining each menu state to be called upon later (Integer Value of 1)
00223     MENUSTATE_Monitor,                                                          // Defining each menu state to be called upon later (Integer Value of 2)
00224     MENUSTATE_OneOff,                                                           // Defining each menu state to be called upon later (Integer Value of 3)
00225     MENUSTATE_Results,                                                          // Defining each menu state to be called upon later (Integer Value of 4)
00226     MENUSTATE_About,                                                            // Defining each menu state to be called upon later (Integer Value of 5)
00227     MENUSTATE_Author,                                                           // Defining each menu state to be called upon later (Integer Value of 6)
00228                                                                                 //    
00229     MENUSTATTE_Num,                                                             // This is a special enum value that allows us to check and see how many menus we have, +1 of menu integer value
00230 };                                                                              //
00231                                                                                 //
00232 void Run()                                                                      //
00233 {                                                                               //    
00234     int MenuState = MENUSTATE_StartTemp;                                        // Ensuring that the first Menu State to be brought up is the Temperature Selection Page 
00235     int SelectedItem = 0;                                                       // 
00236     int NumMenuItems = 1;                                                       // 
00237     int NumFramesInState = 0;                                                   // How many frames have we been in the current menu state.
00238                                                                                 //    
00239     char buffer[14];                                                            // Each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
00240                                                                                 //
00241     FILE *fp = NULL;                                                            // This is our file pointer
00242                                                                                 //
00243     while(1){                                                                   // Project infinite while loop       
00244         if (g_menu_timer_flag){                                                 //        
00245             g_menu_timer_flag = 0;                                              // 
00246                                                                                 //
00247             bool bAButtonWasPressed = g_ButtonA_flag;                           // Get the value of the input flags and reset them
00248             bool bBButtonWasPressed = g_ButtonB_flag;                           // Get the value of the input flags and reset them
00249             g_ButtonA_flag = 0;                                                 // 
00250             g_ButtonB_flag = 0;                                                 // 
00251                                                                                 //
00252             lcd.clear();                                                        // Clear buffer at start of every loop
00253                                                                                 //
00254             int NewMenuState = MENUSTATTE_Num;                                  // The new menu we want to transition to, if any.
00255                                                                                 //
00256             switch(MenuState)                                                   // Update and Draw whichever menu we're on.
00257             {                                                                   //
00258                 case MENUSTATE_StartTemp:                                       //
00259                 {                                                               //
00260                     NumMenuItems = 1;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
00261                     if(SelectedItem >= NumMenuItems)                            // 
00262                     {                                                           //
00263                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
00264                     }                                                           //
00265                     Direction d = joystick.get_direction();                     //          
00266                                                                                 //    
00267                     StartTemp();                                                //
00268                                                                                 //
00269                     float g_StartTemp = fsm[g_state].output;                    // Read temperature from FSM and print selection to LCD
00270                     pc.printf("T = %f C\n",g_StartTemp);                        // Print to serial - allows testing without device attached
00271                     printf ("Joystick Direction Points = %i\n",d);              //
00272                     printf ("State selected = %i\n", g_state);                  //
00273                     int length = sprintf(buffer," T = %.2f C",g_StartTemp);     // Print formatted data to buffer - it is important the format specifier ensures the length will fit in the buffer
00274                     if (length <= 14){                                          // If string will fit on display (assuming printing at x=0)
00275                         lcd.printString("- Set Target -",0,0);                  // 
00276                         lcd.printString("---- Temp ----",0,1);                  // 
00277                         lcd.printString(buffer,0,3);                            // Display on screen
00278                         lcd.printString("'A' to Select",0,5);                   //                      
00279                         lcd.refresh();                                          //
00280                     }                                                           // need to refresh display after setting pixels or writing strings 
00281                                                                                 //
00282                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
00283                     {                                                           //    
00284                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
00285                         {                                                       // Actually 0 line + 1, see circle draw and selection below
00286                             NewMenuState = MENUSTATE_Main;                      // 
00287                         }                                                       //
00288                     }                                                           //
00289                 }                                                               //
00290                 break;                                                          //         
00291                 case MENUSTATE_Main:                                            //
00292                 {                                                               //    
00293                     NumMenuItems = 5;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
00294                     if(SelectedItem >= NumMenuItems)                            // 
00295                     {                                                           //
00296                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
00297                     }                                                           // 
00298                     lcd.printString("---- MENU ----",0,0);                      // Menu title and selectable options    
00299                     lcd.printString("M1 - Monitor",0,1);                        // Printed to the LCD screen
00300                     lcd.printString("M2 - One-off",0,2);                        // 
00301                     lcd.printString("Results",0,3);                             //
00302                     lcd.printString("About",0,4);                               //
00303                     lcd.printString("Author",0,5);                              // 
00304                                                                                 // 
00305                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
00306                     {                                                           // 
00307                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
00308                         {                                                       // Actually 0 line + 1, see circle draw and selection below
00309                             NewMenuState = MENUSTATE_Monitor;                   // 
00310                         }                                                       // 
00311                         else if(SelectedItem == 1)                              // If 1 line is selected, move to detailed menu 
00312                         {                                                       // Actually 1 line + 1, see circle draw and selection below
00313                             NewMenuState = MENUSTATE_OneOff;                    // 
00314                         }                                                       // 
00315                         else if(SelectedItem == 2)                              // If 2 line is selected, move to detailed menu 
00316                         {                                                       // Actually 2 line + 1, see circle draw and selection below
00317                             NewMenuState = MENUSTATE_Results;                   // 
00318                         }                                                       //
00319                         else if(SelectedItem == 3)                              // If 3 line is selected, move to detailed menu 
00320                         {                                                       // Actually 3 line + 1, see circle draw and selection below
00321                             NewMenuState = MENUSTATE_About;                     // 
00322                         }                                                       //        
00323                         else if(SelectedItem == 4)                              // If 4 line is selected, move to detailed menu 
00324                         {                                                       // Actually 4 line + 1, see circle draw and selection below
00325                             NewMenuState = MENUSTATE_Author;                    // 
00326                         }                                                       //
00327                     }                                                           //
00328                 }                                                               //
00329                 break;                                                          // 
00330                 case MENUSTATE_Monitor:                                         // Call constant measurement menu following top menu selection
00331                 {                                                               //
00332                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00333                                                                                 //
00334                     if(SelectedItem >= NumMenuItems)                            // 
00335                     {                                                           //
00336                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00337                     }                                                           //        
00338                                                                                 //
00339                     float T = tmp102.get_temperature();                         // read temperature and print to lcd
00340                     pc.printf("T = %f C\n",T);                                  // Print to serial - allows testing without device attached
00341                     int length = sprintf(buffer," T = %.2f C",T);               // print formatted data to buffer - it is important the format specifier ensures the length will fit in the buffer
00342                     if (length <= 14)                                           // if string will fit on display (assuming printing at x=0)
00343                     lcd.printString("-- Constant --",0,0);                      // 
00344                     lcd.printString("- Monitoring -",0,1);                      // 
00345                     lcd.printString(buffer,0,3);                                // display on screen
00346                     lcd.printString(" 'A' to Menu",0,5);                        // 
00347                     lcd.refresh();                                              // need to refresh display after setting pixels or writing strings 
00348                     wait(0.5);                                                  // 
00349                                                                                 //
00350                     if (T >= g_StartTemp + 2 and T < g_StartTemp + 4) {         // High temp alarm condition - in real world would be lot lower!!
00351                         HighTemp();                                             //  
00352                     }                                                           //
00353                     else  {                                                     //
00354                         PeripheralsOffHigh();                                   //
00355                     }                                                           //
00356                     if (T >= g_StartTemp + 4 and T < g_StartTemp + 6) {         // High temp alarm condition - in real world would be lot lower!!
00357                         SuperHighTemp();                                        //  
00358                     }                                                           //
00359                     else  {                                                     // 
00360                         PeripheralsOffHigh();                                   // 
00361                     }                                                           // 
00362                     if (T >= g_StartTemp + 6) {                                 // 
00363                         UltraHighTemp();                                        // 
00364                     }                                                           // 
00365                     else  {                                                     //
00366                         PeripheralsOffHigh();                                   //
00367                     }                                                           //
00368                     if (T <= g_StartTemp - 2 and T > g_StartTemp - 4) {         // Low temp alarm condition - in real world would be lot lower!!
00369                         LowTemp();                                              //
00370                     }                                                           //
00371                     else  {                                                     //    
00372                         PeripheralsOffLow();                                    //               
00373                     }                                                           //
00374                     if(bAButtonWasPressed)                                      // Check if button was pressed
00375                     {                                                           //
00376                         if(SelectedItem == 0)                                   // 
00377                         {                                                       //
00378                             NewMenuState = MENUSTATE_Main;                      // Transition back to the main menu
00379                             PeripheralsOffHigh();                               // 
00380                             PeripheralsOffLow();                                //
00381                         }                                                       //
00382                     }                                                           //
00383                 }                                                               //
00384                 break;                                                          //
00385                 case MENUSTATE_OneOff:                                          // Call a one off measurement menu following top menu selection
00386                 {                                                               //
00387                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00388                     if(SelectedItem >= NumMenuItems)                            // 
00389                     {                                                           //
00390                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00391                     }                                                           //
00392                                                                                 //        
00393                     if(NumFramesInState == 0)                                   //
00394                     {                                                           //
00395                         g_TempReading = tmp102.get_temperature();               // Gather the temp readings only on the frame we enter this state and keep printing this same temp, not to refresh and read new temp.
00396                     }                                                           //
00397                                                                                 //
00398                     pc.printf("T = %f K\n",g_TempReading);                      // Print to serial - allows testing without device attached
00399                     int length = sprintf(buffer," T = %.2f C",g_TempReading);   // print formatted data to buffer - it is important the format specifier ensures the length will fit in the buffer
00400                     if (length <= 14){                                          // if string will fit on display (assuming printing at x=0)
00401                         lcd.printString("-- One-Off --",0,0);                   // 
00402                         lcd.printString("-- Measure --",0,1);                   // 
00403                         lcd.printString(buffer,0,3);                            // display on screen
00404                         lcd.printString(" 'A' to Menu",0,5);                    // 
00405                     }                                                           //
00406                                                                                 //
00407                     if(bAButtonWasPressed)                                      // Check if button was pressed
00408                     {                                                           //
00409                         if(SelectedItem == 0)                                   // 
00410                         {                                                       //
00411                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu
00412                         }                                                       //
00413                     }                                                           //                                                                         
00414                 }                                                               //
00415                 break;                                                          //
00416                 case MENUSTATE_Results:                                         // Call results menu following top menu selection
00417                 {                                                               //
00418                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00419                     if(SelectedItem >= NumMenuItems)                            // 
00420                     {                                                           //
00421                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00422                     }                                                           //
00423                                                                                 //
00424                     if(NumFramesInState == 0)                                   //
00425                     {                                                           //
00426                         if(fp != NULL){                                         //        
00427                             printf("Error! File already open!\n");              //
00428                             fclose(fp);                                         //
00429                         }                                                       //
00430                                                                                 //
00431                         fp = fopen("/sd/overnighttemp.csv", "w");               // Open our file handle on the first frame.  
00432                     }                                                           //                                    
00433                                                                                 //
00434                     if (fp == NULL) {                                           // if it can't open the file then print error message
00435                         printf("Error! Unable to open file! Returning to main menu.\n");  //                        
00436                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00437                     }                                                           //
00438                     else                                                        //
00439                     {                                                           //
00440                         float T = tmp102.get_temperature();                     // Read temperature and print to lcd
00441                         pc.printf("T = %f K\n",T);                              // Print to serial - allows testing without device attached
00442                         fprintf(fp, "%d,%f\n",NumFramesInState,T);              // Print formatted string to file (CSV)
00443                                                                                 //
00444                         lcd.printString("-- Results --",0,0);                   // 
00445                         lcd.printString(" Writing",0,1);                        // 
00446                         lcd.printString(" results to ",0,2);                    // 
00447                         lcd.printString(" file...",0,3);                        // 
00448                         lcd.printString(" ",0,4);                               // 
00449                         lcd.printString(" 'A' to Menu",0,5);                    // 
00450                     }                                                           //
00451                                                                                 //
00452                     if(bAButtonWasPressed)                                      // Check if button was pressed
00453                     {                                                           //            
00454                         if(SelectedItem == 0)                                   // 
00455                         {                                                       //
00456                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
00457                         }                                                       //
00458                     }                                                           //
00459                 }                                                               //
00460                 break;                                                          //
00461                 case MENUSTATE_About:                                           // Call About menu following top menu selection
00462                 {                                                               //
00463                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00464                     if(SelectedItem >= NumMenuItems)                            // 
00465                     {                                                           //
00466                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00467                     }                                                           //  
00468                                                                                 //    
00469                     lcd.printString("--- About ---",0,0);                       // 
00470                     lcd.printString("ELE3006M - IoT",0,1);                      // 
00471                     lcd.printString("    Project",0,2);                         // 
00472                     lcd.printString("Uni of Lincoln",0,3);                      // 
00473                     lcd.printString(" 'A' to Menu",0,5);                        // 
00474                     lcd.refresh();                                              // 
00475                                                                                 //
00476                     if(bAButtonWasPressed)                                      // Check if button was pressed
00477                     {                                                           //
00478                         if(SelectedItem == 0)                                   // 
00479                         {                                                       //
00480                             NewMenuState = MENUSTATE_Main;                      // Transition back to Main Menu
00481                         }                                                       //
00482                     }                                                           //    
00483                 }                                                               //    
00484                 break;                                                          //
00485                 case MENUSTATE_Author:                                          // Call Author menu following top menu selection
00486                 {                                                               //
00487                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00488                     if(SelectedItem >= NumMenuItems)                            // 
00489                     {                                                           //
00490                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00491                     }                                                           //
00492                                                                                 //
00493                     lcd.printString("--- Author ---",0,0);                      // 
00494                     lcd.printString("David Leaming ",0,1);                      // 
00495                     lcd.printString("   25574043 ",0,2);                        // 
00496                     lcd.printString("  VolkerRail",0,3);                        // 
00497                     lcd.printString(" 'A' to Menu",0,5);                        // 
00498                                                                                 //
00499                     if(bAButtonWasPressed)                                      // Check if button was pressed
00500                     {                                                           //
00501                         if(SelectedItem == 0)                                   // 
00502                         {                                                       //
00503                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
00504                         }                                                       //    
00505                     }                                                           // 
00506                 }                                                               //
00507                 break;                                                          //        
00508                 default:                                                        //
00509                 {                                                               //
00510                     NewMenuState = MENUSTATE_Main;                              // Something has gone wrong, drop back to the main menu.
00511                 }                                                               //
00512             };                                                                  //
00513                                                                                 //
00514             if(NewMenuState != MENUSTATTE_Num)                                  // If we have requested a new menu state.
00515             {                                                                   //
00516                 printf("Transitioning to MenuState: %i\n", NewMenuState);       // Observe on serial port - ensure transition to correct screen
00517                                                                                 //    
00518                 MenuState = NewMenuState;                                       // We want to transition the menu to a new state.
00519                                                                                 //
00520                                                                                 // Do any bookkeeping needed when moving to new state.
00521                 SelectedItem = 0;                                               // Reset the selected item.
00522                 NumFramesInState = 0;                                           // Reset the frames in current state count.
00523                                                                                 //
00524                 if(fp){                                                         //
00525                     fclose(fp);                                                 // Ensure we close the file if the current state had one open.
00526                     fp = NULL;                                                  //
00527                 }                                                               //
00528                 lcd.clear();                                                    // Clear the display for one frame on state transition.
00529             }                                                                   //
00530             else                                                                //
00531             {                                                                   //    
00532                 ++NumFramesInState;                                             //            
00533                                                                                 
00534                 unsigned int SelectionMarkerRadius = 4;                                                         // If we have not selected to move to a new menu.
00535                 unsigned int SelectionMarkerX = WIDTH - (2 * SelectionMarkerRadius);                            // Draw a marker circle at end of line to show which is the currently selected item.
00536                 unsigned int SelectionMarkerY = (HEIGHT / 5) * (SelectedItem + 1);                              // +1 because of the menu title being on first row
00537                 lcd.drawCircle(SelectionMarkerX, SelectionMarkerY, SelectionMarkerRadius, FILL_BLACK);          // Fill the circle black so it can be seen easily                                                   
00538                             
00539                                                                                 // Handle Joystick Input
00540                 Direction d = joystick.get_direction();                         //                                        
00541                 printf("Direction = %i\n", d);                                  //
00542                 switch (joystick.get_direction())  {                            // Call to check direction joystick is pointing                                     
00543                     case N:                                                     //
00544                     {                                                           //        
00545                         SelectedItem--;                                         //  
00546                         printf("Selection decremented to %i\n", SelectedItem);  //
00547                     }                                                           //
00548                     break;                                                      //
00549                     case S:                                                     //
00550                     {                                                           //
00551                         SelectedItem++;                                         //    
00552                         printf("Selection incremented to %i\n", SelectedItem);  //
00553                     }                                                           //
00554                     break;                                                      //
00555                 }                                                               //
00556                 if(SelectedItem < 0)                                            // Wrap the selection around to the start/end of the menu if it goes below 0 or above NumMenuItems.
00557                 {                                                               //
00558                     SelectedItem = NumMenuItems - 1;                            // 
00559                 }                                                               //
00560                 else if(SelectedItem >= NumMenuItems)                           //
00561                 {                                                               //
00562                     SelectedItem = 0;                                           // 
00563                 }                                                               //
00564             }                                                                   //
00565             lcd.refresh();                                                      // Finally update the display.
00566         }                                                                       //    
00567     }                                                                           //
00568 }                                                                               //
00569                                                                                 //
00570 void StartTemp()                                                                //
00571 {                                                                               //
00572     Direction d = joystick.get_direction();                                     //
00573                                                                                 //
00574         g_StartTemp = fsm[g_state].output;                                      // Set ouput depending on current state
00575         wait(fsm[g_state].time);                                                // Wait in that state for desired time           
00576         g_state = fsm[g_state].nextState[d];                                    // Read input and update curent state 
00577 }                                                                               //
00578                                                                                 // 
00579 void HighTemp()                                                                 //
00580 {                                                                               // 
00581     LED01 = !LED01;                                                             // Flash LED01 if temperature is over specified - Simulated starting of cold blowers
00582     printf("WARNING - High Temp!! \n");                                         //
00583     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely high 
00584     Buzzer = 0.5;                                                               // 
00585     wait(0.5);                                                                  // 
00586     Buzzer = 0;                                                                 //
00587 }                                                                               //
00588                                                                                 // 
00589 void SuperHighTemp()                                                            //
00590 {                                                                               // 
00591     LED01 = !LED01;                                                             // Flash LED01 if temperature is over specified - Simulated starting of cold blowers
00592     LED02 = !LED02;                                                             // Flash LED02 if temperature is over specified - Simulated starting of cold blowers
00593     printf("WARNING - Super High Temp!! \n");                                   //
00594     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely high 
00595     Buzzer = 0.5;                                                               // 
00596     wait(0.5);                                                                  // 
00597     Buzzer = 0;                                                                 //
00598 }                                                                               //
00599                                                                                 // 
00600 void UltraHighTemp()                                                            //
00601 {                                                                               // 
00602     LED01 = !LED01;                                                             // Flash LED01 if temperature is over specified - Simulated starting of cold blowers
00603     LED02 = !LED02;                                                             // Flash LED02 if temperature is over specified - Simulated starting of cold blowers
00604     LED03 = !LED03;                                                             // Flash LED02 if temperature is over specified - Simulated starting of cold blowers
00605     printf("WARNING - Ultra High Temp!! \n");                                   //
00606     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely high 
00607     Buzzer = 0.5;                                                               // 
00608     wait(0.5);                                                                  // 
00609     Buzzer = 0;                                                                 //
00610 }                                                                               //
00611                                                                                 //
00612 void LowTemp()                                                                  //
00613 {                                                                               //
00614     LED04 = !LED04;                                                             // Flash LED04 if temperature is over specified - Simulated starting of heaters
00615     printf("WARNING - Low Temp!! \n");                                          //
00616     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely low
00617     wait(0.5);                                                                  // 
00618     Buzzer = 0;                                                                 //
00619 }                                                                               //
00620                                                                                 //                                                                                                                                           //
00621 void SuperLowTemp()                                                             //
00622 {                                                                               //
00623     LED04 = !LED04;                                                             // Flash LED04 if temperature is over specified - Simulated starting of heaters
00624     LED05 = !LED05;                                                             // Flash LED05 if temperature is over specified - Simulated starting of heaters
00625     printf("WARNING - Super Low Temp!! \n");                                    //
00626     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely low
00627     wait(0.5);                                                                  // 
00628     Buzzer = 0;                                                                 //
00629 }                                                                               //
00630                                                                                 //
00631 void UltraLowTemp()                                                             //
00632 {                                                                               //
00633     LED04 = !LED04;                                                             // Flash LED04 if temperature is over specified - Simulated starting of heaters
00634     LED05 = !LED05;                                                             // Flash LED05 if temperature is over specified - Simulated starting of heaters
00635     LED06 = !LED06;                                                             // Flash LED06 if temperature is over specified - Simulated starting of heaters
00636     printf("WARNING - Ultra Low Temp!! \n");                                    //
00637     Buzzer.period(1.0/554.0);                                                   // Warning Buzzer to extremely low
00638     wait(0.5);                                                                  // 
00639     Buzzer = 0;                                                                 //
00640 }                                                                               //
00641                                                                                 // 
00642 void PeripheralsOffHigh()                                                       //
00643 {                                                                               // 
00644     LED01 = 1;                                                                  // LED01 off if temperature is below specified - Simulated stopping of cold blowers
00645     LED02 = 1;                                                                  // LED02 off if temperature is below specified - Simulated stopping of cold blowers
00646     LED03 = 1;                                                                  // LED03 off if temperature is below specified - Simulated stopping of cold blowers
00647     Buzzer = 0;                                                                 // Buzzer off if temperature is below specified - Simulated stopping of cold blowers
00648 }                                                                               // 
00649                                                                                 // 
00650 void PeripheralsOffLow()                                                        // 
00651 {                                                                               //
00652     LED04 = 1;                                                                  // LED04 off if temperature is below specified - Simulated stopping of heaters
00653     LED05 = 1;                                                                  // LED05 off if temperature is below specified - Simulated stopping of heaters
00654     LED06 = 1;                                                                  // LED06 off if temperature is below specified - Simulated stopping of heaters
00655     Buzzer = 0;                                                                 // Buzzer off if temperature is below specified - Simulated stopping of heaters
00656 }                                                                               //