![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Control Code with I/O and ADC working
main.cpp
- Committer:
- jrodenburg
- Date:
- 2018-02-13
- Revision:
- 4:168a446bd0da
- Parent:
- 3:0c9476da0cad
- Child:
- 5:0f38a0bd4f86
File content as of revision 4:168a446bd0da:
// MBED SCRIPT FOR CONTROLLING THE TEMPERATURE CONTROLLED TEST FIXTURE (TCTF) // DATE: SEPTEMBER 2017 #include "mbed.h" #include "MODSERIAL.h" #include "MCP23008.h" #include "LTC2487.h" #include <string> //DEFINITIVE VARIABLES #define DEBUG 0 #define DEBUG1 1 #define CHN_COUNT 48 #define MIN_TEMP 15 #define MAX_TEMP 60 #define HYST 0.2 #define SAMPLES 5 #define I2C_Freq 2000 #define VALVE 1 #define HEATER 2 #define STATUS_GOOD 3 #define STATUS_BAD 4 #define sizeLUT 34 #define FRONT_THERM 0 #define BACK_THERM 1 #define HEAT_FET_AMP 2 #define VALV_FET_AMP 3 //TCTF CHANNEL DATA struct CHNL_DATA{ bool status; float setTemp; }; CHNL_DATA chnlStatus[] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, }; //I2C AADRESS LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) struct I2C_ADDR_LUT{ int adc; int io; }; I2C_ADDR_LUT addrLUT[] = { {0x23, 0x10}, {0x53, 0x60}, {0x43, 0x70}, {0x73, 0x40}, {0x63, 0x50}, {0x22, 0x11}, {0x52, 0x61}, {0x42, 0x71}, {0x72, 0x41}, {0x62, 0x51}, {0x21, 0x12}, {0x51, 0x62}, {0x41, 0x72}, {0x71, 0x42}, {0x61, 0x52}, {0x20, 0x13}, {0x50, 0x63}, {0x40, 0x73}, {0x70, 0x43}, {0x60, 0x53}, {0x26, 0x14}, {0x56, 0x64}, {0x46, 0x74}, {0x76, 0x44}, {0x66, 0x54}, {0x2C, 0x1F}, {0x5C, 0x6F}, {0x4C, 0x7F}, {0x7C, 0x4F}, {0x6C, 0x5F}, {0x2D, 0x1E}, {0x5D, 0x6E}, {0x4D, 0x7E}, {0x7D, 0x4E}, {0x6D, 0x5E}, {0x2E, 0x1D}, {0x5E, 0x6D}, {0x4E, 0x7D}, {0x7E, 0x4D}, {0x6E, 0x5D}, {0x2F, 0x1C}, {0x5F, 0x6C}, {0x4F, 0x7C}, {0x7F, 0x4C}, {0x6F, 0x5C}, {0x20, 0x1B}, {0x50, 0x6B}, {0x40, 0x7B}, }; //THERMISTOR LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) struct THERM_LUT{ int adc; int temp; }; THERM_LUT thermLUT[] = { {113779,-40}, {109152,-35}, {103830,-30}, {97855,-25}, {91319,-20}, {84352,-15}, {77124,-10}, {69820,-5}, {62621,0}, {55693,5}, {49169,10}, {43144,15}, {37669,20}, {32768,25}, {28429,30}, {24622,35}, {21309,40}, {18439,45}, {15962,50}, {13831,55}, {12002,60}, {10428,65}, {9080,70}, {7919,75}, {6923,80}, {6063,85}, {5323,90}, {4685,95}, {4130,100}, {3653,105}, {3234,110}, {2876,115}, {2563,120}, {2284,125} }; //SERIAL COMMUNICATION SETUP MODSERIAL pc(USBTX, USBRX); //DEFINE PINS DigitalOut myled(LED2); //I2C FOR MCP23008 (I/O Control) MCP23008 io_control(PTC9, PTC8, 0x10, 100000); //sda, scl //I2C FOR LTC2487 (ADC Control) LTC2487 ltc2487(PTC11, PTC10, 0x23, 100000); //sda, scl //GLOBAL VARIABLES volatile bool dataRecieved = false; //used to check if data has been recieved char rxBuf[50]; int chnlSel; /* Function: rxInterrupt ************************************************************** Description: serial rx interupt handler Recieves: N/A Returns: N/A */ void rxInterrupt(MODSERIAL_IRQ_INFO *info){ dataRecieved = true; if(DEBUG) pc.printf("DATA RECIEVED \r\n"); } /* Function: parseRXData ************************************************************** Description: The parse recieved data into Recieves: chn: The channel we want to put into the channel Returns: N/A */ void parseRXData(){ int pCount = 0; //count data collected int i = 0; int chnl; string data = ""; if(DEBUG) pc.printf("buff1 = <%s> \r\n", rxBuf); while(pCount < 3){ if(rxBuf[i] != '.'){ data += rxBuf[i]; } else{ pCount++; if(pCount == 1){ //get channel if((atoi(data.c_str()) < 0) || (atoi(data.c_str()) > 15)){ //check if channel is out of array index if(DEBUG) pc.printf("ERROR: INDEX OUT OF RANGE! \r\n", rxBuf); } else{ chnl = atoi(data.c_str()); chnl = chnl-1; //fix for array indexing chnlSel = chnl; //chnl selected by user in GUI } } else if(pCount == 2){ //get channel temperature chnlStatus[chnl].setTemp = atoi(data.c_str()); if(DEBUG) pc.printf("CHANNEL TEMP: %f \r\n", chnlStatus[chnl].setTemp); } else if(pCount == 3){ //get channel status chnlStatus[chnl].status = atoi(data.c_str()); if(DEBUG) pc.printf("CHANNEL STATUS: %f \r\n", chnlStatus[chnl].status); } data = ""; } i++; } } /* Function: get_temp ************************************************************** Description: Retrieve data from thermistor Recieves: chn: the channel of the fixture to read temp. from Returns: the temperature of the fixture (front or back) */ float get_temp(int chn){ myled = 1; ltc2487.setAddress(addrLUT[chn].adc); float ADC_val = ltc2487.readOutput(chn); //(65536*1.334)/2.5; int i = 0; while((i < sizeLUT) && (thermLUT[i].adc > ADC_val)){ i++; } //find the temp. above therm temp //Point slope formula extrapolation: // y1 = m (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) float b = float(thermLUT[i-1].adc - thermLUT[i].adc); //slope of adc between points where therm adc is between (Amax - Amin) float m = a/b; float y = (m*(ADC_val-thermLUT[i].adc))+thermLUT[i].temp; if(DEBUG) pc.printf("ADC VAL: %f TEMP: %f \r\n", ADC_val, y); //if(chn == chnlSel) pc.printf("%f \r\n", y); return y; } /* Function: get_heater_current ************************************************************** Description: Retrieve current into heater control MOSFET Recieves: chn: the channel of the fixture to read current from Returns: the current into the heater control MOSFET */ float get_heater_current(int chn){ return 0.0; } /* Function: get_valve_current ************************************************************** Description: Retrieve current into valve control MOSFET Recieves: chn: the channel of the fixture to read current from Returns: the current into the valve control MOSFET */ float get_valve_current(int chn){ return 0.0; } /* Function: turn_valve_on ************************************************************** Description: Turn valve on and green status LED on Recieves: 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 Recieves: 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 ************************************************************** Description: Turn heater on and green status LED on Recieves: 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 Recieves: 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) Recieves: 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){ io_control.setAddress(addrLUT[chn].io); if(status){ io_control.writeOutput(0,0,1,0); } else{ io_control.writeOutput(0,0,0,1); } } /* Function: test_mcp23008 ************************************************************** Description: Test each output of the MCP23009 Recieves: N/A Returns: N/A */ void test_mcp23008(int chn){ turn_valve_on(chn); wait(1); turn_valve_off(chn); wait(1); turn_heater_on(chn); wait(1); turn_heater_off(chn); wait(1); status_led(chn, 0); wait(1); status_led(chn, 1); } /* Function: test_ltc2487 ************************************************************** Description: Test the reading from LTC2487 Recieves: N/A Returns: N/A */ void test_ltc2487(int chn){ get_temp(chn); //if(DEBUG1) pc.printf("TEMPERATURE READING: %f \r\n", get_temp(chn)); } int main() { pc.baud(9600); pc.autoDetectChar('E'); pc.attach(&rxInterrupt, MODSERIAL::RxAutoDetect); myled = 1; /* //test_mcp23008(1); while(1){ test_ltc2487(1); }*/ while(1) { if(DEBUG) pc.printf("THE PROGRAM STARTED \r\n"); //check if we recieved data/need to update TCTF data if(dataRecieved){ dataRecieved = false; pc.autoDetectChar('\n'); pc.move(rxBuf, 50); pc.rxBufferFlush(); parseRXData(); } for(int chnl = 0; chnl <= CHN_COUNT; chnl++){ float currentTemp = get_temp(chnl); //CONTROL LOOP: if(chnlStatus[chnl].status == 1){ if(currentTemp > ((chnlStatus[chnl].setTemp)+HYST)){ //Turn chiller on turn_valve_on(chnl); //Turn heater off turn_heater_off(chnl); } else if (currentTemp < ((chnlStatus[chnl].setTemp)-HYST)){ //Turn chiller off turn_valve_off(chnl); //Turn heater on turn_heater_on(chnl); } 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); } } } } }