Control Code with I/O and ADC working

Dependencies:   MODSERIAL mbed

Revision:
21:f87464a7e7c6
Parent:
20:cdeed4dad690
--- a/main.cpp	Mon Jul 16 03:53:59 2018 +0000
+++ b/main.cpp	Wed Jul 18 21:28:45 2018 +0000
@@ -1,5 +1,6 @@
 // MBED SCRIPT FOR CONTROLLING THE TEMPERATURE CONTROLLED TEST FIXTURE (TCTF)
 // DATE: SEPTEMBER 2017
+//CHANGE THE PYTHON CODE TO REFLECT ERROR STATE ENTERED
 
 #include "mbed.h"
 #include "MODSERIAL.h"
@@ -23,39 +24,32 @@
 #define IO_I2C_LINE          1
 #define ADC_I2C_LINE         2
 
-
 #define CHAN_COUNT           8
+#define ERROR_COUNT          6
 #define MIN_TEMP             10
 #define MAX_TEMP             65
-#define MEGA_MAX_TEMP        75
 #define TEMP_MARGIN          10
 #define HYST_LOW             0.3
 #define HYST_HIGH            1
-#define SAMPLES              5
-#define I2C_Freq             2000
-#define VALVE                1
-#define HEATER               2
+#define VALVE_ON             1
+#define HEATER_ON            2
 #define GREEN_STATUS_ON      3
-#define RED_STATUS_ON        0
-#define ERROR_STATUS_ON      1
-#define STATUS_OFF           4
+#define RED_STATUS_ON        4
+#define ERROR_STATUS_ON      5
+#define ALL_OFF              6
 #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
-#define MIN_ERROR_CNT_1      4    //ALL SAFETY RELATEDD CHECKS
-#define MIN_ERROR_CNT_2      600  //PEFORMANCE TIME (HAVE TO GIVE FIXTURE TIME TO SETTLE)
-#define MIN_ERROR_CNT_3      60
 #define NUM_EMAIL_SEND       2
 #define STATUS_COOLING       1
 #define STATUS_HEATING       2
 #define STATUS_INACTIVE      3
 #define STATUS_STANDBY       4
+#define MIN_AD_COUNT         10428 //65C
+#define MAX_AD_COUNT         49169 //10C
+#define MAX_TIME_TO_SP       60    //allow 60 minutes for channel to reach set point
 
 #define READ_TEMP_TASK_TIME  .300f //300ms to read one A/D value
 #define I2C_READ_WAIT_TIME   0.08f
@@ -78,8 +72,22 @@
 #define FW_VERSION_DATA         0xD3
 #define ERROR_DATA              0xDF
 
+// Defines for errors
+#define ERR_OVER_TEMP           0
+#define ERR_UNDER_TEMP          1
+#define ERR_TEMP_DIFF           2
+#define ERR_ACK_LTC             3
+#define ERR_ACK_MCP             4
+#define ERR_SP_TIME             5
+#define MAX_ERROR_CNT           8
 
-const char FW_Version[8] =  "V0.01C";
+#define PRINT_ERROR_CHECK_VALS  0
+#define PRINT_ERRORS            0
+
+
+
+
+const char FW_Version[8] =  "V0.01D";
 unsigned int chanSel_SendTemp = 0;
 unsigned int chanSel_SetTemp = 0;
 // Default to chan 0
@@ -89,7 +97,7 @@
 bool newTempData = false;
 bool newTempDataAvailable = false;
 unsigned int UID_print_count = 0;
-unsigned int debug_control = 0x2;
+unsigned int debug_control = 0x80;
 
 //***********************************************
 // Timers
@@ -99,6 +107,7 @@
 Ticker readThermistorTicker;
 Ticker frontTempInProgTicker;
 Ticker backTempInProgTicker;
+Ticker setPointTimeTicker;
 
 //***********************************************
 // LEDs
@@ -200,21 +209,23 @@
 struct CHNL_DATA{
    bool status;
    float setTemp;
-   int error;
+   bool error;
    int state;
-   int errorEmailSent;
-   int i2cRxed;
+   int LTCi2cAckRxed;
+   int MCPi2cAckRxed;
+   bool SPReached;
+   int SPTime;
 };
 
 CHNL_DATA chnlStatus[] = {
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1},
-    {0, NULL, 0, 0, 0, 1}
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0},
+    {0, NULL, false, 0, 0, 0, false, 0}
 };
 
 
