Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TCTF_Control_Main by
main.cpp
00001 // MBED SCRIPT FOR CONTROLLING THE TEMPERATURE CONTROLLED TEST FIXTURE (TCTF) 00002 // DATE: SEPTEMBER 2017 00003 00004 #define FW_VERSION "V.010" 00005 #include "mbed.h" 00006 #include "MODSERIAL.h" 00007 #include "MCP23008.h" 00008 #include "LTC2487.h" 00009 #include <string> 00010 00011 //DEFINITIVE VARIABLES 00012 #define DEBUG 0 00013 #define DEBUG1 0 00014 #define DEBUG2 0 00015 #define DEBUG3 0 00016 #define DEBUG5 0 00017 #define UID_PRINT 1 00018 #define TEMP_PRINT 0 00019 #define LOOP_TIME 0 00020 #define CHN_COUNT 8 00021 #define MIN_TEMP 10 00022 #define MAX_TEMP 65 00023 #define TEMP_MARGIN 20 00024 #define HYST_LOW 0.3 00025 #define HYST_HIGH 1 00026 #define SAMPLES 5 00027 #define I2C_Freq 2000 00028 #define VALVE 1 00029 #define HEATER 2 00030 #define STATUS_GOOD 3 00031 #define STATUS_BAD 0 00032 #define sizeLUT 34 00033 #define BACK_THERM 0 00034 #define FRONT_THERM 1 00035 #define HEAT_FET_AMP 2 00036 #define VALVE_FET_AMP 3 00037 #define FET_ON_CURRENT 1.12 00038 #define ROOM_TEMP 22 00039 #define MAX_HEATER_ON_TIME 25 00040 #define MAX_CHILL_TIME 10 //10sec 00041 00042 // Defines for use with Serial communication 00043 #pragma pack (1) 00044 #define RX_SOF 0x7B 00045 #define RX_EOF 0x7D 00046 #define TX_SOF 0x7B 00047 #define TX_EOF 0x7D 00048 #define DELIMETER 0x2E 00049 #define SET_TEMPERATURE 0xB0 00050 #define SELECT_CHANNEL 0xB1 00051 #define READ_UID 0xB2 00052 #define RESPONSE_DATA 0xD0 00053 #define TEMP_DATA 0xD1 00054 #define UID_DATA 0xD2 00055 #define ERROR_DATA 0xDF 00056 00057 00058 unsigned int chanSel_SendTemp = 0; 00059 unsigned int chanSel_SetTemp = 0; 00060 // Default to chan 0 00061 int currChan = 0; 00062 bool newTempSet = false; 00063 00064 00065 //*********************************************** 00066 // Serial Rx Packet Format 00067 //*********************************************** 00068 typedef struct { 00069 unsigned char SOF_flag; 00070 unsigned char cmd_type; 00071 unsigned char len; 00072 unsigned char Delim; 00073 } HOST_CMD_HEADER; 00074 00075 typedef struct { 00076 HOST_CMD_HEADER cmd_header; 00077 unsigned char chanID; 00078 unsigned char tempDelim; 00079 float setTemp; 00080 unsigned char chanStatDelim; 00081 unsigned char chanStat; 00082 } SET_TEMPERATURE_CMD; 00083 00084 typedef struct { 00085 HOST_CMD_HEADER cmd_header; 00086 unsigned char chanIDSel; 00087 unsigned char chanDelim; 00088 unsigned char chanStat; 00089 } SELECT_CHANNEL_CMD; 00090 00091 typedef struct { 00092 unsigned char SOF_flag; 00093 unsigned char cmd_type; 00094 unsigned char len; 00095 unsigned char Delim; 00096 float data; 00097 unsigned char EOF_flag; 00098 } RESPONSE_CMD; 00099 00100 typedef struct { 00101 unsigned char SOF_flag; 00102 unsigned char cmd_type; 00103 unsigned char len; 00104 unsigned char Delim; 00105 float chTemp[CHN_COUNT]; 00106 unsigned char EOF_flag; 00107 } RESPONSE_TEMP_CMD; 00108 00109 typedef struct { 00110 HOST_CMD_HEADER cmd_header; 00111 unsigned char chanIDSel; 00112 unsigned char chanDelim; 00113 unsigned char chanStat; 00114 } READ_UID_CMD; 00115 00116 typedef struct { 00117 unsigned char SOF_flag; 00118 unsigned char cmd_type; 00119 unsigned char len; 00120 unsigned char Delim; 00121 uint32_t UIDMH; 00122 uint32_t UIDML; 00123 uint32_t UIDL; 00124 unsigned char EOF_flag; 00125 } UID_RESPONSE; 00126 00127 //TCTF CHANNEL DATA 00128 struct CHNL_DATA{ 00129 bool status; 00130 float setTemp; 00131 bool error; 00132 int heater_init_time; 00133 }; 00134 00135 CHNL_DATA chnlStatus[] = { 00136 {0, NULL, 0, 0}, 00137 {0, NULL, 0, 0}, 00138 {0, NULL, 0, 0}, 00139 {0, NULL, 0, 0}, 00140 {0, NULL, 0, 0}, 00141 {0, NULL, 0, 0}, 00142 {0, NULL, 0, 0}, 00143 {0, NULL, 0, 0}, 00144 {0, NULL, 0, 0}, 00145 {0, NULL, 0, 0}, 00146 {0, NULL, 0, 0}, 00147 {0, NULL, 0, 0}, 00148 {0, NULL, 0, 0}, 00149 {0, NULL, 0, 0}, 00150 {0, NULL, 0, 0}, 00151 {0, NULL, 0, 0}, 00152 {0, NULL, 0, 0}, 00153 {0, NULL, 0, 0}, 00154 {0, NULL, 0, 0}, 00155 {0, NULL, 0, 0}, 00156 {0, NULL, 0, 0}, 00157 {0, NULL, 0, 0}, 00158 {0, NULL, 0, 0}, 00159 {0, NULL, 0, 0}, 00160 {0, NULL, 0, 0}, 00161 {0, NULL, 0, 0}, 00162 {0, NULL, 0, 0}, 00163 {0, NULL, 0, 0}, 00164 {0, NULL, 0, 0}, 00165 {0, NULL, 0, 0}, 00166 {0, NULL, 0, 0}, 00167 {0, NULL, 0, 0}, 00168 {0, NULL, 0, 0}, 00169 {0, NULL, 0, 0}, 00170 {0, NULL, 0, 0}, 00171 {0, NULL, 0, 0}, 00172 {0, NULL, 0, 0}, 00173 {0, NULL, 0, 0}, 00174 {0, NULL, 0, 0}, 00175 {0, NULL, 0, 0}, 00176 {0, NULL, 0, 0}, 00177 {0, NULL, 0, 0}, 00178 {0, NULL, 0, 0}, 00179 {0, NULL, 0, 0}, 00180 {0, NULL, 0, 0}, 00181 {0, NULL, 0, 0}, 00182 {0, NULL, 0, 0}, 00183 {0, NULL, 0, 0}, 00184 }; 00185 00186 00187 //I2C AADRESS LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) 00188 struct I2C_ADDR_LUT{ 00189 int adc; 00190 int io; 00191 }; 00192 00193 I2C_ADDR_LUT addrLUT[] = { 00194 {0x23, 0x10}, 00195 {0x53, 0x60}, 00196 {0x43, 0x70}, 00197 {0x73, 0x40}, 00198 {0x63, 0x50}, 00199 {0x22, 0x11}, 00200 {0x52, 0x61}, 00201 {0x42, 0x71}, 00202 {0x72, 0x41}, 00203 {0x62, 0x51}, 00204 {0x21, 0x12}, 00205 {0x51, 0x62}, 00206 {0x41, 0x72}, 00207 {0x71, 0x42}, 00208 {0x61, 0x52}, 00209 {0x20, 0x13}, 00210 {0x50, 0x63}, 00211 {0x40, 0x73}, 00212 {0x70, 0x43}, 00213 {0x60, 0x53}, 00214 {0x26, 0x14}, 00215 {0x56, 0x64}, 00216 {0x46, 0x74}, 00217 {0x76, 0x44}, 00218 {0x66, 0x54}, 00219 {0x2C, 0x1F}, 00220 {0x5C, 0x6F}, 00221 {0x4C, 0x7F}, 00222 {0x7C, 0x4F}, 00223 {0x6C, 0x5F}, 00224 {0x2D, 0x1E}, 00225 {0x5D, 0x6E}, 00226 {0x4D, 0x7E}, 00227 {0x7D, 0x4E}, 00228 {0x6D, 0x5E}, 00229 {0x2E, 0x1D}, 00230 {0x5E, 0x6D}, 00231 {0x4E, 0x7D}, 00232 {0x7E, 0x4D}, 00233 {0x6E, 0x5D}, 00234 {0x2F, 0x1C}, 00235 {0x5F, 0x6C}, 00236 {0x4F, 0x7C}, 00237 {0x7F, 0x4C}, 00238 {0x6F, 0x5C}, 00239 {0x20, 0x1B}, 00240 {0x50, 0x6B}, 00241 {0x40, 0x7B}, 00242 }; 00243 00244 //THERMISTOR LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) 00245 struct THERM_LUT{ 00246 int adc; 00247 int temp; 00248 }; 00249 00250 THERM_LUT thermLUT[] = { 00251 {113779,-40}, 00252 {109152,-35}, 00253 {103830,-30}, 00254 {97855,-25}, 00255 {91319,-20}, 00256 {84352,-15}, 00257 {77124,-10}, 00258 {69820,-5}, 00259 {62621,0}, 00260 {55693,5}, 00261 {49169,10}, 00262 {43144,15}, 00263 {37669,20}, 00264 {32768,25}, 00265 {28429,30}, 00266 {24622,35}, 00267 {21309,40}, 00268 {18439,45}, 00269 {15962,50}, 00270 {13831,55}, 00271 {12002,60}, 00272 {10428,65}, 00273 {9080,70}, 00274 {7919,75}, 00275 {6923,80}, 00276 {6063,85}, 00277 {5323,90}, 00278 {4685,95}, 00279 {4130,100}, 00280 {3653,105}, 00281 {3234,110}, 00282 {2876,115}, 00283 {2563,120}, 00284 {2284,125} 00285 }; 00286 00287 //TCTF CHANNEL TEMPERATURE 00288 typedef struct{ 00289 float currTempFront; 00290 float currTempBack; 00291 }CHNL_TEMP; 00292 00293 CHNL_TEMP channelTempData[CHN_COUNT]; 00294 00295 //SERIAL COMMUNICATION SETUP 00296 MODSERIAL pc(USBTX, USBRX); 00297 00298 //DEFINE PINS 00299 DigitalOut myled(LED2); 00300 00301 //I2C FOR MCP23008 (I/O Control) 00302 MCP23008 io_control(PTC9, PTC8, 0x10, 100000); //sda, scl 00303 00304 //I2C FOR LTC2487 (ADC Control) 00305 LTC2487 ltc2487(PTC11, PTC10, 0x23, 100000); //sda, scl 00306 00307 //GLOBAL VARIABLES 00308 volatile bool dataReceived = false; //used to check if data has been received 00309 volatile bool dataTxReady = false; 00310 char rxBuf[50]; 00311 int chnlSel; 00312 00313 00314 /* Function: turnOffChannel 00315 ************************************************************** 00316 Description: Turns off a channel 00317 Recieves: chnl: channel to turn off 00318 Returns: N/A 00319 */ 00320 00321 void turnOffChannel(int chnl){ 00322 io_control.setAddress(addrLUT[chnl].io); 00323 io_control.init(); 00324 io_control.writeOutput(0,0,0,0); 00325 } 00326 00327 00328 /* Function: rxInterrupt 00329 ************************************************************** 00330 Description: serial rx interupt handler 00331 Receives: N/A 00332 Returns: N/A 00333 */ 00334 00335 DigitalOut rLed(LED1); 00336 DigitalOut gLed(LED2); 00337 00338 void sendUID (); 00339 00340 //*********************************************** 00341 // Rx Interrupt from serial Host interface 00342 //*********************************************** 00343 void rxInterrupt(MODSERIAL_IRQ_INFO *info) 00344 { 00345 gLed = 0; 00346 dataReceived = true; 00347 gLed = 1; 00348 } 00349 00350 00351 //*************************************************************** 00352 // Tx Interrupt from serial Host interface 00353 //*************************************************************** 00354 void txInterrupt(MODSERIAL_IRQ_INFO *info) 00355 { 00356 dataTxReady = true; 00357 } 00358 00359 00360 /* Function: parseRXData 00361 ************************************************************** 00362 Description: The parse received data into 00363 Receives: chn: The channel we want to put into the channel 00364 Returns: N/A 00365 */ 00366 00367 void parseRXData() 00368 { 00369 HOST_CMD_HEADER *pRxPktHdr; 00370 string data = ""; 00371 unsigned char *ptemp; 00372 int i; 00373 00374 pRxPktHdr = (HOST_CMD_HEADER *)rxBuf; 00375 00376 #ifdef DEBUG 00377 pc.printf("DBG: fl=%02x, len=%02x\n", pRxPktHdr->SOF_flag, pRxPktHdr->len); 00378 #endif 00379 00380 // Exit if the packet does not contain correct header 00381 // Maybe send NAK? 00382 if ((pRxPktHdr->SOF_flag != RX_SOF) || (pRxPktHdr->Delim != DELIMETER)) 00383 return; 00384 00385 switch (pRxPktHdr->cmd_type) 00386 { 00387 case SET_TEMPERATURE: 00388 // Process set temp for specified channel 00389 { 00390 SET_TEMPERATURE_CMD *pRxPkt = (SET_TEMPERATURE_CMD *)(rxBuf); 00391 #ifdef DEBUG 00392 pc.printf("DBG: SETTEMP: ch = %02x, tempSet = %f, chanStat = %02x\n", 00393 pRxPkt->chanID, pRxPkt->setTemp, pRxPkt->chanStat); 00394 #endif 00395 if ((pRxPkt->tempDelim != DELIMETER) || (pRxPkt->chanStatDelim != DELIMETER)) { 00396 // Send NAK back 00397 pc.printf("DBG: Error\n"); 00398 } 00399 else { 00400 chanSel_SetTemp = pRxPkt->chanID; 00401 chnlStatus[pRxPkt->chanID].status = pRxPkt->chanStat; 00402 chnlStatus[pRxPkt->chanID].setTemp = pRxPkt->setTemp; 00403 chnlStatus[pRxPkt->chanID].error = 0; 00404 chnlStatus[pRxPkt->chanID].heater_init_time = 0; 00405 newTempSet = true; 00406 } 00407 } 00408 break; 00409 00410 case SELECT_CHANNEL: 00411 // Select channel to send temp data to 00412 { 00413 SELECT_CHANNEL_CMD *pRxPkt = (SELECT_CHANNEL_CMD *)(rxBuf); 00414 00415 chanSel_SendTemp = pRxPkt->chanIDSel; 00416 #ifdef DEBUG 00417 pc.printf("DBG: CHAN_SEL: chan=%02x, chanStat = %02x\n", pRxPkt->chanIDSel, pRxPkt->chanStat); 00418 #endif 00419 } 00420 break; 00421 00422 case READ_UID: 00423 { 00424 READ_UID_CMD *pRxPkt = (READ_UID_CMD *)(rxBuf); 00425 #ifdef DEBUG 00426 pc.printf("DBG: Read UID: chan%02x\n", pRxPkt->chanIDSel); 00427 #endif 00428 sendUID(); 00429 } 00430 break; 00431 00432 default: 00433 // Error 00434 break; 00435 } 00436 } 00437 00438 /* Function: get_temp 00439 ************************************************************** 00440 Description: Convert A/D count to temperature value 00441 Receives: ADC_val: the count from the A/D reading 00442 Returns: the temp. of the A/D reading 00443 */ 00444 00445 float get_temp(float ADC_val){ 00446 myled = 1; 00447 //ltc2487.setAddress(addrLUT[chn].adc); 00448 00449 //float ADC_val = ltc2487.readOutput(port); //(65536*1.334)/2.5 00450 00451 int i = 0; 00452 00453 while((i < sizeLUT) && (thermLUT[i].adc > ADC_val)){ 00454 i++; 00455 } //find the temp. above therm temp 00456 00457 //Point slope formula extrapolation: 00458 // m = (y1-y0)/(x1-x0)+ y0 , y = temp. value, x = adc value 00459 // y1 = thermLUT[i-1].temp y0 = thermLUT[i].temp 00460 // x1 = thermLUT[i-1].adc x0 =thermLUT[i].adc 00461 float a = float(thermLUT[i-1].temp - thermLUT[i].temp); //slope of temp between points where therm temp is between (Tmax - Tmin) 00462 float b = float(thermLUT[i-1].adc - thermLUT[i].adc); //slope of adc between points where therm adc is between (Amax - Amin) 00463 00464 float m = a/b; 00465 float y = (m*(ADC_val-thermLUT[i].adc))+thermLUT[i].temp; 00466 00467 if(DEBUG3) pc.printf("DBG: ADC VAL: %f TEMP: %f \r\n", ADC_val, y); 00468 00469 return y; 00470 } 00471 00472 /* Function: get_temp_DATA 00473 ************************************************************** 00474 Description: Read A/D data from LTC2487 and set array with front and back temp. 00475 Receives: N/A 00476 Returns: N/A 00477 */ 00478 00479 void get_temp_data(){ 00480 //Write to all 8 channels selecting the front port to read 00481 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00482 ltc2487.setAddress(addrLUT[chnl].adc); 00483 ltc2487.writePort(FRONT_THERM); 00484 } 00485 //wait until next clock cycle on LTC 00486 wait(0.08); 00487 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00488 ltc2487.setAddress(addrLUT[chnl].adc); 00489 channelTempData[chnl].currTempFront = get_temp(ltc2487.read()); 00490 } 00491 //wait until next clock cycle on LTC 00492 wait(0.08); 00493 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00494 ltc2487.setAddress(addrLUT[chnl].adc); 00495 ltc2487.writePort(BACK_THERM); 00496 } 00497 //wait until next clock cycle on LTC 00498 wait(0.08); 00499 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00500 ltc2487.setAddress(addrLUT[chnl].adc); 00501 channelTempData[chnl].currTempBack = get_temp(ltc2487.read()); 00502 } 00503 } 00504 00505 /* Function: get_heater_current 00506 ************************************************************** 00507 Description: Retrieve current into heater control MOSFET 00508 Receives: chn: the channel of the fixture to read current from 00509 Returns: the current into the heater control MOSFET 00510 */ 00511 00512 float get_heater_current(int chn, int port){ 00513 ltc2487.setAddress(addrLUT[chn].adc); 00514 ltc2487.writePort(HEAT_FET_AMP); 00515 wait(0.08); 00516 ltc2487.read(); 00517 wait(0.08); 00518 } 00519 00520 /* Function: get_valve_current 00521 ************************************************************** 00522 Description: Retrieve current into valve control MOSFET 00523 Receives: chn: the channel of the fixture to read current from 00524 Returns: the current into the valve control MOSFET 00525 */ 00526 00527 float get_valve_current(int chn, int port){ 00528 ltc2487.setAddress(addrLUT[chn].adc); 00529 ltc2487.writePort(VALVE_FET_AMP); 00530 wait(0.08); 00531 ltc2487.read(); 00532 wait(0.08); 00533 } 00534 00535 /* Function: turn_valve_on 00536 ************************************************************** 00537 Description: Turn valve on and green status LED on 00538 Receives: chn: the channel of the fixture 00539 Returns: N/A 00540 */ 00541 00542 void turn_valve_on(int chn){ 00543 io_control.setAddress(addrLUT[chn].io); 00544 io_control.init(); 00545 io_control.writeOutput(1,0,1,0); 00546 } 00547 00548 /* Function: turn_valve_off 00549 ************************************************************** 00550 Description: Turn valve off and green status LED on 00551 Receives: chn: the channel of the fixture 00552 Returns: N/A 00553 */ 00554 00555 void turn_valve_off(int chn){ 00556 io_control.setAddress(addrLUT[chn].io); 00557 io_control.init(); 00558 io_control.writeOutput(0,0,1,0); 00559 } 00560 00561 /* Function: turn_heater_on 00562 ************************************************************** 00563 Description: Turn heater on and green status LED on 00564 Receives: chn: the channel of the fixture 00565 Returns: N/A 00566 */ 00567 00568 void turn_heater_on(int chn){ 00569 io_control.setAddress(addrLUT[chn].io); 00570 io_control.init(); 00571 io_control.writeOutput(0,1,1,0); 00572 } 00573 00574 /* Function: turn_heater_off 00575 ************************************************************** 00576 Description: Turn heater off and green status LED on 00577 Receives: chn: the channel of the fixture 00578 Returns: N/A 00579 */ 00580 00581 void turn_heater_off(int chn){ 00582 io_control.setAddress(addrLUT[chn].io); 00583 io_control.init(); 00584 io_control.writeOutput(0,0,1,0); 00585 } 00586 00587 /* Function: status_led 00588 ************************************************************** 00589 Description: Turn status LED on (turns on green or red) 00590 Receives: chn: the channel of the fixture 00591 status: the status of channel (good (1) or bad (0)) 00592 Returns: N/A 00593 */ 00594 00595 void status_led(int chn, int status){ 00596 io_control.setAddress(addrLUT[chn].io); 00597 if(status){ 00598 io_control.writeOutput(0,0,1,0); 00599 } 00600 else{ 00601 //turn valve on too 00602 io_control.writeOutput(1,0,0,1); 00603 } 00604 } 00605 00606 /* Function: test_mcp23008 00607 ************************************************************** 00608 Description: Test each output of the MCP23009 00609 Receives: N/A 00610 Returns: N/A 00611 */ 00612 00613 void test_mcp23008(int chn){ 00614 turn_valve_on(chn); 00615 wait(0.5); 00616 turn_valve_off(chn); 00617 wait(0.5); 00618 turn_heater_on(chn); 00619 wait(0.5); 00620 turn_heater_off(chn); 00621 wait(0.5); 00622 status_led(chn, 0); 00623 wait(0.5); 00624 status_led(chn, 1); 00625 } 00626 00627 /* Function: test_ltc2487 00628 ************************************************************** 00629 Description: Test the reading from LTC2487 00630 Receives: N/A 00631 Returns: N/A 00632 */ 00633 00634 void test_ltc2487(){ 00635 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00636 float frontTemp = channelTempData[chnl].currTempFront; 00637 float backTemp = channelTempData[chnl].currTempBack; 00638 pc.printf("TEMPERATURE READING [%i]:: BACK: %f FRONT: %f \r\n", chnl, backTemp, frontTemp); 00639 } 00640 } 00641 00642 //*************************************************************** 00643 // Build packet with temperature readings to send to GUI 00644 //*************************************************************** 00645 void sendTempReadings(){ 00646 RESPONSE_TEMP_CMD response; 00647 unsigned char *ptr = (unsigned char *)&response; 00648 int i; 00649 00650 response.SOF_flag = TX_SOF; 00651 response.cmd_type = TEMP_DATA; 00652 response.len = 5+(sizeof(response.chTemp)); 00653 response.Delim = DELIMETER; 00654 response.chTemp[0] = channelTempData[0].currTempBack; 00655 response.chTemp[1] = channelTempData[1].currTempBack; 00656 response.chTemp[2] = channelTempData[2].currTempBack; 00657 response.chTemp[3] = channelTempData[3].currTempBack; 00658 response.chTemp[4] = channelTempData[4].currTempBack; 00659 response.chTemp[5] = channelTempData[5].currTempBack; 00660 response.chTemp[6] = channelTempData[6].currTempBack; 00661 response.chTemp[7] = channelTempData[7].currTempBack; 00662 /*float *dst = (float *)&response.chTemp[0]; 00663 float *src = (float *)&channelTempData[0]; 00664 memcpy(dst, src, sizeof(channelTempData));*/ 00665 response.EOF_flag = TX_EOF; 00666 00667 // Send response to GUI 00668 for (i=0; i < response.len; i++, ptr++) 00669 pc.printf("%02x", *ptr); 00670 pc.printf("\n"); 00671 } 00672 00673 //*************************************************************** 00674 // Build packet with Board UID (Unique Identification) 00675 //*************************************************************** 00676 void sendUID () 00677 { 00678 UID_RESPONSE response; 00679 unsigned char *ptr = (unsigned char *)&response; 00680 int i; 00681 00682 response.SOF_flag = TX_SOF; 00683 response.cmd_type = UID_DATA; 00684 response.len = 17; 00685 response.Delim = DELIMETER; 00686 response.UIDMH = (uint32_t)SIM->UIDMH; 00687 response.UIDML = (uint32_t)SIM->UIDML; 00688 response.UIDL = (uint32_t)SIM->UIDL; 00689 response.EOF_flag = TX_EOF; 00690 00691 // Send response to GUI 00692 for (i=0; i < response.len; i++, ptr++) 00693 pc.printf("%02x", *ptr); 00694 pc.printf("\n"); 00695 } 00696 00697 //*************************************************************** 00698 // Build packet with errors to send to GUI 00699 //*************************************************************** 00700 void sendError (int chan, float error) 00701 { 00702 RESPONSE_CMD response; 00703 unsigned char *ptr = (unsigned char *)&response; 00704 int i; 00705 00706 response.SOF_flag = TX_SOF; 00707 response.cmd_type = ERROR_DATA; 00708 response.len = 9; 00709 response.Delim = DELIMETER; 00710 response.data = (float)error; 00711 response.EOF_flag = TX_EOF; 00712 00713 // Send response to GUI 00714 for (i=0; i < response.len; i++, ptr++) 00715 pc.printf("%02x", *ptr); 00716 pc.printf("\n"); 00717 } 00718 00719 /* Function: error_check 00720 ************************************************************** 00721 Description: Checks for any system errors 00722 Recieves: frontTemp: temp. of front thermistor 00723 backTemp: temp. of back thermistor 00724 currTimeMin: currentTime in minutes 00725 Returns: N/A 00726 */ 00727 00728 void error_check(int chnl, float currentTempFront, float currentTempBack, int currTimeMin){ 00729 if((currentTempFront >= MAX_TEMP) && (currentTempBack >= MAX_TEMP)){ 00730 status_led(chnl, STATUS_BAD); 00731 sendError(chnl, 1); 00732 chnlStatus[chnl].error = 1; 00733 if(DEBUG3) pc.printf("DBG: [%d] ERROR 1 \r\n", chnl); 00734 } 00735 if(((currentTempFront == 0) || (currentTempBack == 0))){ 00736 status_led(chnl, STATUS_BAD); 00737 sendError(chnl, 2); 00738 chnlStatus[chnl].error = 1; 00739 if(DEBUG3) pc.printf("DBG: [%d] ERROR 2 \r\n", chnl); 00740 } 00741 if((abs(currentTempBack - currentTempFront) >= TEMP_MARGIN)){ 00742 status_led(chnl, STATUS_BAD); 00743 sendError(chnl, 3); 00744 chnlStatus[chnl].error = 1; 00745 if(DEBUG3) pc.printf("DBG: [%d] ERROR 3 \r\n", chnl); 00746 } 00747 if(((currentTempFront <= MIN_TEMP) && (currentTempBack <= MIN_TEMP))){ 00748 status_led(chnl, STATUS_BAD); 00749 sendError(chnl, 4); 00750 chnlStatus[chnl].error = 1; 00751 if(DEBUG3) pc.printf("DBG: [%d] ERROR 4 \r\n", chnl); 00752 } 00753 if(chnlStatus[chnl].heater_init_time != 0){ 00754 int init_time = chnlStatus[chnl].heater_init_time; 00755 int on_time_heater = currTimeMin - init_time; 00756 //account for 0 crossover 00757 if(init_time > currTimeMin){ 00758 on_time_heater = (60 - init_time)+currTimeMin; 00759 } 00760 00761 if(on_time_heater > MAX_HEATER_ON_TIME){ 00762 status_led(chnl, STATUS_BAD); 00763 sendError(chnl, 5); 00764 chnlStatus[chnl].error = 1; 00765 chnlStatus[chnl].heater_init_time = 0; 00766 if(DEBUG3) pc.printf("DBG: [%d] ERROR 5 \r\n", chnl); 00767 } 00768 } 00769 if(chnlStatus[chnl].error == 1){ 00770 status_led(chnl, STATUS_BAD); 00771 chnlStatus[chnl].error = 1; 00772 } 00773 } 00774 00775 00776 /*************************************************************/ 00777 /* MAIN FUNCTION */ 00778 /*************************************************************/ 00779 00780 int main() { 00781 //variables for controlling board 00782 Timer t; 00783 Timer t_cool; 00784 int time_min = 0; 00785 int init_heat_time = 0; 00786 uint32_t UIDMH, UIDML, UIDL; 00787 00788 // Setup serial port 00789 // Look for RX_EOF 00790 pc.baud(9600); 00791 pc.autoDetectChar(RX_EOF); 00792 pc.attach(&rxInterrupt, MODSERIAL::RxAutoDetect); 00793 00794 myled = 1; 00795 rLed = 1; 00796 gLed = 0; 00797 00798 t.start(); 00799 00800 sendUID(); 00801 00802 UIDMH = (uint32_t)SIM->UIDMH; 00803 UIDML = (uint32_t)SIM->UIDML; 00804 UIDL = (uint32_t)SIM->UIDL; 00805 00806 while(1) { 00807 //test_mcp23008(0); 00808 if(UID_PRINT) { 00809 pc.printf("DBG: <%f>[UID: %04X%08X%08X] PSTARTED\n", t.read(), UIDMH, UIDML, UIDL); 00810 } 00811 00812 //SETUP TIMER USED TO TRACK HOW LONG THE HEATER IS ON 00813 float time_sec = t.read(); 00814 00815 if(time_sec >= 60){ 00816 time_min++; 00817 //time_sec = 0; 00818 t.reset(); 00819 } 00820 00821 if(time_min >= 60){ 00822 time_min = 0; 00823 } 00824 00825 //GET TEMPERATURE DATA 00826 get_temp_data(); 00827 00828 //SEND TEMPERATURE DATA FOR LOGGING 00829 sendTempReadings(); 00830 00831 time_sec = t.read(); 00832 if(LOOP_TIME) pc.printf("\r TIME: %f s\r\n", time_sec); 00833 00834 //CONTROL LOOP: LOOPS THROUGH EVERY CHANNEL AND CONTROLS THE FIXTURE IN RESPONSE 00835 for(int chnl = 0; chnl < CHN_COUNT; chnl++){ 00836 00837 //check if we received data/need to update TCTF data 00838 if(dataReceived){ 00839 dataReceived = false; 00840 #ifdef DEBUG 00841 pc.printf("DBG: %d bytes Rx'd\n", pc.rxBufferGetCount()); 00842 #endif 00843 pc.move(rxBuf, 50); 00844 parseRXData(); 00845 pc.rxBufferFlush(); 00846 } 00847 00848 //update channel temperature data 00849 float currentTempFront = channelTempData[chnl].currTempFront; 00850 float currentTempBack = channelTempData[chnl].currTempBack; 00851 00852 //float currentTempBack = get_temp(chnl, BACK_THERM); 00853 float currentTemp = currentTempBack; 00854 00855 //Error check on fixture 00856 error_check(chnl, currentTempFront, currentTempBack, time_min); 00857 00858 if(TEMP_PRINT) pc.printf("DBG: TEMPERATURE: [%d] Temp: F: %f B: %f\r\n", chnl, currentTempFront, currentTempBack); 00859 00860 //CONTROL LOOP: 00861 if(chnlStatus[chnl].status == 1){ 00862 if(DEBUG) pc.printf("DBG: [%d] Temp: F: %f B: %f\r\n", chnl, currentTempFront, currentTempBack); 00863 //main loop for channels 00864 if(chnlStatus[chnl].error == 0){ 00865 if(currentTemp > ((chnlStatus[chnl].setTemp)+HYST_HIGH)){ 00866 if(DEBUG) pc.printf("DBG: [%d] Chiller ON \r\n", chnl); 00867 //reset heater on time 00868 chnlStatus[chnl].heater_init_time = 0; 00869 //Turn chiller on 00870 turn_valve_on(chnl); 00871 } 00872 else if (currentTemp < ((chnlStatus[chnl].setTemp)-HYST_LOW)){ 00873 if(DEBUG) pc.printf("DBG: [%d] Heater ON \r\n", chnl); 00874 //establish starting time for heater 00875 if(chnlStatus[chnl].heater_init_time == 0){ //check if it is the first time that heater has turned on 00876 //make sure time isn't zero, otherwise keeping looping until we are not at 0 00877 if(time_min != 0){ 00878 chnlStatus[chnl].heater_init_time = time_min; 00879 } 00880 } 00881 if(DEBUG2) 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)); 00882 //Turn heater on 00883 turn_heater_on(chnl); 00884 } 00885 else{ 00886 if(DEBUG) pc.printf("DBG: [%d] All OFF \r\n", chnl); 00887 //reset heater on time 00888 chnlStatus[chnl].heater_init_time = 0; 00889 //turn off chiller 00890 turn_valve_off(chnl); 00891 //turn off heater 00892 turn_heater_off(chnl); 00893 //turn on green LED status light 00894 status_led(chnl, 1); 00895 } 00896 } 00897 } 00898 else{ 00899 if(chnlStatus[chnl].error == 0){ 00900 //turn off chiller 00901 turn_valve_off(chnl); 00902 //turn off heater 00903 turn_heater_off(chnl); 00904 //turn on green LED status light 00905 status_led(chnl, 1); 00906 } 00907 else{ 00908 status_led(chnl, STATUS_BAD); 00909 } 00910 //reset heater on time 00911 chnlStatus[chnl].heater_init_time = 0; 00912 } 00913 } 00914 } 00915 }
Generated on Fri Jul 15 2022 01:55:39 by
1.7.2
