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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
legstar85
Date:
Thu Jan 27 08:00:52 2022 +0000
Parent:
15:0cd78b44ea83
Commit message:
V17 - Working FSM for selectable temperature, facility to print results to SD card working, comments added

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Jan 24 20:34:48 2022 +0000
+++ b/main.cpp	Thu Jan 27 08:00:52 2022 +0000
@@ -13,32 +13,32 @@
 * Paul Staron, Piezo Buzzer utility, April 2019
 */ 
 
-#include "mbed.h"                                                               // include the library header, ensure the library has been imported into the project
-#include "TMP102.h"
-#include "N5110.h"
-#include "Joystick.h"
-#include "Bitmap.h"
-#include "SDFileSystem.h"
-
+#include "mbed.h"                                                               // Include the library header, ensure the library has been imported into the project
+#include "TMP102.h"                                                             //
+#include "N5110.h"                                                              //
+#include "Joystick.h"                                                           //
+#include "Bitmap.h"                                                             //
+#include "SDFileSystem.h"                                                       //
+                                                                                //
 TMP102 tmp102(I2C_SDA,I2C_SCL);                                                 // Create TMP102 object  
-
-//        VCC,SCE,RST,D/C,MOSI,SCLK,LED 
+                                                                                //
+//        VCC,SCE,RST,D/C,MOSI,SCLK,LED                                         //    
 N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);                                      // Create Screen Object - K64F - pwr from 3V3, GND Pin also needs connecting
-
-//                  y     x     button
+                                                                                //
+//                  y     x     button                                          //    
 Joystick joystick(PTB10,PTB11,PTC16);                                           // Define Joystick Object 
-
+                                                                                //        
 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");                                  // MOSI, MISO, SCK, CS - Connections to SD card holder on K64F (SPI interface)
-
+                                                                                //
 Serial pc(USBTX,USBRX);                                                         // UART connection for PC
-
+                                                                                //
 struct State {                                                                  // Struct for state
     int output;                                                                 // output value
     float time;                                                                 // time in state
     int nextState[9];                                                           // array of next states
-};
-
-State fsm[11] = {
+};                                                                              //
+                                                                                //
+State fsm[11] = {                                                               //
     {15,0.5,{0,1,0,0,0,10,0,0,0}},                                              // State 0 - 15 Degrees
     {16,0.5,{1,2,1,1,1,0,1,1,1}},                                               // State 1 - 16 Degrees
     {17,0.5,{2,3,2,2,2,1,2,2,2}},                                               // State 2 - 17 Degrees
@@ -50,29 +50,29 @@
     {23,0.5,{8,9,8,8,8,7,8,8,8}},                                               // State 8 - 23 Degrees
     {24,0.5,{9,10,9,9,9,8,9,9,9}},                                              // State 9 - 24 Degrees
     {25,0.5,{10,1,10,10,10,9,10,10,10}}                                         // State 10 - 25 Degrees   
-};
-
+};                                                                              //
+                                                                                //
 Ticker ticker_menu;                                                             // Create Menu ticker object
-
+                                                                                //        
 DigitalOut r_led(LED_RED);                                                      // K64F on-board LEDs 
 DigitalOut g_led(LED_GREEN);                                                    // K64F on-board LEDs 
 DigitalOut b_led(LED_BLUE);                                                     // K64F on-board LEDs 
-
+                                                                                //
 PwmOut LED01 (PTA1);                                                            // PCB Surface Mounted LED's - LED1
 PwmOut LED02 (PTA2);                                                            // PCB Surface Mounted LED's - LED2
 PwmOut LED03 (PTC2);                                                            // PCB Surface Mounted LED's - LED3
 PwmOut LED04 (PTC3);                                                            // PCB Surface Mounted LED's - LED4
 PwmOut LED05 (PTC4);                                                            // PCB Surface Mounted LED's - LED5
 PwmOut LED06 (PTD3);                                                            // PCB Surface Mounted LED's - LED6
-
+                                                                                //    
 PwmOut Buzzer (PTC10);                                                          // PCB Surface Mounted Piezo Buzzer