@@ -282,6 +293,8 @@
 
 //TCTF CHANNEL TEMPERATURE
 typedef struct{
+   float currADCFront;
+   float currADCBack;
    float currTempFront;
    float currTempBack;
 }CHNL_TEMP;
@@ -307,6 +320,39 @@
 int chnlSel;
 bool standbyLED[CHAN_COUNT] = {false,false,false,false,false,false,false,false};
 
+int errorCount[CHAN_COUNT][ERROR_COUNT] =
+    {
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0}
+    };
+
+int errorEmailSent[CHAN_COUNT][ERROR_COUNT] =
+    {
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0},
+        {0,0,0,0,0,0}
+    };
+    
+void resetErrorCount(){
+   for(int i = 0; i < CHAN_COUNT; i++){
+       for(int i = 0; i < ERROR_COUNT; i++){
+           errorCount[CHAN_COUNT][ERROR_COUNT] = 0;
+           errorEmailSent[CHAN_COUNT][ERROR_COUNT] = 0;
+        }
+    } 
+}
+
 /* Function: turnOffChannel
    **************************************************************
    Description: Turns off a channel
@@ -393,14 +439,20 @@
                     pc.printf("DBG: Error\n");
                 }
                 else {
-                    chanSel_SetTemp = pRxPkt->chanID;
-                    chnlStatus[pRxPkt->chanID].status = pRxPkt->chanStat;
-                    chnlStatus[pRxPkt->chanID].state = STATUS_INACTIVE;
-                    chnlStatus[pRxPkt->chanID].setTemp = pRxPkt->setTemp;
-                    chnlStatus[pRxPkt->chanID].error = 0;
-                    chnlStatus[pRxPkt->chanID].errorEmailSent = 0;
-                    chnlStatus[pRxPkt->chanID].i2cRxed = 0;
-                    newTempSet = true;
+                    if((pRxPkt->setTemp < MAX_TEMP) && (pRxPkt->setTemp > MIN_TEMP)){
+                        chanSel_SetTemp = pRxPkt->chanID;
+                        chnlStatus[pRxPkt->chanID].status = pRxPkt->chanStat;
+                        chnlStatus[pRxPkt->chanID].state = STATUS_INACTIVE;
+                        chnlStatus[pRxPkt->chanID].setTemp = pRxPkt->setTemp;
+                        chnlStatus[pRxPkt->chanID].error = false;
+                        chnlStatus[pRxPkt->chanID].LTCi2cAckRxed = 0;
+                        chnlStatus[pRxPkt->chanID].MCPi2cAckRxed = 0;
+                        chnlStatus[pRxPkt->chanID].SPReached = false;
+                        chnlStatus[pRxPkt->chanID].SPTime = 0;
+                        memset(errorCount[pRxPkt->chanID], 0, sizeof(int)*ERROR_COUNT);
+                        memset(errorEmailSent[pRxPkt->chanID], 0, sizeof(int)*ERROR_COUNT);
+                        newTempSet = true;
+                    }
                 }
             }
             break;
@@ -502,22 +554,24 @@
     readThermistorTicker.detach();
     //Write to all 8 channels selecting the front port to read
     for(int chnl = 0; chnl < CHAN_COUNT; chnl++){
-        chnlStatus[chnl].i2cRxed = 0;
+        chnlStatus[chnl].LTCi2cAckRxed = 0;
         ltc2487.setAddress(addrLUT[chnl].adc);
         //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
-        chnlStatus[chnl].i2cRxed = !ltc2487.writePort(FRONT_THERM);
+        chnlStatus[chnl].LTCi2cAckRxed = !ltc2487.writePort(FRONT_THERM);
     }
     //wait until next clock cycle on LTC
     //wait(I2C_READ_WAIT_TIME);
     frontTempInProgTicker.attach(&update_front_temp_data, I2C_READ_WAIT_TIME);
 }
 
-void update_front_temp_data()
-{
+void update_front_temp_data(){
+    float countVal;
     frontTempInProgTicker.detach();
     for(int chnl = 0; chnl < CHAN_COUNT; chnl++){
         ltc2487.setAddress(addrLUT[chnl].adc);
-        channelTempData[chnl].currTempFront = get_temp(ltc2487.read());
+        countVal = ltc2487.read();
+        channelTempData[chnl].currADCFront = countVal;
+        channelTempData[chnl].currTempFront = get_temp(countVal);
     }
     //wait until next clock cycle on LTC
     //wait(0.08);
@@ -537,10 +591,10 @@
     frontTempDoneTicker.detach();
     //Write to all 8 channels selecting the front port to read
     for(int chnl = 0; chnl < CHAN_COUNT; chnl++){
-        chnlStatus[chnl].i2cRxed = 0;
+        chnlStatus[chnl].LTCi2cAckRxed = 0;
         ltc2487.setAddress(addrLUT[chnl].adc);
         //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
-        chnlStatus[chnl].i2cRxed = !ltc2487.writePort(BACK_THERM);
+        chnlStatus[chnl].LTCi2cAckRxed = !ltc2487.writePort(BACK_THERM);
     }
 
     //wait until next clock cycle on LTC
@@ -548,12 +602,14 @@
     backTempInProgTicker.attach(&update_back_temp_data, I2C_READ_WAIT_TIME);
 }
 
-void update_back_temp_data()
-{
+void update_back_temp_data(){
+    float countVal;
     backTempInProgTicker.detach();
     for(int chnl = 0; chnl < CHAN_COUNT; chnl++){
         ltc2487.setAddress(addrLUT[chnl].adc);
-        channelTempData[chnl].currTempBack = get_temp(ltc2487.read());
+        countVal = ltc2487.read();
+        channelTempData[chnl].currADCBack = countVal;
+        channelTempData[chnl].currTempBack = get_temp(countVal);
     }
     //wait until next clock cycle on LTC
     //wait(0.08);
@@ -605,132 +661,73 @@
     wait(0.08);
 }
 
-/* Function: turn_valve_on
-   **************************************************************
-   Description: Turn valve on and green status LED on
-   Receives: chn: the channel of the fixture
-   Returns: N/A
-*/
-
-void turn_valve_on(int chn){
-    io_control.setAddress(addrLUT[chn].io);
-    io_control.init();
-    io_control.writeOutput(1,0,1,0);
-}
-
-/* Function: turn_valve_off
-   **************************************************************
-   Description: Turn valve off and green status LED on
-   Receives: chn: the channel of the fixture
-   Returns: N/A
-*/
-
-void turn_valve_off(int chn){
-    io_control.setAddress(addrLUT[chn].io);
-    io_control.init();
-    io_control.writeOutput(0,0,1,0);
-}
-
-/* Function: turn_heater_on
+/* Function: MCP_Control
    **************************************************************
-   Description: Turn heater on and green status LED on
-   Receives: chn: the channel of the fixture
-   Returns: N/A
-*/
-
-void turn_heater_on(int chn){
-    io_control.setAddress(addrLUT[chn].io);
-    io_control.init();
-    io_control.writeOutput(0,1,1,0);
-}
-
-/* Function: turn_heater_off
-   **************************************************************
-   Description: Turn heater off and green status LED on
-   Receives: chn: the channel of the fixture
-   Returns: N/A
-*/
-
-void turn_heater_off(int chn){
-    io_control.setAddress(addrLUT[chn].io);
-    io_control.init();
-    io_control.writeOutput(0,0,1,0);
-}
-
-/* Function: status_led
-   **************************************************************
-   Description: Turn status LED on (turns on green or red)
+   Description: Controls valves/status LEDs
    Receives: chn: the channel of the fixture
              status: the status of channel (good (1) or bad (0))
    Returns: N/A
 */
 
