Addition of FSM to try and set initial starting temperature for use throughout project. Additional menu option. Joystick input 'bouncing' during FSM use - to be debugged

Dependencies:   mbed N5110v02 TMP102 JoystickIoT

Revision:
11:a6eec09b546e
Parent:
10:357b3329620f
diff -r 357b3329620f -r a6eec09b546e main.cpp
--- a/main.cpp	Wed Jan 19 07:37:55 2022 +0000
+++ b/main.cpp	Thu Jan 20 13:42:30 2022 +0000
@@ -23,6 +23,26 @@
 
 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] = {
+    {15,0.5,{0,1,0,0,0,10,0,0,0}},                                                       // Start Temp = 15 Degrees
+    {16,0.5,{1,2,1,1,1,0,1,1,1}},                                                       // 1 
+    {17,0.5,{2,3,2,2,2,1,2,2,2}},                                                    // 
+    {18,0.5,{3,4,3,3,3,2,3,3,3}},                                                // 
+    {19,0.5,{4,5,4,4,4,3,4,4,4}},                                                // 
+    {20,0.5,{5,6,5,5,5,4,5,5,5}},                                                // 
+    {21,0.5,{6,7,6,6,6,5,6,6,6}},                                                // 
+    {22,0.5,{7,8,7,7,7,6,7,7,7}},                                                // 
+    {23,0.5,{8,9,8,8,8,7,8,8,8}},                                                // 
+    {24,0.5,{9,10,9,9,9,8,9,9,9}},                                                // 
+    {25,0.5,{10,1,10,10,10,9,10,10,10}}                                                // 
+};
+
 Ticker ticker_menu;                                                             // Create Menu ticker object
 
 DigitalOut r_led(LED_RED);                                                      // K64F on-board LEDs 
@@ -50,6 +70,8 @@
 volatile int g_sw2_flag = 0;                                                    // flag - must be volatile as changes within ISR - g_ prefix makes it easier to distinguish it as global
 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
 volatile int option = 0;                                                        // Menu option selection based on joystick direction
+volatile int g_state = 0;                                                       // 
+volatile int g_StartTemp = 0;                                                   // 
 
 void error();                                                                   // error function hangs flashing an LED
 void init_serial();                                                             // setup serial port
@@ -63,6 +85,7 @@
 void OnStartup();                                                               // 
 void Run();                                                                     // 
 void ConstantMonitoring();                                                      //   
+void StartTemp();                                                               //
 
 int main()
 {
@@ -82,7 +105,7 @@
     
     lcd.setContrast(0.5);                                                       // change set contrast in range 0.0 to 1.0
     
-    OnStartup();                                                                // Call intro screen    
+    OnStartup();                                                                // Call intro screen   
     Run();                                                                      // Call main-menu and functions
 }      
 
@@ -142,22 +165,22 @@
 
 void OnStartup()                                                                // Run some start up display 
 {
-    Buzzer.period(1.0/659.0);                                                   // Welcome sounds from Piezo
-    Buzzer = 0.5;                                                               //                   
-    wait(0.5);                                                                  // 
-    Buzzer.period(1.0/494.0);                                                   // 
-    Buzzer = 0.5;                                                               //    
-    wait(0.5);                                                                  // 
-    Buzzer.period(1.0/554.0);                                                   // 
-    Buzzer = 0.5;                                                               // 
-    wait(0.5);                                                                  // 
-    Buzzer = 0;                                                                 // Turn off welcome sounds 
+    //Buzzer.period(1.0/659.0);                                                   // Welcome sounds from Piezo
+    //Buzzer = 0.5;                                                               //                   
+   // wait(0.5);                                                                  // 
+    //Buzzer.period(1.0/494.0);                                                   // 
+   // Buzzer = 0.5;                                                               //    
+  //  wait(0.5);                                                                  // 
+    //Buzzer.period(1.0/554.0);                                                   // 
+   // Buzzer = 0.5;                                                               // 
+    //wait(0.5);                                                                  // 
+   // Buzzer = 0;                                                                 // Turn off welcome sounds 
     lcd.clear();                                                                // Clear buffer at start of every loop
     lcd.printString("--------------",0,0);                                      // Can directly print strings at specified co-ordinates (must be less than 84 pixels to fit on display)
     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("V10 - Jan 2022",0,4);                                      //
+    lcd.printString("V11 - 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
@@ -176,6 +199,7 @@
 
 enum EMenuState                                                                 // An enum controlling the current state of the display.
 {
+    MENUSTATE_StartTemp,                                                        //
     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
@@ -205,9 +229,45 @@
             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;                                           // Dont for get to set this when changing 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
+                    pc.printf("T = %f K\n",g_state);                            // Print to serial - allows testing without device attached
+                    printf ("Joystick Direction Points = %i\n",d);              //
+                    printf ("State selected = %i\n", g_StartTemp);                          //
+                    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("'A' to Select",0,5);                        // 
+                    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:                                            //
                 {
 
@@ -270,6 +330,7 @@
                         LED01 = 0;                                              // Light LED01 if temperature is over specified - Simulated starting of cold blowers
                         LED02 = 0;                                              // Light LED02 if temperature is over specified - Simulated starting of cold blowers
                         LED03 = 0;                                              // Light LED03 if temperature is over specified - Simulated starting of cold blowers
+                    printf("WARNING - High Temp!! \n");                         //
                     } 
                     else {
                         LED01 = 1;                                              // LED01 off if temperature is below specified - Simulated stopping of cold blowers
@@ -283,6 +344,7 @@
                         LED04 = 0;                                              // Light LED04 if temperature is over specified - Simulated starting of heaters
                         LED05 = 0;                                              // Light LED05 if temperature is over specified - Simulated starting of heaters
                         LED06 = 0;                                              // Light LED06 if temperature is over specified - Simulated starting of heaters
+                    printf("WARNING - Low Temp!! \n");                          //
                     } 
                     else {
                         LED04 = 1;                                              // LED04 off if temperature is above specified - Simulated stopping of heaters
@@ -305,7 +367,7 @@
                     }
                 }
                 break;      
-                case MENUSTATE_OneOff:                                          // Call a one off measuremnt menu following top menu selection
+                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.
@@ -399,13 +461,13 @@
                 SelectedItem = 0;                                               // Reset the selected item.   
                 
                 lcd.clear();                                                    // Clear the display for one frame on state transition.
-            }                                                                   // Could do something else like invert colour etc here.
+            }                                                                   
             else
             {
                 
-                                                                                                            // If we have not selected to move to a new menu.
-            unsigned int SelectionMarkerRadius = 4       ;                                                  // Draw a marker circle at end of line to show which is the currently selected item.
-            unsigned int SelectionMarkerX = WIDTH - (2 * SelectionMarkerRadius);
+                                                                                                            
+            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                                                   
                             
@@ -434,5 +496,14 @@
         }
     }       
 }  
- 
 
+void StartTemp()                                                                //
+{
+    Direction d = joystick.get_direction();                                     //
+    
+    joystick.init();
+         
+        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 
+}