Control Code with I/O and ADC working

Dependencies:   MODSERIAL mbed

Revision:
14:69cd53434783
Parent:
13:604e6933366f
Child:
15:74a01aaeb60e
--- a/main.cpp	Tue May 08 17:08:37 2018 +0000
+++ b/main.cpp	Wed May 16 19:31:12 2018 +0000
@@ -8,29 +8,32 @@
 #include <string>
 
 //DEFINITIVE VARIABLES
-#define DEBUG            0
-#define DEBUG1           0
-#define DEBUG2           0
-#define DEBUG3           1
-#define CHN_COUNT        8
-#define MIN_TEMP         10
-#define MAX_TEMP         65
-#define TEMP_MARGIN      20
-#define HYST_LOW         0.3
-#define HYST_HIGH        1
-#define SAMPLES          5
-#define I2C_Freq         2000
-#define VALVE            1
-#define HEATER           2
-#define STATUS_GOOD      3
-#define STATUS_BAD       0
-#define sizeLUT          34
-#define BACK_THERM       0
-#define FRONT_THERM      1
-#define HEAT_FET_AMP     2
-#define VALVE_FET_AMP    3
-#define FET_ON_CURRENT   1.12
-#define ROOM_TEMP        22
+#define DEBUG                0
+#define DEBUG1               0
+#define DEBUG2               0
+#define DEBUG3               1
+#define DEBUG5               0
+#define CHN_COUNT            8
+#define MIN_TEMP             10
+#define MAX_TEMP             65
+#define TEMP_MARGIN          20
+#define HYST_LOW             0.3
+#define HYST_HIGH            1
+#define SAMPLES              5
+#define I2C_Freq             2000
+#define VALVE                1
+#define HEATER               2
+#define STATUS_GOOD          3
+#define STATUS_BAD           0
+#define sizeLUT              34
+#define BACK_THERM           0
+#define FRONT_THERM          1
+#define HEAT_FET_AMP         2
+#define VALVE_FET_AMP        3
+#define FET_ON_CURRENT       1.12
+#define ROOM_TEMP            22
+#define MAX_HEATER_ON_TIME   25
+#define MAX_CHILL_TIME       10 //10sec
 
 // Defines for use with Serial communication
 #pragma pack (1)
@@ -93,57 +96,58 @@
    bool status;
    float setTemp;
    bool error;
+   int heater_init_time;
 };
 
 CHNL_DATA chnlStatus[] = {
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
-    {0, NULL, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
+    {0, NULL, 0, 0},
 };
 
 
@@ -356,6 +360,7 @@
                     chnlStatus[pRxPkt->chanID].status = pRxPkt->chanStat;
                     chnlStatus[pRxPkt->chanID].setTemp = pRxPkt->setTemp;
                     chnlStatus[pRxPkt->chanID].error = 0;
+                    chnlStatus[pRxPkt->chanID].heater_init_time = 0;
                     newTempSet = true;
                 }
             }
@@ -401,7 +406,7 @@
     }  //find the temp. above therm temp
 
     //Point slope formula extrapolation:
-    // y1 = m (x1-x0)+ y0 , y = temp. value, x = adc value
+    // m = (y1-y0)/(x1-x0)+ y0 , y = temp. value, x = adc value
     // y1 = thermLUT[i-1].temp   y0 = thermLUT[i].temp
     // x1 = thermLUT[i-1].adc    x0 =thermLUT[i].adc
     float a = float(thermLUT[i-1].temp - thermLUT[i].temp); //slope of temp between points where therm temp is between (Tmax - Tmin)
@@ -546,52 +551,6 @@
     //if(DEBUG1) pc.printf("TEMPERATURE READING: %f \r\n", get_temp(chn));
 }
 
-/* Function: error_check
-   **************************************************************
-   Description: Checks for any system errors
-   Recieves: frontTemp: temp. of front thermistor
-             backTemp: temp. of back thermistor
-             valveFet: current through valve FET
-             heaterFet: current through heater FET
-   Returns: N/A
-*/
-
-void error_check(int chn, float frontTemp, float backTemp, float valveFet, float heaterFet){
-    float setTemp = chnlStatus[chn].setTemp;
-
-    //CHECK IF THERMISTOR READINGS ARE OFF (> 5 DEGREES)
-    if(abs(frontTemp-backTemp) > 5){
-        //ERROR 6: Thermistor reading off
-        chnlStatus[chn].error = 1;
-    }
-
-    //CHECK IF HEATER'S STUCK ON OR CELL OVERHEATING
-    if((frontTemp >= (setTemp+TEMP_MARGIN)) || (backTemp >= (setTemp+TEMP_MARGIN))){
-         //ERROR 0
-         chnlStatus[chn].error = 1;
-         status_led(chn, STATUS_BAD);
-         if(heaterFet >= FET_ON_CURRENT){
-         //ERROR 1: Heater FET stuck on
-         }
-         if(valveFet <= FET_ON_CURRENT){
-         //ERROR 2: valve FET stuck off
-         }
-    }
-
-    //CHECK IF VALVE STUCK ON OR CELL OVERHEATING
-    if((frontTemp <= (setTemp-TEMP_MARGIN)) || (backTemp <= (setTemp-TEMP_MARGIN))){
-        //ERROR 0
-        chnlStatus[chn].error = 1;
-        status_led(chn, STATUS_BAD);
-        if(heaterFet <= FET_ON_CURRENT){
-        //ERROR 2: Heater FET stuck off
-        }
-        else if(valveFet >= FET_ON_CURRENT){
-        //ERROR 3: Chiller FET stuck on
-        }
-    }
-}
-
 //***************************************************************
 // Build packet with temperature readings to send to GUI
 //***************************************************************