-void status_led(int chn, int status){
+void Chn_Control(int chn, int status){
+    //writeOutput(VALVE, HEATER, GREEN STATUS LED, RED STATUS LED)
+    pc.printf("[%i] CHANNEL CONTROL \r\n", chn);
+    if(status == VALVE_ON){
+        //valve ON, heater OFF,  green status LED ON, red status led OFF
+        if(debug_control & LED_PRINT) pc.printf("VALVE ON %d \r\n", chn);
+        io_control.setAddress(addrLUT[chn].io);
+        io_control.init();
+        chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(1,0,1,0);
+    }
+    if(status == HEATER_ON){
+        //valve ON, heater ON,  green status LED ON, red status led OFF
+        if(debug_control & LED_PRINT) pc.printf("HEATER ON %d \r\n", chn);
+        io_control.setAddress(addrLUT[chn].io);
+        io_control.init();
+        chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,1,1,0);
+    }
     if(status == GREEN_STATUS_ON){
-        //green LED
+        //valve OFF, heater OFF,  green status LED ON, red status led OFF
         if(debug_control & LED_PRINT) pc.printf("GREEN LED %d \r\n", chn);
         io_control.setAddress(addrLUT[chn].io);
         io_control.init();
-        io_control.writeOutput(0,0,1,0);
+         chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,1,0);
     }
     if(status == RED_STATUS_ON){
-        //red LED
+        //valve OFF, heater OFF,  green status LED OFF, red status led ON
         if(debug_control & LED_PRINT) pc.printf("RED LED %d \r\n", chn);
         io_control.setAddress(addrLUT[chn].io);
         io_control.init();
-        io_control.writeOutput(0,0,0,1);
+        chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,0,1);
     }
     if(status == ERROR_STATUS_ON){
-        //turn valve on too
+        //valve ON, heater OFF,  green status LED OFF, red status led ON
         if(debug_control & LED_PRINT) pc.printf("RED AND BLUE LED %d \r\n", chn);
         io_control.setAddress(addrLUT[chn].io);
         io_control.init();
-        io_control.writeOutput(1,0,0,1);
+        chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(1,0,0,1);
     }