-
+                                                                                //
 InterruptIn sw2(SW2);                                                           // K64F on-board switches
 InterruptIn sw3(SW3);                                                           // K64F on-board switches
 InterruptIn ButtonA (PTB9);                                                     // PCB Button - A
 InterruptIn ButtonB (PTD0);                                                     // PCB Button - B
 InterruptIn ButtonBack (PTB10);                                                 // PCB Button - Back
-
+                                                                                //
 volatile int g_ButtonA_flag = 0;                                                // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
 volatile int g_ButtonB_flag = 0;                                                // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
 volatile int g_ButtonBack_flag = 0;                                             // Flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
@@ -81,7 +81,8 @@
 volatile int option = 0;                                                        // Menu option selection based on joystick direction
 volatile int g_state = 0;                                                       // 
 volatile int g_StartTemp = 0;                                                   // 
-
+volatile float g_TempReading = 0.0f;                                            //
+                                                                                //
 void error();                                                                   // error function hangs flashing an LED
 void init_serial();                                                             // setup serial port
 void init_K64F();                                                               // set-up the on-board LEDs and switches
@@ -95,87 +96,86 @@
 void Run();                                                                     // 
 void StartTemp();                                                               //
 void delete_file(char filename[]);                                              //
-void WriteToFile();                                                             // Function to attempt to write temperature to file
-void OneOff();                                                                  // 
-
-int main()
-{
-    init_K64F();                                                                // initialise the board
+                                                                                //
+                                                                                //
+int main()                                                                      //
+{                                                                               //
+    init_K64F();                                                                // Initialise the board
     init_serial();                                                              // initialise the serial port
-    init_PCB();                                                                 // initialise the PCB
-        
-    tmp102.init();                                                              // call the sensor init method using dot syntax
-    lcd.init();                                                                 // initialise display
-    joystick.init();                                                            // initialise joystick
-    
+    init_PCB();                                                                 // Initialise the PCB
+                                                                                //
+    tmp102.init();                                                              // Call the sensor init method using dot syntax
+    lcd.init();                                                                 // Initialise display
+    joystick.init();                                                            // Initialise joystick
+                                                                                //        
     ticker_menu.attach(&menu_timer_isr,0.2);                                    // Attach ticker for the Joystick
-    
+                                                                                //
     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
     ButtonA.rise(&ButtonA_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
     ButtonB.rise(&ButtonB_isr);                                                 // External push button, pin set to 0V by pull down command, means a rising edge is looked for
-    
+                                                                                //
     lcd.setContrast(0.5);                                                       // change set contrast in range 0.0 to 1.0
-    
+                                                                                //
     OnStartup();                                                                // Call intro screen   
     Run();                                                                      // Call main-menu and functions
-}      
-
-void init_serial() {
+}                                                                               //
+                                                                                //
+void init_serial() {                                                            //
     pc.baud(115200);                                                            // set to highest baud - ensure terminal software matches
-}
-
-void init_K64F() 
-{
+}                                                                               //        
+                                                                                //
+void init_K64F()                                                                //
+{                                                                               // 
     r_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
     g_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
     b_led = 1;                                                                  // on-board LEDs are active-low, so set pin high to turn them off.
-    
+                                                                                //
     sw2.mode(PullNone);                                                         // since the on-board switches have external pull-ups, we should disable the internal pull-down
     sw3.mode(PullNone);                                                         // resistors that are enabled by default using InterruptIn
-}
-
-void init_PCB ()
-{
+}                                                                               //
+                                                                                //
+void init_PCB ()                                                                //        
+{                                                                               //        
     LED01 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
     LED02 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
     LED03 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
     LED04 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
     LED05 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly
     LED06 = 1;                                                                  // PCB surface mounted LED's are active low - write a 1 to turn them off initiallly    
-    
+                                                                                //
     Buzzer = 0;                                                                 // Ensure Piezo Buzzer is off
-    
+                                                                                //
     ButtonA.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
     ButtonB.mode(PullDown);                                                     // Set pin to Pull Down to OV, meaning that a rising edge is looked for when button is pressed
-}
-
+}                                                                               //        
+                                                                                //
 void ButtonA_isr()                                                              // ButtonA event-triggered interrupt
-{
+{                                                                               //
     g_ButtonA_flag = 1;                                                         // set flag in ISR
-}
-
+}                                                                               //        
+                                                                                //
 void ButtonB_isr()                                                              // ButtonB event-triggered interrupt
-{
+{                                                                               //
     g_ButtonB_flag = 1;                                                         // set flag in ISR
-}
-
+}                                                                               //
+                                                                                //
 void ButtonBack_isr()                                                           // ButtonB event-triggered interrupt
-{
+{                                                                               //
     g_ButtonBack_flag = 1;                                                      // set flag in ISR
-}
-
+}                                                                               //
+                                                                                //
 void sw2_isr()                                                                  // SW2 event-triggered interrupt
-{
+{                                                                               //
     g_sw2_flag = 1;                                                             // set flag in ISR
-}
-
-void menu_timer_isr()
-{
+}                                                                               //
+                                                                                //    
+void menu_timer_isr()                                                           //
+{                                                                               //
     g_menu_timer_flag = 1;                                                      // set flag in ISR
-}
-
+}                                                                               //
+                                                                                //        
 void OnStartup()                                                                // Run some start up display 
-{
+{                                                                               //
     Buzzer.period(1.0/659.0);                                                   // Welcome sounds from Piezo
     Buzzer = 0.5;                                                               //                   
     wait(0.5);                                                                  // 
@@ -191,7 +191,7 @@
     lcd.printString("  Smart Cold",0,1);                                        // Just a welcome message before auto moving to main menu
     lcd.printString("   Storage",0,2);                                          //
     lcd.printString("  Monitoring",0,3);                                        // 
-    lcd.printString("V16 - Jan 2022",0,4);                                      //
+    lcd.printString("V17 - Jan 2022",0,4);                                      //
     lcd.printString("--------------",0,5);                                      //
     lcd.refresh();                                                              // Need to refresh display after setting pixels or writing strings 
     wait(5.0);                                                                  // Leave welcome screen on for designated amount of time
@@ -207,125 +207,128 @@
     wait(5.0);                                                                  //
     init_PCB();                                                                 // Ran again to ensure all LED's etc are turned off
     printf("Transition to Temp Selection %i\n",StartTemp);                      // Observe on serial port - ensure transition to correct screen
-}
-
+}                                                                               //
+                                                                                //
 enum EMenuState                                                                 // An enum controlling the current state of the display.
-{
-    MENUSTATE_StartTemp,                                                        // Defining each menu state to be called upon later
-    MENUSTATE_Main,                                                             // Defining each menu state to be called upon later
-    MENUSTATE_Monitor,                                                          // Defining each menu state to be called upon later
-    MENUSTATE_OneOff,                                                           // Defining each menu state to be called upon later
-    MENUSTATE_Results,                                                          // Defining each menu state to be called upon later
-    MENUSTATE_About,                                                            // Defining each menu state to be called upon later
-    MENUSTATE_Author,                                                           // Defining each menu state to be called upon later
-    
-    MENUSTATTE_Num,                                                             // This is a special enum value that just gives is a way to get the number of elements in the enum.
-};
-
-void Run()
-{
+{                                                                               //
+    MENUSTATE_StartTemp,                                                        // Defining each menu state to be called upon later (Integer Value of 0)
+    MENUSTATE_Main,                                                             // Defining each menu state to be called upon later (Integer Value of 1)
+    MENUSTATE_Monitor,                                                          // Defining each menu state to be called upon later (Integer Value of 2)
+    MENUSTATE_OneOff,                                                           // Defining each menu state to be called upon later (Integer Value of 3)
+    MENUSTATE_Results,                                                          // Defining each menu state to be called upon later (Integer Value of 4)
+    MENUSTATE_About,                                                            // Defining each menu state to be called upon later (Integer Value of 5)
+    MENUSTATE_Author,                                                           // Defining each menu state to be called upon later (Integer Value of 6)
+                                                                                //    
+    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
+};                                                                              //
+                                                                                //
+void Run()                                                                      //
+{                                                                               //    
     int MenuState = MENUSTATE_StartTemp;                                        // Ensuring that the first Menu State to be brought up is the Temperature Selection Page 
     int SelectedItem = 0;                                                       // 
     int NumMenuItems = 1;                                                       // 
-    
+    int NumFramesInState = 0;                                                   // How many frames have we been in the current menu state.
+                                                                                //    
     char buffer[14];                                                            // Each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
-    
-    while(1){
+                                                                                //
+    FILE *fp = NULL;                                                            // This is our file pointer
+                                                                                //
+    while(1){                                                                   // Project infinite while loop       
         if (g_menu_timer_flag){                                                 //        
             g_menu_timer_flag = 0;                                              // 
-            
+                                                                                //
             bool bAButtonWasPressed = g_ButtonA_flag;                           // Get the value of the input flags and reset them
             bool bBButtonWasPressed = g_ButtonB_flag;                           // Get the value of the input flags and reset them
             g_ButtonA_flag = 0;                                                 // 
             g_ButtonB_flag = 0;                                                 // 
-            
-            lcd.clear();                                                        // clear buffer at start of every loop
-                        
+                                                                                //
+            lcd.clear();                                                        // Clear buffer at start of every loop
+                                                                                //
             int NewMenuState = MENUSTATTE_Num;                                  // The new menu we want to transition to, if any.
-        
+                                                                                //
             switch(MenuState)                                                   // Update and Draw whichever menu we're on.
-            {      
+            {                                                                   //
                 case MENUSTATE_StartTemp:                                       //
-                {                    
+                {                                                               //
                     NumMenuItems = 1;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
-                    }
-                    Direction d = joystick.get_direction();                               
-                    
-                    StartTemp();
-                    
-                    float g_StartTemp = fsm[g_state].output;                    // read temperature and print to lcd
+                    }                                                           //
+                    Direction d = joystick.get_direction();                     //          
+                                                                                //    
+                    StartTemp();                                                //
+                                                                                //
+                    float g_StartTemp = fsm[g_state].output;                    // Read temperature from FSM and print selection to LCD
                     pc.printf("T = %f C\n",g_StartTemp);                        // Print to serial - allows testing without device attached
                     printf ("Joystick Direction Points = %i\n",d);              //
                     printf ("State selected = %i\n", g_state);                  //
-                    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
-                    if (length <= 14){                                          // if string will fit on display (assuming printing at x=0)
+                    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
+                    if (length <= 14){                                          // If string will fit on display (assuming printing at x=0)
                         lcd.printString("- Set Target -",0,0);                  // 
                         lcd.printString("---- Temp ----",0,1);                  // 
-                        lcd.printString(buffer,0,3);                            // display on screen
+                        lcd.printString(buffer,0,3);                            // Display on screen
                         lcd.printString("'A' to Select",0,5);                   //                      
-                        lcd.refresh();      
+                        lcd.refresh();                                          //
                     }                                                           // need to refresh display after setting pixels or writing strings 
- 
+                                                                                //
                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
-                    {
+                    {                                                           //    
                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
                         {                                                       // Actually 0 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_Main;                      // 
-                        }
-                    }
-                }
+                        }                                                       //
+                    }                                                           //
+                }                                                               //
                 break;                                                          //         
                 case MENUSTATE_Main:                                            //
-                {
+                {                                                               //    
                     NumMenuItems = 5;                                           // Details number of items in the menu. We need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         SelectedItem = 0;                                       // Something has gone wrong, reset selected item.
-                    }
+                    }                                                           // 
                     lcd.printString("---- MENU ----",0,0);                      // Menu title and selectable options    
                     lcd.printString("M1 - Monitor",0,1);                        // Printed to the LCD screen
                     lcd.printString("M2 - One-off",0,2);                        // 
                     lcd.printString("Results",0,3);                             //
                     lcd.printString("About",0,4);                               //
                     lcd.printString("Author",0,5);                              // 
-                    
+                                                                                // 
                     if(bAButtonWasPressed)                                      // If A was pressed then we transition to the selected screen.
-                    {
+                    {                                                           // 
                         if(SelectedItem == 0)                                   // If 0 line is selected, move to detailed menu 
                         {                                                       // Actually 0 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_Monitor;                   // 
-                        }
+                        }                                                       // 
                         else if(SelectedItem == 1)                              // If 1 line is selected, move to detailed menu 
                         {                                                       // Actually 1 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_OneOff;                    // 
-                        }
+                        }                                                       // 
                         else if(SelectedItem == 2)                              // If 2 line is selected, move to detailed menu 
                         {                                                       // Actually 2 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_Results;                   // 
-                        }
+                        }                                                       //
                         else if(SelectedItem == 3)                              // If 3 line is selected, move to detailed menu 
                         {                                                       // Actually 3 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_About;                     // 
-                        }
+                        }                                                       //        
                         else if(SelectedItem == 4)                              // If 4 line is selected, move to detailed menu 
                         {                                                       // Actually 4 line + 1, see circle draw and selection below
                             NewMenuState = MENUSTATE_Author;                    // 
-                        }
-                    }
-                }
+                        }                                                       //
+                    }                                                           //
+                }                                                               //
                 break;                                                          // 
                 case MENUSTATE_Monitor:                                         // Call constant measurement menu following top menu selection