@@ -636,14 +595,73 @@
     pc.printf("\n");
 }
 
+/* Function: error_check
+   **************************************************************
+   Description: Checks for any system errors
+   Recieves: frontTemp: temp. of front thermistor
+             backTemp: temp. of back thermistor
+             currTimeMin: currentTime in minutes
+   Returns: N/A
+*/
+
+void error_check(int chnl, float currentTempFront, float currentTempBack, int currTimeMin){
+    if((currentTempFront >= MAX_TEMP) && (currentTempBack >= MAX_TEMP)){
+        status_led(chnl, STATUS_BAD);
+        sendError(chnl, 1);
+        chnlStatus[chnl].error = 1;
+        if(DEBUG3) pc.printf("DBG: [%d] ERROR 1 \r\n", chnl);
+    }
+    if(((currentTempFront == 0) || (currentTempBack == 0))){
+        status_led(chnl, STATUS_BAD);
+        sendError(chnl, 2);
+        chnlStatus[chnl].error = 1;
+        if(DEBUG3) pc.printf("DBG: [%d] ERROR 2 \r\n", chnl);
+    }
+    if((abs(currentTempBack - currentTempFront) >= TEMP_MARGIN)){
+        status_led(chnl, STATUS_BAD);
+        sendError(chnl, 3);
+        chnlStatus[chnl].error = 1;
+        if(DEBUG3) pc.printf("DBG: [%d] ERROR 3 \r\n", chnl);
+    }
+    if(((currentTempFront <= MIN_TEMP) && (currentTempBack <= MIN_TEMP))){
+        status_led(chnl, STATUS_BAD);
+        sendError(chnl, 4);
+        chnlStatus[chnl].error = 1;
+        if(DEBUG3) pc.printf("DBG: [%d] ERROR 4 \r\n", chnl);
+    }
+    if(chnlStatus[chnl].heater_init_time != 0){
+        int init_time = chnlStatus[chnl].heater_init_time;
+        int on_time_heater = currTimeMin - init_time;   
+        //account for 0 crossover
+        if(init_time > currTimeMin){
+            on_time_heater = (60 - init_time)+currTimeMin;
+        }
+
+        if(on_time_heater > MAX_HEATER_ON_TIME){
+            status_led(chnl, STATUS_BAD);
+            sendError(chnl, 5);
+            chnlStatus[chnl].error = 1;
+            chnlStatus[chnl].heater_init_time = 0;
+            if(DEBUG3) pc.printf("DBG: [%d] ERROR 5 \r\n", chnl);
+        }
+    }
+    if(chnlStatus[chnl].error == 1){
+        status_led(chnl, STATUS_BAD);
+        chnlStatus[chnl].error = 1;
+    }
+}
+
 
 /*************************************************************/
 /*                       MAIN FUNCTION                       */
 /*************************************************************/
 
 int main() {
-
+    //variables for controlling board
     Timer t;
+    Timer t_cool;
+    int time_min = 0;
+    int init_heat_time = 0;
 
     // Setup serial port
     // Look for RX_EOF
@@ -662,23 +680,23 @@
         if(DEBUG3)
             pc.printf("DBG: PROGRAM STARTED \r\n");
 
-        /*float time_sec = t.read();
-        
+        //setup timer used to track how long the heater is on
+        float time_sec = t.read();
+
         if(time_sec >= 60){
+            time_min++;
+            //time_sec = 0;
             t.reset();
         }
-        
-        pc.printf("Time: %f \r\n", time_sec);*/
+
+        if(time_min >= 60){
+           time_min = 0;
+        }
+
+        //pc.printf("Time: %f \r\n", time_sec);
 
         for(int chnl = 0; chnl < CHN_COUNT; chnl++){
             float currentTempFront = get_temp(chnl, FRONT_THERM);
-            //wait(0.08);
-            
-            //float valveCurrent = get_valve_current(chnl, VALVE_FET_AMP);
-            //float heaterCurrent = get_heater_current(chnl, HEAT_FET_AMP);
-            //float currentTemp = currentTempFront;
-            //currentTemp = currentTempFront;
-            
 
             //check if we received data/need to update TCTF data
             if(dataReceived){
@@ -696,48 +714,61 @@
                 //Send temp readings for selected chan to GUI
                 sendTempReadings(currChan, currentTemp);
             }
-            
-            
+
+            //Error check on fixture
+            error_check(chnl, currentTempFront, currentTempBack, time_min);
 
             //CONTROL LOOP:
             if(chnlStatus[chnl].status == 1){
                 if(DEBUG3) pc.printf("DBG: [%d] Temp: F: %f B: %f\r\n", chnl, currentTempFront, currentTempBack);
-
-                //Error check on fixture
-                //error_check(chnl, currentTempFront, currentTempBack, valveCurrent, heaterCurrent);
-                if(((currentTempFront >= MAX_TEMP) && (currentTempBack >= MAX_TEMP)) ||
-                   ((currentTempFront == 0) || (currentTempBack == 0))||
-                    (abs(currentTempBack - currentTempFront) >= TEMP_MARGIN)||
-                   ((currentTempFront <= MIN_TEMP) && (currentTempBack <= MIN_TEMP))||
-                    (chnlStatus[chnl].error == 1)){
-                    status_led(chnl, STATUS_BAD);
-                    sendError(chnl, 1);
-                    chnlStatus[chnl].error = 1;
-                }
-
+                //main loop for channels
                 if(chnlStatus[chnl].error == 0){
                     if(currentTemp > ((chnlStatus[chnl].setTemp)+HYST_HIGH)){
                         if(DEBUG3) pc.printf("DBG: [%d] Chiller ON \r\n", chnl);
+                        //reset heater on time
+                        chnlStatus[chnl].heater_init_time = 0;
+                        //reset cooling timer
+                        float time_sec = 0;
                         //check if the temp. diff. is small and can't wait for an entire period (~4.18) to turn valve off
                         if(abs(currentTemp - (chnlStatus[chnl].setTemp)) < 5){
+                            //start timer
+                            t_cool.start();
+                            //turn chiller on
                             turn_valve_on(chnl);
-                            while(currentTemp > ((chnlStatus[chnl].setTemp)+HYST_HIGH)){
+                            //read timer
+                            time_sec = t_cool.read();
+                            while((currentTemp > ((chnlStatus[chnl].setTemp)+HYST_HIGH)) && (time_sec < MAX_CHILL_TIME)){
                                 currentTemp = get_temp(chnl, BACK_THERM);
+                                time_sec = t_cool.read();
+                                if(DEBUG5) pc.printf("DBG: [%d] TIME: %f \r\n", chnl, time_sec);
                             }
+                            time_sec = 0;
+                            t_cool.stop();
+                            t_cool.reset();
                             turn_valve_off(chnl);
                         }
                         else{
                             //Turn chiller on
-                            turn_valve_on(chnl);    
+                            turn_valve_on(chnl);
                         }
                     }
                     else if (currentTemp < ((chnlStatus[chnl].setTemp)-HYST_LOW)){
                         if(DEBUG3) pc.printf("DBG: [%d] Heater ON \r\n", chnl);
+                        //establish starting time for heater
+                        if(chnlStatus[chnl].heater_init_time == 0){ //check if it is the first time that heater has turned on
+                            //make sure time isn't zero, otherwise keeping looping until we are not at 0
+                            if(time_min != 0){
+                                chnlStatus[chnl].heater_init_time = time_min;
+                            }
+                        }
+                        if(DEBUG5) pc.printf("DBG: TIME ON: %d %d %f %d %d\r\n", chnlStatus[chnl].heater_init_time, time_min, time_sec, init_heat_time, (chnlStatus[chnl].heater_init_time == NULL));
                         //Turn heater on
                         turn_heater_on(chnl);
                     }
                     else{
                         if(DEBUG3) pc.printf("DBG: [%d] All OFF \r\n", chnl);
+                        //reset heater on time
+                        chnlStatus[chnl].heater_init_time = 0;
                         //turn off chiller
                         turn_valve_off(chnl);
                         //turn off heater
@@ -748,12 +779,19 @@
                 }
             }
             else{
-                //turn off chiller
-                turn_valve_off(chnl);
-                //turn off heater
-                turn_heater_off(chnl);
-                //turn on green LED status light
-                status_led(chnl, 1);
+                if(chnlStatus[chnl].error == 0){
+                    //turn off chiller
+                    turn_valve_off(chnl);
+                    //turn off heater
+                    turn_heater_off(chnl);
+                    //turn on green LED status light
+                    status_led(chnl, 1);
+                }
+                else{
+                    status_led(chnl, STATUS_BAD);
+                }
+                //reset heater on time
+                chnlStatus[chnl].heater_init_time = 0;
             }
         }
     }