-    if(status == STATUS_OFF){
-        //turn valve on too
-            if(debug_control & LED_PRINT) pc.printf("ALL OFF %d \r\n", chn);
+    if(status == ALL_OFF){
+        //valve OFF, heater OFF,  green status LED OFF, red status led OFF
+        if(debug_control & LED_PRINT) pc.printf("ALL OFF %d \r\n", chn);
         io_control.setAddress(addrLUT[chn].io);
         io_control.init();
-        io_control.writeOutput(0,0,0,0);
+        chnlStatus[chn].MCPi2cAckRxed = 0;
+        //Check if write was ack'ed (0 =  ACK, (non)0 = NACK)
+        chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,0,0);
     }
 }
 
-/* Function: test_mcp23008
-   **************************************************************
-   Description: Test each output of the MCP23009
-   Receives: N/A
-   Returns: N/A
-*/
-
-void test_mcp23008(int chn){
-    turn_valve_on(chn);
-    wait(0.5);
-    turn_valve_off(chn);
-    wait(0.5);
-    turn_heater_on(chn);
-    wait(0.5);
-    turn_heater_off(chn);
-    wait(0.5);
-    status_led(chn, 0);
-    wait(0.5);
-    status_led(chn, 1);
-}
-
-/* Function: test_ltc2487
-   **************************************************************
-   Description: Test the reading from LTC2487
-   Receives: N/A
-   Returns: N/A
-*/
-
-void test_ltc2487(){
-    for(int chnl = 0; chnl < CHAN_COUNT; chnl++){
-        float frontTemp = channelTempData[chnl].currTempFront;
-        float backTemp = channelTempData[chnl].currTempBack;
-        pc.printf("TEMPERATURE READING [%i]:: BACK: %f FRONT: %f \r\n", chnl, backTemp, frontTemp);
-    }
-}
 
 //***************************************************************
 // Build packet with temperature readings to send to GUI
@@ -829,9 +826,6 @@
     unsigned char *ptr = (unsigned char *)&response;
     int i;
 
-    if(chnlStatus[chan].errorEmailSent >= NUM_EMAIL_SEND)
-        return;
-
     response.SOF_flag = TX_SOF;
     response.cmd_type = ERROR_DATA;
     response.len = 13;
@@ -846,7 +840,6 @@
         pc.printf("%02x", *ptr);
     pc.printf("\n");
 
