(DA) Internet of Things and Smart Electronics- ELE3006M2122 / Mbed 2 deprecated Final_Project_V16_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 
00085 void error();                                                                   // error function hangs flashing an LED
00086 void init_serial();                                                             // setup serial port
00087 void init_K64F();                                                               // set-up the on-board LEDs and switches
00088 void init_PCB();                                                                // set-up the PCB LEDs and buttons
00089 void ButtonA_isr();                                                             // 
00090 void ButtonB_isr();                                                             // 
00091 void ButtonBack_isr();                                                          // 
00092 void sw2_isr();                                                                 // 
00093 void menu_timer_isr();                                                          // 
00094 void OnStartup();                                                               // 
00095 void Run();                                                                     // 
00096 void StartTemp();                                                               //
00097 void delete_file(char filename[]);                                              //
00098 void WriteToFile();                                                             // Function to attempt to write temperature to file
00099 void OneOff();                                                                  // 
00100 
00101 int main()
00102 {
00103     init_K64F();                                                                // initialise the board
00104     init_serial();                                                              // initialise the serial port
00105     init_PCB();                                                                 // initialise the PCB
00106         
00107     tmp102.init();                                                              // call the sensor init method using dot syntax
00108     lcd.init();                                                                 // initialise display
00109     joystick.init();                                                            // initialise joystick
00110     
00111     ticker_menu.attach(&menu_timer_isr,0.2);                                    // Attach ticker for the Joystick
00112     
00113     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
00114     ButtonA.rise(&ButtonA_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
00115     ButtonB.rise(&ButtonB_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
00116     
00117     lcd.setContrast(0.5);                                                       // change set contrast in range 0.0 to 1.0
00118     
00119     OnStartup();                                                                // Call intro screen   
00120     Run();                                                                      // Call main-menu and functions
00121 }      
00122 
00123 void init_serial() {
00124     pc.baud(115200);                                                            // set to highest baud - ensure terminal software matches
00125 }
00126 
00127 void init_K64F() 
00128 {
00129     r_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00130     g_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00131     b_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
00132     
00133     sw2.mode(PullNone);                                                         // since the on-board switches have external pull-ups, we should disable the internal pull-down
00134     sw3.mode(PullNone);                                                         // resistors that are enabled by default using InterruptIn
00135 }
00136 
00137 void init_PCB ()
00138 {
00139     LED01 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00140     LED02 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00141     LED03 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00142     LED04 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
00143     LED05 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
00144     LED06 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
00145     
00146     Buzzer = 0;                                                                 // Ensure Piezo Buzzer is off
00147     
00148     ButtonA.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
00149     ButtonB.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
00150 }
00151 
00152 void ButtonA_isr()                                                              // ButtonA event-triggered interrupt
00153 {
00154     g_ButtonA_flag = 1;                                                         // set flag in ISR
00155 }
00156 
00157 void ButtonB_isr()                                                              // ButtonB event-triggered interrupt
00158 {
00159     g_ButtonB_flag = 1;                                                         // set flag in ISR
00160 }
00161 
00162 void ButtonBack_isr()                                                           // ButtonB event-triggered interrupt
00163 {
00164     g_ButtonBack_flag = 1;                                                      // set flag in ISR
00165 }
00166 
00167 void sw2_isr()                                                                  // SW2 event-triggered interrupt
00168 {
00169     g_sw2_flag = 1;                                                             // set flag in ISR
00170 }
00171 
00172 void menu_timer_isr()
00173 {
00174     g_menu_timer_flag = 1;                                                      // set flag in ISR
00175 }
00176 
00177 void OnStartup()                                                                // Run some start up display 
00178 {
00179     Buzzer.period(1.0/659.0);                                                   // Welcome sounds from Piezo
00180     Buzzer = 0.5;                                                               //                   
00181     wait(0.5);                                                                  // 
00182     Buzzer.period(1.0/494.0);                                                   // 
00183     Buzzer = 0.5;                                                               //    
00184     wait(0.5);                                                                  // 
00185     Buzzer.period(1.0/554.0);                                                   // 
00186     Buzzer = 0.5;                                                               // 
00187     wait(0.5);                                                                  // 
00188     Buzzer = 0;                                                                 // Turn off welcome sounds 
00189     lcd.clear();                                                                // Clear buffer at start of every loop
00190     lcd.printString("--------------",0,0);                                      // Can directly print strings at specified co-ordinates (must be less than 84 pixels to fit on display)
00191     lcd.printString("  Smart Cold",0,1);                                        // Just a welcome message before auto moving to main menu
00192     lcd.printString("   Storage",0,2);                                          //
00193     lcd.printString("  Monitoring",0,3);                                        // 
00194     lcd.printString("V16 - Jan 2022",0,4);                                      //
00195     lcd.printString("--------------",0,5);                                      //
00196     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings 
00197     wait(5.0);                                                                  // Leave welcome screen on for designated amount of time
00198     lcd.clear();                                                                // Clear buffer at start of every loop
00199     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings 
00200     lcd.printString("--------------",0,0);                                      //
00201     lcd.printString(" Use Joystick",0,1);                                       // Instruction for use of menu
00202     lcd.printString(" To Navigate",0,2);                                        //
00203     lcd.printString("",0,3);                                                    // Blank Line
00204     lcd.printString("  A = Select",0,4);                                        //
00205     lcd.printString("--------------",0,5);                                      //
00206     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings
00207     wait(5.0);                                                                  //
00208     init_PCB();                                                                 // Ran again to ensure all LED's etc are turned off
00209     printf("Transition to Temp Selection %i\n",StartTemp);                      // Observe on serial port - ensure transition to correct screen
00210 }
00211 
00212 enum EMenuState                                                                 // An enum controlling the current state of the display.
00213 {
00214     MENUSTATE_StartTemp,                                                        // Defining each menu state to be called upon later
00215     MENUSTATE_Main,                                                             // Defining each menu state to be called upon later
00216     MENUSTATE_Monitor,                                                          // Defining each menu state to be called upon later
00217     MENUSTATE_OneOff,                                                           // Defining each menu state to be called upon later
00218     MENUSTATE_Results,                                                          // Defining each menu state to be called upon later
00219     MENUSTATE_About,                                                            // Defining each menu state to be called upon later
00220     MENUSTATE_Author,                                                           // Defining each menu state to be called upon later
00221     
00222     MENUSTATTE_Num,                                                             // This is a special enum value that just gives is a way to get the number of elements in the enum.
00223 };
00224 
00225 void Run()
00226 {
00227     int MenuState = MENUSTATE_StartTemp;                                        // Ensuring that the first Menu State to be brought up is the Temperature Selection Page 
00228     int SelectedItem = 0;                                                       // 
00229     int NumMenuItems = 1;                                                       // 
00230     
00231     char buffer[14];                                                            // Each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
00232     
00233     while(1){
00234         if (g_menu_timer_flag){                                                 //        
00235             g_menu_timer_flag = 0;                                              // 
00236             
00237             bool bAButtonWasPressed = g_ButtonA_flag;                           // Get the value of the input flags and reset them
00238             bool bBButtonWasPressed = g_ButtonB_flag;                           // Get the value of the input flags and reset them
00239             g_ButtonA_flag = 0;                                                 // 
00240             g_ButtonB_flag = 0;                                                 // 
00241             
00242             lcd.clear();                                                        // clear buffer at start of every loop
00243                         
00244             int NewMenuState = MENUSTATTE_Num;                                  // The new menu we want to transition to, if any.
00245         
00246             switch(MenuState)                                                   // Update and Draw whichever menu we're on.
00247             {      
00248                 case MENUSTATE_StartTemp:                                       //
00249                 {                    
00250                     NumMenuItems = 1;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
00251                     if(SelectedItem >= NumMenuItems)                            // 
00252                     {
00253                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
00254                     }
00255                     Direction d = joystick.get_direction();                               
00256                     
00257                     StartTemp();
00258                     
00259                     float g_StartTemp = fsm[g_state].output;                    // read temperature and print to lcd
00260                     pc.printf("T = %f C\n",g_StartTemp);                        // Print to serial - allows testing without device attached
00261                     printf ("Joystick Direction Points = %i\n",d);              //
00262                     printf ("State selected = %i\n", g_state);                  //
00263                     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
00264                     if (length <= 14){                                          // if string will fit on display (assuming printing at x=0)
00265                         lcd.printString("- Set Target -",0,0);                  // 
00266                         lcd.printString("---- Temp ----",0,1);                  // 
00267                         lcd.printString(buffer,0,3);                            // display on screen
00268                         lcd.printString("'A' to Select",0,5);                   //                      
00269                         lcd.refresh();      
00270                     }                                                           // need to refresh display after setting pixels or writing strings 
00271  
00272                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
00273                     {
00274                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
00275                         {                                                       // Actually 0 line + 1, see circle draw and selection below
00276                             NewMenuState = MENUSTATE_Main;                      // 
00277                         }
00278                     }
00279                 }
00280                 break;                                                          //         
00281                 case MENUSTATE_Main:                                            //
00282                 {
00283                     NumMenuItems = 5;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
00284                     if(SelectedItem >= NumMenuItems)                            // 
00285                     {
00286                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
00287                     }
00288                     lcd.printString("---- MENU ----",0,0);                      // Menu title and selectable options    
00289                     lcd.printString("M1 - Monitor",0,1);                        // Printed to the LCD screen
00290                     lcd.printString("M2 - One-off",0,2);                        // 
00291                     lcd.printString("Results",0,3);                             //
00292                     lcd.printString("About",0,4);                               //
00293                     lcd.printString("Author",0,5);                              // 
00294                     
00295                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
00296                     {
00297                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
00298                         {                                                       // Actually 0 line + 1, see circle draw and selection below
00299                             NewMenuState = MENUSTATE_Monitor;                   // 
00300                         }
00301                         else if(SelectedItem == 1)                              // If 1 line is selected, move to detailed menu 
00302                         {                                                       // Actually 1 line + 1, see circle draw and selection below
00303                             NewMenuState = MENUSTATE_OneOff;                    // 
00304                         }
00305                         else if(SelectedItem == 2)                              // If 2 line is selected, move to detailed menu 
00306                         {                                                       // Actually 2 line + 1, see circle draw and selection below
00307                             NewMenuState = MENUSTATE_Results;                   // 
00308                         }
00309                         else if(SelectedItem == 3)                              // If 3 line is selected, move to detailed menu 
00310                         {                                                       // Actually 3 line + 1, see circle draw and selection below
00311                             NewMenuState = MENUSTATE_About;                     // 
00312                         }
00313                         else if(SelectedItem == 4)                              // If 4 line is selected, move to detailed menu 
00314                         {                                                       // Actually 4 line + 1, see circle draw and selection below
00315                             NewMenuState = MENUSTATE_Author;                    // 
00316                         }
00317                     }
00318                 }
00319                 break;                                                          // 
00320                 case MENUSTATE_Monitor:                                         // Call constant measurement menu following top menu selection
00321                 {
00322                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00323                     
00324                     if(SelectedItem >= NumMenuItems)                            // 
00325                     {
00326                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00327                     }
00328                     
00329                     float T = tmp102.get_temperature();                         // read temperature and print to lcd
00330                     pc.printf("T = %f K\n",T);                                  // Print to serial - allows testing without device attached
00331                     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
00332                     if (length <= 14)                                           // if string will fit on display (assuming printing at x=0)
00333                     lcd.printString("-- Constant --",0,0);                      // 
00334                     lcd.printString("- Monitoring -",0,1);                      // 
00335                     lcd.printString(buffer,0,3);                                // display on screen
00336                     lcd.printString(" 'A' to Menu",0,5);                        // 
00337                     lcd.refresh();                                              // need to refresh display after setting pixels or writing strings 
00338                     wait(0.5);                                                  // 
00339                     
00340                     if (T >= g_StartTemp + 2) {                                 // High temp alarm condition - in real world would be lot lower!!
00341                         LED01 = !LED01;                                         // Flash LED01 if temperature is over specified - Simulated starting of cold blowers
00342                         LED02 = !LED02;                                         // Flash LED02 if temperature is over specified - Simulated starting of cold blowers
00343                         LED03 = !LED03;                                         // Flash LED03 if temperature is over specified - Simulated starting of cold blowers
00344                         printf("WARNING - High Temp!! \n");                     //
00345                         Buzzer.period(1.0/554.0);                               // Warning Buzzer to extremely high 
00346                         Buzzer = 0.5;                                           // 
00347                         wait(0.5);                                              // 
00348                         Buzzer = 0;                                             //
00349                     } 
00350                     else  {
00351                         LED01 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
00352                         LED02 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
00353                         LED03 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
00354                         Buzzer = 0;                                             // Buzzer off if temperature is below specified - Simulated stopping of cold blowers
00355                     } 
00356                     
00357                     if (T <= g_StartTemp - 2) {                                 // High temp alarm condition - in real world would be lot lower!!
00358                         LED04 = !LED04;                                         // Flash LED01 if temperature is over specified - Simulated starting of heaters
00359                         LED05 = !LED05;                                         // Flash LED02 if temperature is over specified - Simulated starting of heaters
00360                         LED06 = !LED06;                                         // Flash LED03 if temperature is over specified - Simulated starting of heaters
00361                         printf("WARNING - Low Temp!! \n");                      //
00362                         Buzzer.period(1.0/554.0);                               // Warning Buzzer to extremely high 
00363                         Buzzer = 0.5;                                           // 
00364                         wait(0.5);                                              // 
00365                         Buzzer = 0;                                             //
00366                     } 
00367                     else  {
00368                         LED04 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
00369                         LED05 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
00370                         LED06 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
00371                         Buzzer = 0;                                             // Buzzer off if temperature is below specified - Simulated stopping of heaters
00372                     } 
00373                     if(bAButtonWasPressed)                                      // Check if button was pressed
00374                     {
00375                         if(SelectedItem == 0)                                   // 
00376                         {
00377                             NewMenuState = MENUSTATE_Main;                      // Transition back to the main menu
00378                             LED01 = 1;                                          // Turn off LED upon transition back to main menu
00379                             LED02 = 1;                                          // Turn off LED upon transition back to main menu
00380                             LED03 = 1;                                          // Turn off LED upon transition back to main menu
00381                             LED04 = 1;                                          // Turn off LED upon transition back to main menu
00382                             LED05 = 1;                                          // Turn off LED upon transition back to main menu
00383                             LED06 = 1;                                          // Turn off LED upon transition back to main menu
00384                         }
00385                     }
00386                 }
00387                 break;      
00388                 case MENUSTATE_OneOff:                                          // Call a one off measurement menu following top menu selection
00389                 {
00390                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00391                     if(SelectedItem >= NumMenuItems)                            // 
00392                     {
00393                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00394                     }
00395                     
00396                     OneOff();                                                   // read temperature and print to lcd
00397 
00398                                         
00399                     if(bAButtonWasPressed)                                      // Check if button was pressed
00400                     {
00401                         if(SelectedItem == 0)                                   // 
00402                         {
00403                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu
00404                         }
00405                     }                   
00406                     
00407                 }
00408                 break; 
00409                 case MENUSTATE_Results:                                         // Call results menu following top menu selection
00410                 {
00411 
00412                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00413                     if(SelectedItem >= NumMenuItems)                            // 
00414                     {
00415                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00416                     }
00417                     
00418                     WriteToFile();                                              //
00419                     
00420                     lcd.printString("--- Results ---",0,0);                     // 
00421                     lcd.printString(" ",0,1);                                   // 
00422                     lcd.printString(" ",0,2);                                   // 
00423                     lcd.printString(" ",0,3);                                   // 
00424                     lcd.printString(" ",0,4);                                   // 
00425                     lcd.printString(" 'A' to Menu",0,5);                        // 
00426                                         
00427                     if(bAButtonWasPressed)                                      // Check if button was pressed
00428                     {
00429                         if(SelectedItem == 0)                                   // 
00430                         {
00431                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
00432                         }
00433                     }
00434                 }
00435                 break;     
00436                 case MENUSTATE_About:                                           // Call About menu following top menu selection
00437                 {
00438                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
00439                     if(SelectedItem >= NumMenuItems)                            // 
00440                     {
00441                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
00442                     }
00443                     
00444                     lcd.printString("--- About ---",0,0);                       // 
00445                     lcd.printString("ELE3006M - IoT",0,1);                      // 
00446                     lcd.printString("    Project",0,2);                         // 
00447                     lcd.printString("Uni of Lincoln",0,3);                      // 
00448                     lcd.printString(" 'A' to Menu",0,5);                        // 
00449                     lcd.refresh();                                              // 
00450                                         
00451                     if(bAButtonWasPressed)                                      // Check if button was pressed
00452                     {
00453                         if(SelectedItem == 0)                                   // 
00454                         {
00455                             NewMenuState = MENUSTATE_Main;                      // Transition back to Main Menu
00456                         }
00457                     }
00458                 }
00459                 break;
00460                 case MENUSTATE_Author:                                          // Call Author menu following top menu selection
00461                 {
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("--- Author ---",0,0);                      // 
00470                     lcd.printString("David Leaming ",0,1);                      // 
00471                     lcd.printString("   25574043 ",0,2);                        // 
00472                     lcd.printString("  VolkerRail",0,3);                        // 
00473                     lcd.printString(" 'A' to Menu",0,5);                        // 
00474                                         
00475                     if(bAButtonWasPressed)                                      // Check if button was pressed
00476                     {
00477                         if(SelectedItem == 0)                                   // 
00478                         {
00479                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
00480                         }
00481                     }
00482                 }
00483                 break;
00484                 
00485                 default:
00486                 {
00487                     NewMenuState = MENUSTATE_Main;                              // Something has gone wrong, drop back to the main menu.
00488                 }
00489             };
00490             
00491             if(NewMenuState != MENUSTATTE_Num)                                  // If we have requested a new menu state.
00492             {
00493                 printf("Transitioning to MenuState: %i\n", NewMenuState);       // Observe on serial port - ensure transition to correct screen
00494                 
00495                 MenuState = NewMenuState;                                       // We want to transition the menu to a new state.
00496                 
00497                                                                                 // Do any bookkeeping needed when moving to new state.
00498                 SelectedItem = 0;                                               // Reset the selected item.   
00499                 
00500                 lcd.clear();                                                    // Clear the display for one frame on state transition.
00501             }                                                                   
00502             else
00503             {
00504                 unsigned int SelectionMarkerRadius = 4;                                                         // If we have not selected to move to a new menu.
00505                 unsigned int SelectionMarkerX = WIDTH - (2 * SelectionMarkerRadius);                            // Draw a marker circle at end of line to show which is the currently selected item.
00506                 unsigned int SelectionMarkerY = (HEIGHT / 5) * (SelectedItem + 1);                              // +1 because of the menu title being on first row
00507                 lcd.drawCircle(SelectionMarkerX, SelectionMarkerY, SelectionMarkerRadius, FILL_BLACK);          // Fill the circle black so it can be seen easily                                                   
00508                             
00509                                                                                 // Handle Joystick Input
00510                 Direction d = joystick.get_direction();                                                                 
00511                 printf("Direction = %i\n"); 
00512                 switch (joystick.get_direction())  {                            // Call to check direction joystick is pointing                                     
00513                     case N:        
00514                     {   
00515                         SelectedItem--;                                           
00516                         printf("Selection decremented to %i\n", SelectedItem); 
00517                     }
00518                     break;                                                      //
00519                     case S:   
00520                     {
00521                         SelectedItem++;
00522                         printf("Selection incremented to %i\n", SelectedItem); 
00523                     }
00524                     break;                                                      //
00525                 }
00526                 
00527                 if(SelectedItem < 0)                                            // Wrap the selection around to the start/end of the menu if it goes below 0 or above NumMenuItems.
00528                 {                   
00529                     SelectedItem = NumMenuItems - 1;                            // 
00530                 }
00531                 else if(SelectedItem >= NumMenuItems)                           //
00532                 {
00533                     SelectedItem = 0;                                           // 
00534                 }
00535             }
00536             
00537             lcd.refresh();                                                      // Finally update the display.
00538         }
00539     }       
00540 }  
00541 
00542 void StartTemp()                                                                //
00543 {
00544     Direction d = joystick.get_direction();                                     //
00545              
00546         g_StartTemp = fsm[g_state].output;                                      // set ouput depending on current state
00547         wait(fsm[g_state].time);                                                // wait in that state for desired time           
00548         g_state = fsm[g_state].nextState[d];                                    // read input and update curent state 
00549 }
00550 
00551 void WriteToFile()                                                              // Function to attempt to write temperature to file
00552 {
00553     printf("#### SD Card Example #####\n");
00554     FILE *fp;                                                                   // this is our file pointer
00555     
00556     float T = tmp102.get_temperature();                                         // read temperature and print to lcd
00557     pc.printf("T = %f K\n",T);                                                  // Print to serial - allows testing without device attached
00558     
00559     fp = fopen("/sd/overnighttemp", "w");                                       // 
00560     int ONight_Temp = T;                                                        // 
00561     
00562     if (fp == NULL) {                                                           // if it can't open the file then print error message
00563     printf("Error! Unable to open file!\n");
00564     } 
00565     else {                                                                      // opened file so can write
00566         printf("Writing to file....");
00567         for(int i = T; i <= 50; i++) {
00568             float T = 1000.0F/i;                                                // dummy variable
00569             fprintf(fp, "%d,%f\n",i,T);                                         // print formatted string to file (CSV)
00570         }
00571         printf("Done.\n");
00572         fclose(fp);                                                             // ensure you close the file after writing
00573     }
00574 }
00575 
00576 void OneOff()                                                                   // 
00577 {
00578     char buffer[14];                                                            // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
00579     
00580     lcd.clear();                                                                // 
00581     
00582     float T = tmp102.get_temperature();                                         // read temperature and print to lcd
00583     pc.printf("T = %f K\n",T);                                                  // Print to serial - allows testing without device attached
00584     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
00585     if (length <= 14){                                                          // if string will fit on display (assuming printing at x=0)
00586     lcd.printString("-- One-Off --",0,0);                                       // 
00587     lcd.printString("-- Measure --",0,1);                                       // 
00588     lcd.printString(buffer,0,3);                                                // display on screen
00589     lcd.printString(" 'A' to Menu",0,5);                                        // 
00590     }                                                                           //
00591 }                                                                               //