-                {
+                {                                                               //
                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
-                    
+                                                                                //
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
-                    }
-                    
+                    }                                                           //        
+                                                                                //
                     float T = tmp102.get_temperature();                         // read temperature and print to lcd
                     pc.printf("T = %f K\n",T);                                  // Print to serial - allows testing without device attached
                     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
@@ -336,7 +339,7 @@
                     lcd.printString(" 'A' to Menu",0,5);                        // 
                     lcd.refresh();                                              // need to refresh display after setting pixels or writing strings 
                     wait(0.5);                                                  // 
-                    
+                                                                                //
                     if (T >= g_StartTemp + 2) {                                 // High temp alarm condition - in real world would be lot lower!!
                         LED01 = !LED01;                                         // Flash LED01 if temperature is over specified - Simulated starting of cold blowers
                         LED02 = !LED02;                                         // Flash LED02 if temperature is over specified - Simulated starting of cold blowers
@@ -346,34 +349,33 @@
                         Buzzer = 0.5;                                           // 
                         wait(0.5);                                              // 
                         Buzzer = 0;                                             //
-                    } 
-                    else  {
+                    }                                                           //
+                    else  {                                                     //
                         LED01 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
                         LED02 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
                         LED03 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
                         Buzzer = 0;                                             // Buzzer off if temperature is below specified - Simulated stopping of cold blowers
-                    } 
-                    
+                    }                                                           //
+                                                                                //
                     if (T <= g_StartTemp - 2) {                                 // High temp alarm condition - in real world would be lot lower!!
                         LED04 = !LED04;                                         // Flash LED01 if temperature is over specified - Simulated starting of heaters
                         LED05 = !LED05;                                         // Flash LED02 if temperature is over specified - Simulated starting of heaters
                         LED06 = !LED06;                                         // Flash LED03 if temperature is over specified - Simulated starting of heaters
                         printf("WARNING - Low Temp!! \n");                      //
-                        Buzzer.period(1.0/554.0);                               // Warning Buzzer to extremely high 
-                        Buzzer = 0.5;                                           // 
+                        Buzzer.period(1.0/554.0);                               // Warning Buzzer to extremely low
                         wait(0.5);                                              // 
                         Buzzer = 0;                                             //
-                    } 
-                    else  {
+                    }                                                           //
+                    else  {                                                     //    
                         LED04 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
                         LED05 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
                         LED06 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of heaters
                         Buzzer = 0;                                             // Buzzer off if temperature is below specified - Simulated stopping of heaters
-                    } 
+                    }                                                           //
                     if(bAButtonWasPressed)                                      // Check if button was pressed