-    chnlStatus[chan].errorEmailSent++;
 }
 
 /* Function: toggleI2C
@@ -888,9 +881,58 @@
 
 }
 
+/* Function: sendErrorEmail
+   **************************************************************
+   Description: sends error email
+   Receives: chn: channel to check error on
+   Returns: N/A
+*/
+
+void sendErrorEmail(int chn){
+    int error;
+
+    for (error=0; error < ERROR_COUNT; error++){
+        if((errorCount[chn][error] == MAX_ERROR_CNT) && (!errorEmailSent[chn][error])){
+            sendError(chn, error);
+            errorEmailSent[chn][error] = 1;
+        }
+    }
+}
+
+/* Function: errorCheck
+   **************************************************************
+   Description: Updates error count for the channel
+   Receives: chn: channel to update
+             errorFlag: if the error was encountered
+             errorNum: number of error encountered
+   Returns: N/A
+*/
+
+void errorCheck(int chn, bool errorFlag, int errorNum){
+    if(errorFlag){
+        if(errorCount[chn][errorNum] < MAX_ERROR_CNT){
+            //increase error count
+            errorCount[chn][errorNum]++;
+            pc.printf("[%i] ERROR ENCOUNTERED: %i %i \r\n", chn, errorNum, errorCount[chn][errorNum]);
+        }
+        else{
+            //this is an error, set error flag
+            chnlStatus[chn].error = true;
+            //pc.printf("[%i] ERROR FLAGGED: %i %i\r\n", chn, errorNum, errorCount[chn][errorNum]);
+        }
+    }
+    else{
+        if(errorCount[chn][errorNum] > 0){
+            //decrease error count
+            errorCount[chn][errorNum]--;
+        }
+        //pc.printf("[%i] NO ERROR FLAGGED: %i \r\n\n", chn, errorNum);
+    }
+}
+
 /* Function: softwareReset
    **************************************************************
-   Description: soft Reset
+   Description: soft reset
    Recieves: N/A
    Returns: N/A
 */
@@ -900,6 +942,28 @@
     for(;;){}
 }
 
+/* Function: SP_Time_Check
+   **************************************************************
+   Description: Reset the SP time for each channel every minute
+               (minutes since SP has been set and SP hasn't been reach)
+   Recieves: N/A
+   Returns: N/A
+*/
+
+void SP_Time_Check(){
+    int chan;
+
+    for (chan=0; chan < CHAN_COUNT; chan++){
+        if(chnlStatus[chan].status == 1){
+            if(!chnlStatus[chan].SPReached){
+                if(chnlStatus[chan].SPTime != MAX_TIME_TO_SP){
+                    chnlStatus[chan].SPTime++;
+                }
+            }
+        }
+    }
+}
+
 /* Function: read I2C Line
    **************************************************************
    Description: Read the I2C line to check if pulled high
@@ -926,113 +990,11 @@
     return 0;
 }
 
-/* Function: error_check
-   **************************************************************
-   Description: Checks for any system errors
-   Recieves: frontTemp: temp. of front thermistor
-             backTemp: temp. of back thermistor
-             currTimeMin: currentTime in minutes
-             ioSDA: voltage on the SDA line
-             adcSDA: voltage on the SDA line
-   Returns: N/A
-*/
-
-int error_check(int chnl, float currentTempFront, float currentTempBack, int currTimeMin, int ioSDA, int adcSDA){
-    //check if the thermistors are disconnected
-    if((currentTempFront == 0) || (currentTempBack == 0)){
-        if(chnlStatus[chnl].error >= MIN_ERROR_CNT_1){
-            sendError(chnl, 2);
-            status_led(chnl, RED_STATUS_ON);
-        }
-        else{
-            chnlStatus[chnl].error++;
-        }
-        if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 2 \r\n", chnl);
-        return 1;
-    }
-    //check if the channels are disconnected
-    if(currentTempBack == currentTempFront){
-        if(chnlStatus[chnl].error >= MIN_ERROR_CNT_1){
-        sendError(chnl, 8);
-            status_led(chnl, RED_STATUS_ON);
-    }
-        else{
-            chnlStatus[chnl].error++;
-        }
-        if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 2A \r\n", chnl);
-        return 1;
-    }
-
-    //check if there is a temperature difference |b| front and back
-    if((abs(currentTempBack - currentTempFront) >= TEMP_MARGIN)){
-        if(chnlStatus[chnl].error >= MIN_ERROR_CNT_2){
-            sendError(chnl, 3);
-            status_led(chnl, RED_STATUS_ON);
-        }
-        else{
-            chnlStatus[chnl].error++;
-        }
-        if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 3 \r\n", chnl);
-        return 1;
-    }
-    //check if channels are over the MAX temperature
-    if((currentTempFront >= MAX_TEMP) || (currentTempBack >= MAX_TEMP)){
-        //if fixture over 65C for more than ~60s
-        if(chnlStatus[chnl].error >= MIN_ERROR_CNT_3){
-            sendError(chnl, 1);
-            status_led(chnl, RED_STATUS_ON);
-            if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 1 SOFTWARE RESET %d \r\n", chnl, chnlStatus[chnl].error);
-            softwareReset();
-        }
-        //if fixture over 65C for more than ~1s
-        else if(chnlStatus[chnl].error >= MIN_ERROR_CNT_1){
-             sendError(chnl, 1);
-             status_led(chnl, RED_STATUS_ON);
-             if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 1.9 SOFTWARE RESET %d \r\n", chnl, chnlStatus[chnl].error);
-             chnlStatus[chnl].error++;
-        }
-        else{
-            chnlStatus[chnl].error++;
-        }
-        if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 1 \r\n", chnl);
-        return 1;
-    }
-    //check if the valves are stuck open
-    if(((currentTempFront <= MIN_TEMP) && (currentTempBack <= MIN_TEMP))){
-        if(chnlStatus[chnl].error >= MIN_ERROR_CNT_1){
-            sendError(chnl, 4);
-            status_led(chnl, RED_STATUS_ON );
-        }
-        else{
-            chnlStatus[chnl].error++;
-        }
-        if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 4 \r\n", chnl);
-        return 1;
-    }
-
-    //check that the SDA lines aren't stuck low
-    if((ioSDA != 1) || (adcSDA != 1)){
-            if(chnlStatus[chnl].error >= MIN_ERROR_CNT_1){
-                sendError(chnl, 6);
-                status_led(chnl, RED_STATUS_ON );
-                softwareReset();
-            }
-            else{
-                toggleI2C();
-                chnlStatus[chnl].error++;
-            }
-            if(debug_control & ERROR_PRINT) pc.printf("DBG: [%d] ERROR 6 \r\n", chnl);
-            return 1;
-    }
-    //no errors
-    return 0;
-}
-
 
 /* Function: systemLogic
    **************************************************************
-   Description: Checks for any system errors
-   Receives: Channel to modify
+   Description: Sets setting for fixture needed to maintain temperature at SP
+   Receives: N/A
    Returns: N/A
 */
 