-                    {
+                    {                                                           //
                         if(SelectedItem == 0)                                   // 
-                        {
+                        {                                                       //
                             NewMenuState = MENUSTATE_Main;                      // Transition back to the main menu
                             LED01 = 1;                                          // Turn off LED upon transition back to main menu
                             LED02 = 1;                                          // Turn off LED upon transition back to main menu
@@ -381,211 +383,200 @@
                             LED04 = 1;                                          // Turn off LED upon transition back to main menu
                             LED05 = 1;                                          // Turn off LED upon transition back to main menu
                             LED06 = 1;                                          // Turn off LED upon transition back to main menu
-                        }
-                    }
-                }
-                break;      
+                        }                                                       //
+                    }                                                           //
+                }                                                               //
+                break;                                                          //
                 case MENUSTATE_OneOff:                                          // Call a one off measurement menu following top menu selection
-                {
+                {                                                               //
                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
-                    }
-                    
-                    OneOff();                                                   // read temperature and print to lcd
-
-                                        
+                    }                                                           //
+                                                                                //        
+                    if(NumFramesInState == 0)                                   //
+                    {                                                           //
+                        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.
+                    }                                                           //
+                                                                                //
+                    pc.printf("T = %f K\n",g_TempReading);                      // Print to serial - allows testing without device attached
+                    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
+                    if (length <= 14){                                          // if string will fit on display (assuming printing at x=0)
+                        lcd.printString("-- One-Off --",0,0);                   // 
+                        lcd.printString("-- Measure --",0,1);                   // 
+                        lcd.printString(buffer,0,3);                            // display on screen
+                        lcd.printString(" 'A' to Menu",0,5);                    // 
+                    }                                                           //
+                                                                                //
                     if(bAButtonWasPressed)                                      // Check if button was pressed