@@ -1061,6 +1023,7 @@
         }
         else{
             //FIXTURE STANDBY
+            pc.printf("FIXTURE IN STANDBY \r\n");
             chnlStatus[chan].state = STATUS_STANDBY;
         }
     }
@@ -1069,48 +1032,124 @@
 
 /* Function: systemControl
    **************************************************************
-   Description: Checks for any system errors
-   Receives: chn: Channel to modify
+   Description: Changes fixture setting in accordance to logic set in systemLOGIC function
+   Receives: N/A
    Returns: N/A
 */
 
 void systemControl()
 {
     int chan;
-
+    
     for (chan=0; chan < CHAN_COUNT; chan++){
-        if(chnlStatus[chan].status == 1){
-            if(chnlStatus[chan].state == STATUS_COOLING){
-                //TURN COOLING ON
-                turn_valve_on(chan);
-            }
-            else if(chnlStatus[chan].state == STATUS_HEATING){
-                //TURN HEATER ON
-                turn_heater_off(chan);
-                turn_heater_on(chan);
-            }
-            else{
-                //FIXTURE INACTIVE
-                status_led(chan, GREEN_STATUS_ON );
+        pc.printf("[%i] CHANNEL ERRORS: %d \r\n", chan, chnlStatus[chan].error);
+        if(!chnlStatus[chan].error){
+            //pc.printf("[%i] CHANNEL NO ERRORS \r\n", chan);
+            if(errorCount[chan][ERR_ACK_LTC] == 0){
+                if(chnlStatus[chan].state == STATUS_INACTIVE){
+                    //FIXTURE INACTIVE
+                    Chn_Control(chan, GREEN_STATUS_ON);
+                    //SP reached
+                    chnlStatus[chan].SPReached = true;
+                }
+                else if(chnlStatus[chan].state == STATUS_COOLING){
+                    //TURN COOLING ON
+                    Chn_Control(chan, VALVE_ON);
+                }
+                else if(chnlStatus[chan].state == STATUS_HEATING){
+                    //TURN HEATER ON (have to toggle bc of charge pump in circuit)
+                    Chn_Control(chan, GREEN_STATUS_ON); //turn heater off
+                    Chn_Control(chan, HEATER_ON);
+                }
+                else if(chnlStatus[chan].state == STATUS_STANDBY){
+                    //FIXTURE IN STANDBY (i.e. off)
+                    if(standbyLED[chan]){
+                        Chn_Control(chan, GREEN_STATUS_ON);
+                        standbyLED[chan] = !standbyLED[chan];
+                    }
+                    else{
+                        Chn_Control(chan, ALL_OFF);
+                        standbyLED[chan] = !standbyLED[chan];
+                    }
+                }
             }
         }
-        else
-        {
-            //FIXTURE INACTIVE
-            if(standbyLED[chan]){
-                status_led(chan, GREEN_STATUS_ON);
-                standbyLED[chan] = !standbyLED[chan];
-            }
-            else{
-                status_led(chan, STATUS_OFF);
-                standbyLED[chan] = !standbyLED[chan];
-            }
+        else{
+            sendErrorEmail(chan);
         }
     }
 }
 
-void systemDiagnostic()
-{
+/* Function: systemDiagnostic
+   **************************************************************
+   Description: Checks for any system errors
+   Receives: chn: Channel to modify
+   Returns: N/A
+*/
+
+void systemDiagnostic(){
+    int chan;
+    float backCount;
+    float frontCount;
+    float backTemp;
+    float frontTemp;
+    bool errorFlag;
+    float tempDiff;
+    int LTC_Ack;
+    int MCP_Ack;
+    int timeToSP;
+    bool reachedSP;
+
+    for (chan=0; chan < CHAN_COUNT; chan++){
+        backCount = channelTempData[chan].currADCBack;
+        frontCount = channelTempData[chan].currADCFront;
+        frontTemp = channelTempData[chan].currTempFront;
+        backTemp = channelTempData[chan].currTempBack;
+        LTC_Ack = chnlStatus[chan].LTCi2cAckRxed;
+        MCP_Ack = chnlStatus[chan].MCPi2cAckRxed;
+        timeToSP = chnlStatus[chan].SPTime;
+        reachedSP = chnlStatus[chan].SPReached;
+        
+        if(PRINT_ERROR_CHECK_VALS){
+            pc.printf("BAKC COUNT: %f \r\n", backCount);
+            pc.printf("FRONT COUNT: %f \r\n", frontCount);
+            pc.printf("TEMP DIFF: %f \r\n", abs(frontTemp-backTemp));
+            pc.printf("LTC ACK: %f \r\n", LTC_Ack);
+            pc.printf("MCP ACK: %f \r\n", MCP_Ack);
+        }
+
+        //Check if the ADC temperature is too high (low ADC count)
+        errorFlag = false;
+        if((backCount < MIN_AD_COUNT) || (frontCount < MIN_AD_COUNT)) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_OVER_TEMP);
+
+        //Check if the ADC temperature is too low (high ADC count), valve stuck on
+        errorFlag = false;
+        if((backCount > MAX_AD_COUNT) || (frontCount > MAX_AD_COUNT)) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_UNDER_TEMP);
+
+        //Check for a substantial temp. diff. |b| the front & back of the fixture
+        errorFlag = false;
+        tempDiff = abs(frontTemp-backTemp);
+        if(tempDiff > TEMP_MARGIN) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_TEMP_DIFF);
+
+        //Check for ACK from the LTC2487 chip (temperature reading)
+        errorFlag = false;
+        if(!LTC_Ack) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_ACK_LTC);
+
+        //Check for ACK from the MCP23008 chip (valve/heater controller)
+        /*errorFlag = false;
+        if(!MCP_Ack) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_ACK_MCP);*/
+
+        //Check if the fixture has not reached SP in X amount of time
+        errorFlag = false;
+        if(!reachedSP && (timeToSP == MAX_TIME_TO_SP)) errorFlag = true;
+        errorCheck(chan, errorFlag, ERR_SP_TIME);
+        
+    }
 }
 
 /*************************************************************/
@@ -1123,14 +1162,17 @@
     // Look for RX_EOF
     uint32_t UIDMH, UIDML, UIDL;
     int UID_print_count = 0;
+    //resetErrorCount();
 
 
     //*********************************
     // Initial thermistors readings
-    // Kick off temperature reding
+    // Kick of SP time updates
+    // Kick off temperature reading
     // state machine
     //*********************************
     readThermistorTicker.attach(&read_front_temp_data, .0001);
+    //setPointTimeTicker.attach(&SP_Time_Check, 60);
 
     pc.baud(9600);
     pc.autoDetectChar(RX_EOF);
@@ -1149,6 +1191,7 @@
         //*********************************
         // Process Rx UART data from GUI
         //*********************************
+        //pc.printf("LOOP \r\n");
         if (dataReceived)
         {
             dataReceived = false;
@@ -1187,5 +1230,4 @@
             newTempDataAvailable = false;
         }
     }
-
-}
+}
\ No newline at end of file