-                    {
+                    {                                                           //
                         if(SelectedItem == 0)                                   // 
-                        {
+                        {                                                       //
                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu
-                        }
-                    }                   
-                    
-                }
-                break; 
+                        }                                                       //
+                    }                                                           //                                                                         
+                }                                                               //
+                break;                                                          //
                 case MENUSTATE_Results:                                         // Call results menu following top menu selection
-                {
-
+                {                                                               //
                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
+                        NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
+                    }                                                           //
+                                                                                //
+                    if(NumFramesInState == 0)                                   //
+                    {                                                           //
+                        if(fp != NULL){                                         //        
+                            printf("Error! File already open!\n");              //
+                            fclose(fp);                                         //
+                        }                                                       //
+                                                                                //
+                        fp = fopen("/sd/overnighttemp.csv", "w");               // Open our file handle on the first frame.  
+                    }                                                           //                                    
+                                                                                //
+                    if (fp == NULL) {                                           // if it can't open the file then print error message
+                        printf("Error! Unable to open file! Returning to main menu.\n");                    //                        
                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
-                    }
-                    
-                    WriteToFile();                                              //
-                    
-                    lcd.printString("--- Results ---",0,0);                     // 
-                    lcd.printString(" ",0,1);                                   // 
-                    lcd.printString(" ",0,2);                                   // 
-                    lcd.printString(" ",0,3);                                   // 
-                    lcd.printString(" ",0,4);                                   // 
-                    lcd.printString(" 'A' to Menu",0,5);                        // 
-                                        
+                    }                                                           //
+                    else                                                        //
+                    {                                                           //
+                        float T = tmp102.get_temperature();                     // Read temperature and print to lcd
+                        pc.printf("T = %f K\n",T);                              // Print to serial - allows testing without device attached
+                        fprintf(fp, "%d,%f\n",NumFramesInState,T);              // Print formatted string to file (CSV)
+                                                                                //
+                        lcd.printString("-- Results --",0,0);                   // 
+                        lcd.printString(" Writing",0,1);                        // 
+                        lcd.printString(" results to ",0,2);                    // 
+                        lcd.printString(" file...",0,3);                        // 
+                        lcd.printString(" ",0,4);                               // 
+                        lcd.printString(" 'A' to Menu",0,5);                    // 
+                    }                                                           //
+                                                                                //
                     if(bAButtonWasPressed)                                      // Check if button was pressed
-                    {
+                    {                                                           //            
                         if(SelectedItem == 0)                                   // 
-                        {
+                        {                                                       //
                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
-                        }
-                    }
-                }
-                break;     
+                        }                                                       //
+                    }                                                           //
+                }                                                               //
+                break;                                                          //
                 case MENUSTATE_About:                                           // Call About menu following top menu selection
-                {
+                {                                                               //
                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
-                    }
-                    
+                    }                                                           //  
+                                                                                //    
                     lcd.printString("--- About ---",0,0);                       // 
                     lcd.printString("ELE3006M - IoT",0,1);                      // 
                     lcd.printString("    Project",0,2);                         // 
                     lcd.printString("Uni of Lincoln",0,3);                      // 
                     lcd.printString(" 'A' to Menu",0,5);                        // 
                     lcd.refresh();                                              // 
-                                        
+                                                                                //
                     if(bAButtonWasPressed)                                      // Check if button was pressed
-                    {
+                    {                                                           //
                         if(SelectedItem == 0)                                   // 
-                        {
+                        {                                                       //
                             NewMenuState = MENUSTATE_Main;                      // Transition back to Main Menu
-                        }
-                    }
-                }
-                break;
+                        }                                                       //
+                    }                                                           //    
+                }                                                               //    
+                break;                                                          //
                 case MENUSTATE_Author:                                          // Call Author menu following top menu selection
-                {
-
+                {                                                               //
                     NumMenuItems = 1;                                           // Detail the number of items in Menu -  need this to wrap the selection around properly etc.
                     if(SelectedItem >= NumMenuItems)                            // 
-                    {
+                    {                                                           //
                         NewMenuState = MENUSTATE_Main;                          // Something has gone wrong, drop back to the main menu.
-                    }
-                    
+                    }                                                           //
+                                                                                //
                     lcd.printString("--- Author ---",0,0);                      // 
                     lcd.printString("David Leaming ",0,1);                      // 
                     lcd.printString("   25574043 ",0,2);                        // 
                     lcd.printString("  VolkerRail",0,3);                        // 
                     lcd.printString(" 'A' to Menu",0,5);                        // 
-                                        
+                                                                                //
                     if(bAButtonWasPressed)                                      // Check if button was pressed
-                    {
+                    {                                                           //
                         if(SelectedItem == 0)                                   // 
-                        {
+                        {                                                       //
                             NewMenuState = MENUSTATE_Main;                      // Take us back to top menu 
-                        }
-                    }
-                }
-                break;
-                
-                default:
-                {
+                        }                                                       //    
+                    }                                                           // 
+                }                                                               //
+                break;                                                          //        
+                default:                                                        //
+                {                                                               //
                     NewMenuState = MENUSTATE_Main;                              // Something has gone wrong, drop back to the main menu.
-                }
-            };
-            
+                }                                                               //
+            };                                                                  //
+                                                                                //
             if(NewMenuState != MENUSTATTE_Num)                                  // If we have requested a new menu state.
-            {
+            {                                                                   //
                 printf("Transitioning to MenuState: %i\n", NewMenuState);       // Observe on serial port - ensure transition to correct screen
-                
+                                                                                //    
                 MenuState = NewMenuState;                                       // We want to transition the menu to a new state.
-                
+                                                                                //
                                                                                 // Do any bookkeeping needed when moving to new state.
-                SelectedItem = 0;                                               // Reset the selected item.   
-                
+                SelectedItem = 0;                                               // Reset the selected item.
+                NumFramesInState = 0;                                           // Reset the frames in current state count.
+                                                                                //
+                if(fp){                                                         //
+                    fclose(fp);                                                 // Ensure we close the file if the current state had one open.
+                    fp = NULL;                                                  //
+                }                                                               //
                 lcd.clear();                                                    // Clear the display for one frame on state transition.
-            }                                                                   
-            else
-            {
+            }                                                                   //
+            else                                                                //
+            {                                                                   //    
+                ++NumFramesInState;                                             //            
+                                                                                
                 unsigned int SelectionMarkerRadius = 4;                                                         // If we have not selected to move to a new menu.
                 unsigned int SelectionMarkerX = WIDTH - (2 * SelectionMarkerRadius);                            // Draw a marker circle at end of line to show which is the currently selected item.
                 unsigned int SelectionMarkerY = (HEIGHT / 5) * (SelectedItem + 1);                              // +1 because of the menu title being on first row
                 lcd.drawCircle(SelectionMarkerX, SelectionMarkerY, SelectionMarkerRadius, FILL_BLACK);          // Fill the circle black so it can be seen easily                                                   
                             
                                                                                 // Handle Joystick Input
-                Direction d = joystick.get_direction();                                                                 
-                printf("Direction = %i\n"); 
+                Direction d = joystick.get_direction();                         //                                        
+                printf("Direction = %i\n", d);                                  //
                 switch (joystick.get_direction())  {                            // Call to check direction joystick is pointing                                     
-                    case N:        
-                    {   
-                        SelectedItem--;                                           
-                        printf("Selection decremented to %i\n", SelectedItem); 
-                    }
+                    case N:                                                     //
+                    {                                                           //        
+                        SelectedItem--;                                         //  
+                        printf("Selection decremented to %i\n", SelectedItem);  //
+                    }                                                           //
                     break;                                                      //
-                    case S:   
-                    {
-                        SelectedItem++;
-                        printf("Selection incremented to %i\n", SelectedItem); 
-                    }
+                    case S:                                                     //
+                    {                                                           //
+                        SelectedItem++;                                         //    
+                        printf("Selection incremented to %i\n", SelectedItem);  //
+                    }                                                           //
                     break;                                                      //
-                }
-                
+                }                                                               //
                 if(SelectedItem < 0)                                            // Wrap the selection around to the start/end of the menu if it goes below 0 or above NumMenuItems.
-                {                   
+                {                                                               //
                     SelectedItem = NumMenuItems - 1;                            // 
-                }
+                }                                                               //
                 else if(SelectedItem >= NumMenuItems)                           //
-                {
+                {                                                               //
                     SelectedItem = 0;                                           // 
-                }
-            }
-            
+                }                                                               //
+            }                                                                   //
             lcd.refresh();                                                      // Finally update the display.
-        }
-    }       
-}  
-
+        }                                                                       //    
+    }                                                                           //
+}                                                                               //
+                                                                                //
 void StartTemp()                                                                //
-{
+{                                                                               //
     Direction d = joystick.get_direction();                                     //
-             
+                                                                                //
         g_StartTemp = fsm[g_state].output;                                      // set ouput depending on current state
         wait(fsm[g_state].time);                                                // wait in that state for desired time           
         g_state = fsm[g_state].nextState[d];                                    // read input and update curent state 
-}
-
-void WriteToFile()                                                              // Function to attempt to write temperature to file
-{
-    printf("#### SD Card Example #####\n");
-    FILE *fp;                                                                   // this is our file pointer
-    
-    float T = tmp102.get_temperature();                                         // read temperature and print to lcd
-    pc.printf("T = %f K\n",T);                                                  // Print to serial - allows testing without device attached
-    
-    fp = fopen("/sd/overnighttemp", "w");                                       // 
-    int ONight_Temp = T;                                                        // 
-    
-    if (fp == NULL) {                                                           // if it can't open the file then print error message
-    printf("Error! Unable to open file!\n");
-    } 
-    else {                                                                      // opened file so can write
-        printf("Writing to file....");
-        for(int i = T; i <= 50; i++) {
-            float T = 1000.0F/i;                                                // dummy variable
-            fprintf(fp, "%d,%f\n",i,T);                                         // print formatted string to file (CSV)
-        }
-        printf("Done.\n");
-        fclose(fp);                                                             // ensure you close the file after writing
-    }
-}
-
-void OneOff()                                                                   // 
-{
-    char buffer[14];                                                            // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14)
-    
-    lcd.clear();                                                                // 
-    
-    float T = tmp102.get_temperature();                                         // read temperature and print to lcd
-    pc.printf("T = %f K\n",T);                                                  // Print to serial - allows testing without device attached
-    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
-    if (length <= 14){                                                          // if string will fit on display (assuming printing at x=0)
-    lcd.printString("-- One-Off --",0,0);                                       // 
-    lcd.printString("-- Measure --",0,1);                                       // 
-    lcd.printString(buffer,0,3);                                                // display on screen
-    lcd.printString(" 'A' to Menu",0,5);                                        // 
-    }                                                                           //
-}                                                                               //
\ No newline at end of file
+}                                                                               //