![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Control Code with I/O and ADC working
main.cpp@21:f87464a7e7c6, 2018-07-18 (annotated)
- Committer:
- jrodenburg
- Date:
- Wed Jul 18 21:28:45 2018 +0000
- Revision:
- 21:f87464a7e7c6
- Parent:
- 20:cdeed4dad690
Code with diagnostics
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jrodenburg | 4:168a446bd0da | 1 | // MBED SCRIPT FOR CONTROLLING THE TEMPERATURE CONTROLLED TEST FIXTURE (TCTF) |
jrodenburg | 0:a28a1035c31b | 2 | // DATE: SEPTEMBER 2017 |
jrodenburg | 21:f87464a7e7c6 | 3 | //CHANGE THE PYTHON CODE TO REFLECT ERROR STATE ENTERED |
jrodenburg | 0:a28a1035c31b | 4 | |
jrodenburg | 0:a28a1035c31b | 5 | #include "mbed.h" |
jrodenburg | 0:a28a1035c31b | 6 | #include "MODSERIAL.h" |
jrodenburg | 8:dbf8bd4815f8 | 7 | #include "MCP23008.h" |
jrodenburg | 0:a28a1035c31b | 8 | #include "LTC2487.h" |
jrodenburg | 2:bd118a724f03 | 9 | #include <string> |
jrodenburg | 0:a28a1035c31b | 10 | |
jrodenburg | 20:cdeed4dad690 | 11 | |
jrodenburg | 0:a28a1035c31b | 12 | //DEFINITIVE VARIABLES |
jrodenburg | 20:cdeed4dad690 | 13 | #define DEBUG_LOOP_TIME 0x00000001 |
jrodenburg | 20:cdeed4dad690 | 14 | #define RXDATA_PRINT 0x00000002 |
jrodenburg | 20:cdeed4dad690 | 15 | #define UID_PRINT 0x00000004 |
jrodenburg | 20:cdeed4dad690 | 16 | #define ERROR_PRINT 0x00000008 |
jrodenburg | 20:cdeed4dad690 | 17 | #define ADC_VAL_PRINT 0x00000010 |
jrodenburg | 20:cdeed4dad690 | 18 | #define HEATER_CHILLER_PRINT 0x00000020 |
jrodenburg | 20:cdeed4dad690 | 19 | #define HEATER_ON_TIME_PRINT 0x00000040 |
jrodenburg | 20:cdeed4dad690 | 20 | #define LED_PRINT 0x00000080 |
jrodenburg | 20:cdeed4dad690 | 21 | #define TEMP_PRINT 0x00000100 |
jrodenburg | 20:cdeed4dad690 | 22 | #define I2C_PRINT 0x00000200 |
jrodenburg | 20:cdeed4dad690 | 23 | |
jrodenburg | 20:cdeed4dad690 | 24 | #define IO_I2C_LINE 1 |
jrodenburg | 20:cdeed4dad690 | 25 | #define ADC_I2C_LINE 2 |
jrodenburg | 20:cdeed4dad690 | 26 | |
jrodenburg | 20:cdeed4dad690 | 27 | #define CHAN_COUNT 8 |
jrodenburg | 21:f87464a7e7c6 | 28 | #define ERROR_COUNT 6 |
jrodenburg | 16:82d941b1ef21 | 29 | #define MIN_TEMP 10 |
jrodenburg | 16:82d941b1ef21 | 30 | #define MAX_TEMP 65 |
jrodenburg | 20:cdeed4dad690 | 31 | #define TEMP_MARGIN 10 |
jrodenburg | 16:82d941b1ef21 | 32 | #define HYST_LOW 0.3 |
jrodenburg | 16:82d941b1ef21 | 33 | #define HYST_HIGH 1 |
jrodenburg | 21:f87464a7e7c6 | 34 | #define VALVE_ON 1 |
jrodenburg | 21:f87464a7e7c6 | 35 | #define HEATER_ON 2 |
jrodenburg | 20:cdeed4dad690 | 36 | #define GREEN_STATUS_ON 3 |
jrodenburg | 21:f87464a7e7c6 | 37 | #define RED_STATUS_ON 4 |
jrodenburg | 21:f87464a7e7c6 | 38 | #define ERROR_STATUS_ON 5 |
jrodenburg | 21:f87464a7e7c6 | 39 | #define ALL_OFF 6 |
jrodenburg | 16:82d941b1ef21 | 40 | #define sizeLUT 34 |
jrodenburg | 16:82d941b1ef21 | 41 | #define BACK_THERM 0 |
jrodenburg | 16:82d941b1ef21 | 42 | #define FRONT_THERM 1 |
jrodenburg | 16:82d941b1ef21 | 43 | #define HEAT_FET_AMP 2 |
jrodenburg | 16:82d941b1ef21 | 44 | #define VALVE_FET_AMP 3 |
jrodenburg | 20:cdeed4dad690 | 45 | #define NUM_EMAIL_SEND 2 |
jrodenburg | 20:cdeed4dad690 | 46 | #define STATUS_COOLING 1 |
jrodenburg | 20:cdeed4dad690 | 47 | #define STATUS_HEATING 2 |
jrodenburg | 20:cdeed4dad690 | 48 | #define STATUS_INACTIVE 3 |
jrodenburg | 20:cdeed4dad690 | 49 | #define STATUS_STANDBY 4 |
jrodenburg | 21:f87464a7e7c6 | 50 | #define MIN_AD_COUNT 10428 //65C |
jrodenburg | 21:f87464a7e7c6 | 51 | #define MAX_AD_COUNT 49169 //10C |
jrodenburg | 21:f87464a7e7c6 | 52 | #define MAX_TIME_TO_SP 60 //allow 60 minutes for channel to reach set point |
jrodenburg | 20:cdeed4dad690 | 53 | |
jrodenburg | 20:cdeed4dad690 | 54 | #define READ_TEMP_TASK_TIME .300f //300ms to read one A/D value |
jrodenburg | 20:cdeed4dad690 | 55 | #define I2C_READ_WAIT_TIME 0.08f |
jrodenburg | 12:1cada1fe4743 | 56 | |
jrodenburg | 8:dbf8bd4815f8 | 57 | // Defines for use with Serial communication |
jrodenburg | 8:dbf8bd4815f8 | 58 | #pragma pack (1) |
jrodenburg | 8:dbf8bd4815f8 | 59 | #define RX_SOF 0x7B |
jrodenburg | 8:dbf8bd4815f8 | 60 | #define RX_EOF 0x7D |
jrodenburg | 8:dbf8bd4815f8 | 61 | #define TX_SOF 0x7B |
jrodenburg | 8:dbf8bd4815f8 | 62 | #define TX_EOF 0x7D |
jrodenburg | 8:dbf8bd4815f8 | 63 | #define DELIMETER 0x2E |
jrodenburg | 8:dbf8bd4815f8 | 64 | #define SET_TEMPERATURE 0xB0 |
jrodenburg | 8:dbf8bd4815f8 | 65 | #define SELECT_CHANNEL 0xB1 |
jrodenburg | 15:74a01aaeb60e | 66 | #define READ_UID 0xB2 |
jrodenburg | 20:cdeed4dad690 | 67 | #define READ_FW_VERSION 0xB3 |
jrodenburg | 20:cdeed4dad690 | 68 | #define DEBUG_CONTROL 0xB4 |
jrodenburg | 15:74a01aaeb60e | 69 | #define RESPONSE_DATA 0xD0 |
jrodenburg | 15:74a01aaeb60e | 70 | #define TEMP_DATA 0xD1 |
jrodenburg | 15:74a01aaeb60e | 71 | #define UID_DATA 0xD2 |
jrodenburg | 20:cdeed4dad690 | 72 | #define FW_VERSION_DATA 0xD3 |
jrodenburg | 15:74a01aaeb60e | 73 | #define ERROR_DATA 0xDF |
jrodenburg | 12:1cada1fe4743 | 74 | |
jrodenburg | 21:f87464a7e7c6 | 75 | // Defines for errors |
jrodenburg | 21:f87464a7e7c6 | 76 | #define ERR_OVER_TEMP 0 |
jrodenburg | 21:f87464a7e7c6 | 77 | #define ERR_UNDER_TEMP 1 |
jrodenburg | 21:f87464a7e7c6 | 78 | #define ERR_TEMP_DIFF 2 |
jrodenburg | 21:f87464a7e7c6 | 79 | #define ERR_ACK_LTC 3 |
jrodenburg | 21:f87464a7e7c6 | 80 | #define ERR_ACK_MCP 4 |
jrodenburg | 21:f87464a7e7c6 | 81 | #define ERR_SP_TIME 5 |
jrodenburg | 21:f87464a7e7c6 | 82 | #define MAX_ERROR_CNT 8 |
jrodenburg | 0:a28a1035c31b | 83 | |
jrodenburg | 21:f87464a7e7c6 | 84 | #define PRINT_ERROR_CHECK_VALS 0 |
jrodenburg | 21:f87464a7e7c6 | 85 | #define PRINT_ERRORS 0 |
jrodenburg | 21:f87464a7e7c6 | 86 | |
jrodenburg | 21:f87464a7e7c6 | 87 | |
jrodenburg | 21:f87464a7e7c6 | 88 | |
jrodenburg | 21:f87464a7e7c6 | 89 | |
jrodenburg | 21:f87464a7e7c6 | 90 | const char FW_Version[8] = "V0.01D"; |
jrodenburg | 8:dbf8bd4815f8 | 91 | unsigned int chanSel_SendTemp = 0; |
jrodenburg | 8:dbf8bd4815f8 | 92 | unsigned int chanSel_SetTemp = 0; |
jrodenburg | 8:dbf8bd4815f8 | 93 | // Default to chan 0 |
jrodenburg | 8:dbf8bd4815f8 | 94 | int currChan = 0; |
jrodenburg | 8:dbf8bd4815f8 | 95 | bool newTempSet = false; |
jrodenburg | 20:cdeed4dad690 | 96 | bool readFrontThermistor = true; |
jrodenburg | 20:cdeed4dad690 | 97 | bool newTempData = false; |
jrodenburg | 20:cdeed4dad690 | 98 | bool newTempDataAvailable = false; |
jrodenburg | 20:cdeed4dad690 | 99 | unsigned int UID_print_count = 0; |
jrodenburg | 21:f87464a7e7c6 | 100 | unsigned int debug_control = 0x80; |
jrodenburg | 8:dbf8bd4815f8 | 101 | |
jrodenburg | 20:cdeed4dad690 | 102 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 103 | // Timers |
jrodenburg | 20:cdeed4dad690 | 104 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 105 | Ticker frontTempDoneTicker; |
jrodenburg | 20:cdeed4dad690 | 106 | Ticker backTempDoneTicker; |
jrodenburg | 20:cdeed4dad690 | 107 | Ticker readThermistorTicker; |
jrodenburg | 20:cdeed4dad690 | 108 | Ticker frontTempInProgTicker; |
jrodenburg | 20:cdeed4dad690 | 109 | Ticker backTempInProgTicker; |
jrodenburg | 21:f87464a7e7c6 | 110 | Ticker setPointTimeTicker; |
jrodenburg | 20:cdeed4dad690 | 111 | |
jrodenburg | 20:cdeed4dad690 | 112 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 113 | // LEDs |
jrodenburg | 20:cdeed4dad690 | 114 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 115 | DigitalOut rLed(LED1); |
jrodenburg | 20:cdeed4dad690 | 116 | DigitalOut gLed(LED2); |
jrodenburg | 20:cdeed4dad690 | 117 | |
jrodenburg | 20:cdeed4dad690 | 118 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 119 | // Functions Declarations |
jrodenburg | 20:cdeed4dad690 | 120 | //*********************************************** |
jrodenburg | 20:cdeed4dad690 | 121 | void sendUID (); |
jrodenburg | 20:cdeed4dad690 | 122 | void sendFWVersion(); |
jrodenburg | 20:cdeed4dad690 | 123 | void read_front_temp(); |
jrodenburg | 20:cdeed4dad690 | 124 | void read_back_temp(); |
jrodenburg | 20:cdeed4dad690 | 125 | void update_front_temp_data(); |
jrodenburg | 20:cdeed4dad690 | 126 | void update_back_temp_data(); |
jrodenburg | 20:cdeed4dad690 | 127 | void temperatureDataReady(); |
jrodenburg | 12:1cada1fe4743 | 128 | |
jrodenburg | 8:dbf8bd4815f8 | 129 | //*********************************************** |
jrodenburg | 8:dbf8bd4815f8 | 130 | // Serial Rx Packet Format |
jrodenburg | 8:dbf8bd4815f8 | 131 | //*********************************************** |
jrodenburg | 8:dbf8bd4815f8 | 132 | typedef struct { |
jrodenburg | 8:dbf8bd4815f8 | 133 | unsigned char SOF_flag; |
jrodenburg | 8:dbf8bd4815f8 | 134 | unsigned char cmd_type; |
jrodenburg | 8:dbf8bd4815f8 | 135 | unsigned char len; |
jrodenburg | 8:dbf8bd4815f8 | 136 | unsigned char Delim; |
jrodenburg | 8:dbf8bd4815f8 | 137 | } HOST_CMD_HEADER; |
jrodenburg | 8:dbf8bd4815f8 | 138 | |
jrodenburg | 8:dbf8bd4815f8 | 139 | typedef struct { |
jrodenburg | 8:dbf8bd4815f8 | 140 | HOST_CMD_HEADER cmd_header; |
jrodenburg | 8:dbf8bd4815f8 | 141 | unsigned char chanID; |
jrodenburg | 8:dbf8bd4815f8 | 142 | unsigned char tempDelim; |
jrodenburg | 8:dbf8bd4815f8 | 143 | float setTemp; |
jrodenburg | 8:dbf8bd4815f8 | 144 | unsigned char chanStatDelim; |
jrodenburg | 8:dbf8bd4815f8 | 145 | unsigned char chanStat; |
jrodenburg | 8:dbf8bd4815f8 | 146 | } SET_TEMPERATURE_CMD; |
jrodenburg | 8:dbf8bd4815f8 | 147 | |
jrodenburg | 8:dbf8bd4815f8 | 148 | typedef struct { |
jrodenburg | 8:dbf8bd4815f8 | 149 | HOST_CMD_HEADER cmd_header; |
jrodenburg | 8:dbf8bd4815f8 | 150 | unsigned char chanIDSel; |
jrodenburg | 8:dbf8bd4815f8 | 151 | unsigned char chanDelim; |
jrodenburg | 8:dbf8bd4815f8 | 152 | unsigned char chanStat; |
jrodenburg | 8:dbf8bd4815f8 | 153 | } SELECT_CHANNEL_CMD; |
jrodenburg | 8:dbf8bd4815f8 | 154 | |
jrodenburg | 8:dbf8bd4815f8 | 155 | typedef struct { |
jrodenburg | 8:dbf8bd4815f8 | 156 | unsigned char SOF_flag; |
jrodenburg | 8:dbf8bd4815f8 | 157 | unsigned char cmd_type; |
jrodenburg | 8:dbf8bd4815f8 | 158 | unsigned char len; |
jrodenburg | 8:dbf8bd4815f8 | 159 | unsigned char Delim; |
jrodenburg | 20:cdeed4dad690 | 160 | uint32_t channel; |
jrodenburg | 8:dbf8bd4815f8 | 161 | float data; |
jrodenburg | 8:dbf8bd4815f8 | 162 | unsigned char EOF_flag; |
jrodenburg | 8:dbf8bd4815f8 | 163 | } RESPONSE_CMD; |
jrodenburg | 2:bd118a724f03 | 164 | |
jrodenburg | 15:74a01aaeb60e | 165 | typedef struct { |
jrodenburg | 16:82d941b1ef21 | 166 | unsigned char SOF_flag; |
jrodenburg | 16:82d941b1ef21 | 167 | unsigned char cmd_type; |
jrodenburg | 16:82d941b1ef21 | 168 | unsigned char len; |
jrodenburg | 16:82d941b1ef21 | 169 | unsigned char Delim; |
jrodenburg | 20:cdeed4dad690 | 170 | float chTemp[CHAN_COUNT]; |
jrodenburg | 16:82d941b1ef21 | 171 | unsigned char EOF_flag; |
jrodenburg | 16:82d941b1ef21 | 172 | } RESPONSE_TEMP_CMD; |
jrodenburg | 16:82d941b1ef21 | 173 | |
jrodenburg | 16:82d941b1ef21 | 174 | typedef struct { |
jrodenburg | 15:74a01aaeb60e | 175 | HOST_CMD_HEADER cmd_header; |
jrodenburg | 15:74a01aaeb60e | 176 | unsigned char chanIDSel; |
jrodenburg | 15:74a01aaeb60e | 177 | unsigned char chanDelim; |
jrodenburg | 15:74a01aaeb60e | 178 | unsigned char chanStat; |
jrodenburg | 15:74a01aaeb60e | 179 | } READ_UID_CMD; |
jrodenburg | 15:74a01aaeb60e | 180 | |
jrodenburg | 15:74a01aaeb60e | 181 | typedef struct { |
jrodenburg | 20:cdeed4dad690 | 182 | HOST_CMD_HEADER cmd_header; |
jrodenburg | 20:cdeed4dad690 | 183 | unsigned char chanIDSel; |
jrodenburg | 20:cdeed4dad690 | 184 | unsigned char chanDelim; |
jrodenburg | 20:cdeed4dad690 | 185 | uint32_t commandData; |
jrodenburg | 20:cdeed4dad690 | 186 | } GUI_STANDARD_CMD; |
jrodenburg | 20:cdeed4dad690 | 187 | |
jrodenburg | 20:cdeed4dad690 | 188 | typedef struct { |
jrodenburg | 20:cdeed4dad690 | 189 | unsigned char SOF_flag; |
jrodenburg | 20:cdeed4dad690 | 190 | unsigned char cmd_type; |
jrodenburg | 20:cdeed4dad690 | 191 | unsigned char len; |
jrodenburg | 20:cdeed4dad690 | 192 | unsigned char Delim; |
jrodenburg | 20:cdeed4dad690 | 193 | unsigned char FW_Version[8]; |
jrodenburg | 20:cdeed4dad690 | 194 | unsigned char EOF_flag; |
jrodenburg | 20:cdeed4dad690 | 195 | } FW_VERSION_RESPONSE; |
jrodenburg | 20:cdeed4dad690 | 196 | |
jrodenburg | 20:cdeed4dad690 | 197 | typedef struct { |
jrodenburg | 15:74a01aaeb60e | 198 | unsigned char SOF_flag; |
jrodenburg | 15:74a01aaeb60e | 199 | unsigned char cmd_type; |
jrodenburg | 15:74a01aaeb60e | 200 | unsigned char len; |
jrodenburg | 15:74a01aaeb60e | 201 | unsigned char Delim; |
jrodenburg | 15:74a01aaeb60e | 202 | uint32_t UIDMH; |
jrodenburg | 15:74a01aaeb60e | 203 | uint32_t UIDML; |
jrodenburg | 15:74a01aaeb60e | 204 | uint32_t UIDL; |
jrodenburg | 15:74a01aaeb60e | 205 | unsigned char EOF_flag; |
jrodenburg | 15:74a01aaeb60e | 206 | } UID_RESPONSE; |
jrodenburg | 15:74a01aaeb60e | 207 | |
jrodenburg | 2:bd118a724f03 | 208 | //TCTF CHANNEL DATA |
jrodenburg | 2:bd118a724f03 | 209 | struct CHNL_DATA{ |
jrodenburg | 2:bd118a724f03 | 210 | bool status; |
jrodenburg | 2:bd118a724f03 | 211 | float setTemp; |
jrodenburg | 21:f87464a7e7c6 | 212 | bool error; |
jrodenburg | 20:cdeed4dad690 | 213 | int state; |
jrodenburg | 21:f87464a7e7c6 | 214 | int LTCi2cAckRxed; |
jrodenburg | 21:f87464a7e7c6 | 215 | int MCPi2cAckRxed; |
jrodenburg | 21:f87464a7e7c6 | 216 | bool SPReached; |
jrodenburg | 21:f87464a7e7c6 | 217 | int SPTime; |
jrodenburg | 2:bd118a724f03 | 218 | }; |
jrodenburg | 2:bd118a724f03 | 219 | |
jrodenburg | 4:168a446bd0da | 220 | CHNL_DATA chnlStatus[] = { |
jrodenburg | 21:f87464a7e7c6 | 221 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 222 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 223 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 224 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 225 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 226 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 227 | {0, NULL, false, 0, 0, 0, false, 0}, |
jrodenburg | 21:f87464a7e7c6 | 228 | {0, NULL, false, 0, 0, 0, false, 0} |
jrodenburg | 2:bd118a724f03 | 229 | }; |
jrodenburg | 2:bd118a724f03 | 230 | |
jrodenburg | 2:bd118a724f03 | 231 | |
jrodenburg | 0:a28a1035c31b | 232 | //I2C AADRESS LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) |
jrodenburg | 2:bd118a724f03 | 233 | struct I2C_ADDR_LUT{ |
jrodenburg | 0:a28a1035c31b | 234 | int adc; |
jrodenburg | 0:a28a1035c31b | 235 | int io; |
jrodenburg | 0:a28a1035c31b | 236 | }; |
jrodenburg | 0:a28a1035c31b | 237 | |
jrodenburg | 0:a28a1035c31b | 238 | I2C_ADDR_LUT addrLUT[] = { |
jrodenburg | 0:a28a1035c31b | 239 | {0x23, 0x10}, |
jrodenburg | 0:a28a1035c31b | 240 | {0x53, 0x60}, |
jrodenburg | 0:a28a1035c31b | 241 | {0x43, 0x70}, |
jrodenburg | 0:a28a1035c31b | 242 | {0x73, 0x40}, |
jrodenburg | 0:a28a1035c31b | 243 | {0x63, 0x50}, |
jrodenburg | 0:a28a1035c31b | 244 | {0x22, 0x11}, |
jrodenburg | 0:a28a1035c31b | 245 | {0x52, 0x61}, |
jrodenburg | 20:cdeed4dad690 | 246 | {0x42, 0x71} |
jrodenburg | 0:a28a1035c31b | 247 | }; |
jrodenburg | 0:a28a1035c31b | 248 | |
jrodenburg | 0:a28a1035c31b | 249 | //THERMISTOR LOOK UP TABLE, CREATED IN EXCEL SHEET (COUNT, TEMP) |
jrodenburg | 2:bd118a724f03 | 250 | struct THERM_LUT{ |
jrodenburg | 0:a28a1035c31b | 251 | int adc; |
jrodenburg | 0:a28a1035c31b | 252 | int temp; |
jrodenburg | 0:a28a1035c31b | 253 | }; |
jrodenburg | 0:a28a1035c31b | 254 | |
jrodenburg | 0:a28a1035c31b | 255 | THERM_LUT thermLUT[] = { |
jrodenburg | 0:a28a1035c31b | 256 | {113779,-40}, |
jrodenburg | 0:a28a1035c31b | 257 | {109152,-35}, |
jrodenburg | 0:a28a1035c31b | 258 | {103830,-30}, |
jrodenburg | 0:a28a1035c31b | 259 | {97855,-25}, |
jrodenburg | 0:a28a1035c31b | 260 | {91319,-20}, |
jrodenburg | 0:a28a1035c31b | 261 | {84352,-15}, |
jrodenburg | 0:a28a1035c31b | 262 | {77124,-10}, |
jrodenburg | 0:a28a1035c31b | 263 | {69820,-5}, |
jrodenburg | 0:a28a1035c31b | 264 | {62621,0}, |
jrodenburg | 0:a28a1035c31b | 265 | {55693,5}, |
jrodenburg | 0:a28a1035c31b | 266 | {49169,10}, |
jrodenburg | 0:a28a1035c31b | 267 | {43144,15}, |
jrodenburg | 0:a28a1035c31b | 268 | {37669,20}, |
jrodenburg | 0:a28a1035c31b | 269 | {32768,25}, |
jrodenburg | 0:a28a1035c31b | 270 | {28429,30}, |
jrodenburg | 0:a28a1035c31b | 271 | {24622,35}, |
jrodenburg | 0:a28a1035c31b | 272 | {21309,40}, |
jrodenburg | 0:a28a1035c31b | 273 | {18439,45}, |
jrodenburg | 0:a28a1035c31b | 274 | {15962,50}, |
jrodenburg | 0:a28a1035c31b | 275 | {13831,55}, |
jrodenburg | 0:a28a1035c31b | 276 | {12002,60}, |
jrodenburg | 0:a28a1035c31b | 277 | {10428,65}, |
jrodenburg | 0:a28a1035c31b | 278 | {9080,70}, |
jrodenburg | 0:a28a1035c31b | 279 | {7919,75}, |
jrodenburg | 0:a28a1035c31b | 280 | {6923,80}, |
jrodenburg | 0:a28a1035c31b | 281 | {6063,85}, |
jrodenburg | 0:a28a1035c31b | 282 | {5323,90}, |
jrodenburg | 0:a28a1035c31b | 283 | {4685,95}, |
jrodenburg | 0:a28a1035c31b | 284 | {4130,100}, |
jrodenburg | 0:a28a1035c31b | 285 | {3653,105}, |
jrodenburg | 0:a28a1035c31b | 286 | {3234,110}, |
jrodenburg | 0:a28a1035c31b | 287 | {2876,115}, |
jrodenburg | 0:a28a1035c31b | 288 | {2563,120}, |
jrodenburg | 0:a28a1035c31b | 289 | {2284,125} |
jrodenburg | 0:a28a1035c31b | 290 | }; |
jrodenburg | 0:a28a1035c31b | 291 | |
jrodenburg | 20:cdeed4dad690 | 292 | |
jrodenburg | 20:cdeed4dad690 | 293 | |
jrodenburg | 16:82d941b1ef21 | 294 | //TCTF CHANNEL TEMPERATURE |
jrodenburg | 16:82d941b1ef21 | 295 | typedef struct{ |
jrodenburg | 21:f87464a7e7c6 | 296 | float currADCFront; |
jrodenburg | 21:f87464a7e7c6 | 297 | float currADCBack; |
jrodenburg | 16:82d941b1ef21 | 298 | float currTempFront; |
jrodenburg | 16:82d941b1ef21 | 299 | float currTempBack; |
jrodenburg | 16:82d941b1ef21 | 300 | }CHNL_TEMP; |
jrodenburg | 16:82d941b1ef21 | 301 | |
jrodenburg | 20:cdeed4dad690 | 302 | CHNL_TEMP channelTempData[CHAN_COUNT]; |
jrodenburg | 16:82d941b1ef21 | 303 | |
jrodenburg | 2:bd118a724f03 | 304 | //SERIAL COMMUNICATION SETUP |
jrodenburg | 2:bd118a724f03 | 305 | MODSERIAL pc(USBTX, USBRX); |
jrodenburg | 1:0182b86f9bd4 | 306 | |
jrodenburg | 0:a28a1035c31b | 307 | //DEFINE PINS |
jrodenburg | 0:a28a1035c31b | 308 | DigitalOut myled(LED2); |
jrodenburg | 0:a28a1035c31b | 309 | |
jrodenburg | 0:a28a1035c31b | 310 | //I2C FOR MCP23008 (I/O Control) |
jrodenburg | 12:1cada1fe4743 | 311 | MCP23008 io_control(PTC9, PTC8, 0x10, 100000); //sda, scl |
jrodenburg | 0:a28a1035c31b | 312 | |
jrodenburg | 0:a28a1035c31b | 313 | //I2C FOR LTC2487 (ADC Control) |
jrodenburg | 12:1cada1fe4743 | 314 | LTC2487 ltc2487(PTC11, PTC10, 0x23, 100000); //sda, scl |
jrodenburg | 0:a28a1035c31b | 315 | |
jrodenburg | 0:a28a1035c31b | 316 | //GLOBAL VARIABLES |
jrodenburg | 12:1cada1fe4743 | 317 | volatile bool dataReceived = false; //used to check if data has been received |
jrodenburg | 8:dbf8bd4815f8 | 318 | volatile bool dataTxReady = false; |
jrodenburg | 2:bd118a724f03 | 319 | char rxBuf[50]; |
jrodenburg | 2:bd118a724f03 | 320 | int chnlSel; |
jrodenburg | 20:cdeed4dad690 | 321 | bool standbyLED[CHAN_COUNT] = {false,false,false,false,false,false,false,false}; |
jrodenburg | 7:8a5e65e63e2a | 322 | |
jrodenburg | 21:f87464a7e7c6 | 323 | int errorCount[CHAN_COUNT][ERROR_COUNT] = |
jrodenburg | 21:f87464a7e7c6 | 324 | { |
jrodenburg | 21:f87464a7e7c6 | 325 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 326 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 327 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 328 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 329 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 330 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 331 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 332 | {0,0,0,0,0,0} |
jrodenburg | 21:f87464a7e7c6 | 333 | }; |
jrodenburg | 21:f87464a7e7c6 | 334 | |
jrodenburg | 21:f87464a7e7c6 | 335 | int errorEmailSent[CHAN_COUNT][ERROR_COUNT] = |
jrodenburg | 21:f87464a7e7c6 | 336 | { |
jrodenburg | 21:f87464a7e7c6 | 337 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 338 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 339 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 340 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 341 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 342 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 343 | {0,0,0,0,0,0}, |
jrodenburg | 21:f87464a7e7c6 | 344 | {0,0,0,0,0,0} |
jrodenburg | 21:f87464a7e7c6 | 345 | }; |
jrodenburg | 21:f87464a7e7c6 | 346 | |
jrodenburg | 21:f87464a7e7c6 | 347 | void resetErrorCount(){ |
jrodenburg | 21:f87464a7e7c6 | 348 | for(int i = 0; i < CHAN_COUNT; i++){ |
jrodenburg | 21:f87464a7e7c6 | 349 | for(int i = 0; i < ERROR_COUNT; i++){ |
jrodenburg | 21:f87464a7e7c6 | 350 | errorCount[CHAN_COUNT][ERROR_COUNT] = 0; |
jrodenburg | 21:f87464a7e7c6 | 351 | errorEmailSent[CHAN_COUNT][ERROR_COUNT] = 0; |
jrodenburg | 21:f87464a7e7c6 | 352 | } |
jrodenburg | 21:f87464a7e7c6 | 353 | } |
jrodenburg | 21:f87464a7e7c6 | 354 | } |
jrodenburg | 21:f87464a7e7c6 | 355 | |
jrodenburg | 7:8a5e65e63e2a | 356 | /* Function: turnOffChannel |
jrodenburg | 7:8a5e65e63e2a | 357 | ************************************************************** |
jrodenburg | 7:8a5e65e63e2a | 358 | Description: Turns off a channel |
jrodenburg | 7:8a5e65e63e2a | 359 | Recieves: chnl: channel to turn off |
jrodenburg | 7:8a5e65e63e2a | 360 | Returns: N/A |
jrodenburg | 7:8a5e65e63e2a | 361 | */ |
jrodenburg | 7:8a5e65e63e2a | 362 | |
jrodenburg | 7:8a5e65e63e2a | 363 | void turnOffChannel(int chnl){ |
jrodenburg | 7:8a5e65e63e2a | 364 | io_control.setAddress(addrLUT[chnl].io); |
jrodenburg | 7:8a5e65e63e2a | 365 | io_control.init(); |
jrodenburg | 7:8a5e65e63e2a | 366 | io_control.writeOutput(0,0,0,0); |
jrodenburg | 7:8a5e65e63e2a | 367 | } |
jrodenburg | 7:8a5e65e63e2a | 368 | |
jrodenburg | 8:dbf8bd4815f8 | 369 | |
jrodenburg | 2:bd118a724f03 | 370 | /* Function: rxInterrupt |
jrodenburg | 1:0182b86f9bd4 | 371 | ************************************************************** |
jrodenburg | 8:dbf8bd4815f8 | 372 | Description: serial rx interupt handler |
jrodenburg | 8:dbf8bd4815f8 | 373 | Receives: N/A |
jrodenburg | 8:dbf8bd4815f8 | 374 | Returns: N/A |
jrodenburg | 2:bd118a724f03 | 375 | */ |
jrodenburg | 2:bd118a724f03 | 376 | |
jrodenburg | 8:dbf8bd4815f8 | 377 | //*********************************************** |
jrodenburg | 8:dbf8bd4815f8 | 378 | // Rx Interrupt from serial Host interface |
jrodenburg | 8:dbf8bd4815f8 | 379 | //*********************************************** |
jrodenburg | 8:dbf8bd4815f8 | 380 | void rxInterrupt(MODSERIAL_IRQ_INFO *info) |
jrodenburg | 8:dbf8bd4815f8 | 381 | { |
jrodenburg | 8:dbf8bd4815f8 | 382 | gLed = 0; |
jrodenburg | 8:dbf8bd4815f8 | 383 | dataReceived = true; |
jrodenburg | 20:cdeed4dad690 | 384 | //wait(.5); |
jrodenburg | 8:dbf8bd4815f8 | 385 | gLed = 1; |
jrodenburg | 2:bd118a724f03 | 386 | } |
jrodenburg | 2:bd118a724f03 | 387 | |
jrodenburg | 8:dbf8bd4815f8 | 388 | |
jrodenburg | 8:dbf8bd4815f8 | 389 | //*************************************************************** |
jrodenburg | 8:dbf8bd4815f8 | 390 | // Tx Interrupt from serial Host interface |
jrodenburg | 8:dbf8bd4815f8 | 391 | //*************************************************************** |
jrodenburg | 8:dbf8bd4815f8 | 392 | void txInterrupt(MODSERIAL_IRQ_INFO *info) |
jrodenburg | 8:dbf8bd4815f8 | 393 | { |
jrodenburg | 20:cdeed4dad690 | 394 | gLed = 1; |
jrodenburg | 8:dbf8bd4815f8 | 395 | dataTxReady = true; |
jrodenburg | 20:cdeed4dad690 | 396 | gLed = 1; |
jrodenburg | 8:dbf8bd4815f8 | 397 | } |
jrodenburg | 8:dbf8bd4815f8 | 398 | |
jrodenburg | 8:dbf8bd4815f8 | 399 | |
jrodenburg | 2:bd118a724f03 | 400 | /* Function: parseRXData |
jrodenburg | 2:bd118a724f03 | 401 | ************************************************************** |
jrodenburg | 12:1cada1fe4743 | 402 | Description: The parse received data into |
jrodenburg | 12:1cada1fe4743 | 403 | Receives: chn: The channel we want to put into the channel |
jrodenburg | 12:1cada1fe4743 | 404 | Returns: N/A |
jrodenburg | 1:0182b86f9bd4 | 405 | */ |
jrodenburg | 20:cdeed4dad690 | 406 | void processRxUARTData() |
jrodenburg | 8:dbf8bd4815f8 | 407 | { |
jrodenburg | 8:dbf8bd4815f8 | 408 | HOST_CMD_HEADER *pRxPktHdr; |
jrodenburg | 2:bd118a724f03 | 409 | string data = ""; |
jrodenburg | 8:dbf8bd4815f8 | 410 | |
jrodenburg | 8:dbf8bd4815f8 | 411 | pRxPktHdr = (HOST_CMD_HEADER *)rxBuf; |
jrodenburg | 8:dbf8bd4815f8 | 412 | |
jrodenburg | 20:cdeed4dad690 | 413 | if (debug_control & RXDATA_PRINT) { |
jrodenburg | 20:cdeed4dad690 | 414 | pc.printf("DBG: SOF=%02x, Len=%02x, CMD=%02x\r\n", pRxPktHdr->SOF_flag, pRxPktHdr->len, pRxPktHdr->cmd_type); |
jrodenburg | 20:cdeed4dad690 | 415 | pc.printf("DBG: "); |
jrodenburg | 20:cdeed4dad690 | 416 | for (int i=0; i <5; i++) |
jrodenburg | 20:cdeed4dad690 | 417 | pc.printf("%02x ", rxBuf[i]); |
jrodenburg | 20:cdeed4dad690 | 418 | pc.printf("\n"); |
jrodenburg | 20:cdeed4dad690 | 419 | } |
jrodenburg | 8:dbf8bd4815f8 | 420 | |
jrodenburg | 8:dbf8bd4815f8 | 421 | // Exit if the packet does not contain correct header |
jrodenburg | 8:dbf8bd4815f8 | 422 | // Maybe send NAK? |
jrodenburg | 8:dbf8bd4815f8 | 423 | if ((pRxPktHdr->SOF_flag != RX_SOF) || (pRxPktHdr->Delim != DELIMETER)) |
jrodenburg | 8:dbf8bd4815f8 | 424 | return; |
jrodenburg | 2:bd118a724f03 | 425 | |
jrodenburg | 8:dbf8bd4815f8 | 426 | switch (pRxPktHdr->cmd_type) |
jrodenburg | 8:dbf8bd4815f8 | 427 | { |
jrodenburg | 8:dbf8bd4815f8 | 428 | case SET_TEMPERATURE: |
jrodenburg | 8:dbf8bd4815f8 | 429 | // Process set temp for specified channel |
jrodenburg | 8:dbf8bd4815f8 | 430 | { |
jrodenburg | 8:dbf8bd4815f8 | 431 | SET_TEMPERATURE_CMD *pRxPkt = (SET_TEMPERATURE_CMD *)(rxBuf); |
jrodenburg | 20:cdeed4dad690 | 432 | |
jrodenburg | 20:cdeed4dad690 | 433 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 434 | pc.printf("DBG: SETTEMP: ch = %02x, tempSet = %f, chanStat = %02x\r\n", |
jrodenburg | 20:cdeed4dad690 | 435 | pRxPkt->chanID, pRxPkt->setTemp, pRxPkt->chanStat); |
jrodenburg | 20:cdeed4dad690 | 436 | |
jrodenburg | 8:dbf8bd4815f8 | 437 | if ((pRxPkt->tempDelim != DELIMETER) || (pRxPkt->chanStatDelim != DELIMETER)) { |
jrodenburg | 8:dbf8bd4815f8 | 438 | // Send NAK back |
jrodenburg | 8:dbf8bd4815f8 | 439 | pc.printf("DBG: Error\n"); |
jrodenburg | 2:bd118a724f03 | 440 | } |
jrodenburg | 8:dbf8bd4815f8 | 441 | else { |
jrodenburg | 21:f87464a7e7c6 | 442 | if((pRxPkt->setTemp < MAX_TEMP) && (pRxPkt->setTemp > MIN_TEMP)){ |
jrodenburg | 21:f87464a7e7c6 | 443 | chanSel_SetTemp = pRxPkt->chanID; |
jrodenburg | 21:f87464a7e7c6 | 444 | chnlStatus[pRxPkt->chanID].status = pRxPkt->chanStat; |
jrodenburg | 21:f87464a7e7c6 | 445 | chnlStatus[pRxPkt->chanID].state = STATUS_INACTIVE; |
jrodenburg | 21:f87464a7e7c6 | 446 | chnlStatus[pRxPkt->chanID].setTemp = pRxPkt->setTemp; |
jrodenburg | 21:f87464a7e7c6 | 447 | chnlStatus[pRxPkt->chanID].error = false; |
jrodenburg | 21:f87464a7e7c6 | 448 | chnlStatus[pRxPkt->chanID].LTCi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 449 | chnlStatus[pRxPkt->chanID].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 450 | chnlStatus[pRxPkt->chanID].SPReached = false; |
jrodenburg | 21:f87464a7e7c6 | 451 | chnlStatus[pRxPkt->chanID].SPTime = 0; |
jrodenburg | 21:f87464a7e7c6 | 452 | memset(errorCount[pRxPkt->chanID], 0, sizeof(int)*ERROR_COUNT); |
jrodenburg | 21:f87464a7e7c6 | 453 | memset(errorEmailSent[pRxPkt->chanID], 0, sizeof(int)*ERROR_COUNT); |
jrodenburg | 21:f87464a7e7c6 | 454 | newTempSet = true; |
jrodenburg | 21:f87464a7e7c6 | 455 | } |
jrodenburg | 2:bd118a724f03 | 456 | } |
jrodenburg | 2:bd118a724f03 | 457 | } |
jrodenburg | 8:dbf8bd4815f8 | 458 | break; |
jrodenburg | 8:dbf8bd4815f8 | 459 | |
jrodenburg | 8:dbf8bd4815f8 | 460 | case SELECT_CHANNEL: |
jrodenburg | 8:dbf8bd4815f8 | 461 | // Select channel to send temp data to |
jrodenburg | 8:dbf8bd4815f8 | 462 | { |
jrodenburg | 8:dbf8bd4815f8 | 463 | SELECT_CHANNEL_CMD *pRxPkt = (SELECT_CHANNEL_CMD *)(rxBuf); |
jrodenburg | 8:dbf8bd4815f8 | 464 | |
jrodenburg | 8:dbf8bd4815f8 | 465 | chanSel_SendTemp = pRxPkt->chanIDSel; |
jrodenburg | 20:cdeed4dad690 | 466 | |
jrodenburg | 20:cdeed4dad690 | 467 | // Send back FW version for each select channel |
jrodenburg | 20:cdeed4dad690 | 468 | sendFWVersion(); |
jrodenburg | 20:cdeed4dad690 | 469 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 470 | pc.printf("DBG: CHAN_SEL: chan=%02x, chanStat = %02x\r\n", pRxPkt->chanIDSel, pRxPkt->chanStat); |
jrodenburg | 20:cdeed4dad690 | 471 | |
jrodenburg | 2:bd118a724f03 | 472 | } |
jrodenburg | 8:dbf8bd4815f8 | 473 | break; |
jrodenburg | 8:dbf8bd4815f8 | 474 | |
jrodenburg | 15:74a01aaeb60e | 475 | case READ_UID: |
jrodenburg | 15:74a01aaeb60e | 476 | { |
jrodenburg | 15:74a01aaeb60e | 477 | READ_UID_CMD *pRxPkt = (READ_UID_CMD *)(rxBuf); |
jrodenburg | 20:cdeed4dad690 | 478 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 479 | pc.printf("DBG: Read UID: chan%02x\n", pRxPkt->chanIDSel); |
jrodenburg | 20:cdeed4dad690 | 480 | |
jrodenburg | 15:74a01aaeb60e | 481 | sendUID(); |
jrodenburg | 15:74a01aaeb60e | 482 | } |
jrodenburg | 15:74a01aaeb60e | 483 | break; |
jrodenburg | 15:74a01aaeb60e | 484 | |
jrodenburg | 20:cdeed4dad690 | 485 | case READ_FW_VERSION: |
jrodenburg | 20:cdeed4dad690 | 486 | { |
jrodenburg | 20:cdeed4dad690 | 487 | sendFWVersion(); |
jrodenburg | 20:cdeed4dad690 | 488 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 489 | pc.printf("DBG: Read SW Version\r\n"); |
jrodenburg | 20:cdeed4dad690 | 490 | |
jrodenburg | 20:cdeed4dad690 | 491 | } |
jrodenburg | 20:cdeed4dad690 | 492 | break; |
jrodenburg | 20:cdeed4dad690 | 493 | |
jrodenburg | 20:cdeed4dad690 | 494 | case DEBUG_CONTROL: |
jrodenburg | 20:cdeed4dad690 | 495 | { |
jrodenburg | 20:cdeed4dad690 | 496 | GUI_STANDARD_CMD *pRxPkt = (GUI_STANDARD_CMD *)rxBuf; |
jrodenburg | 20:cdeed4dad690 | 497 | debug_control = pRxPkt->commandData; |
jrodenburg | 20:cdeed4dad690 | 498 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 499 | pc.printf ("DBG: Rx'd DEBUG CMD: %04x\r\n", pRxPkt->commandData); |
jrodenburg | 20:cdeed4dad690 | 500 | } |
jrodenburg | 20:cdeed4dad690 | 501 | break; |
jrodenburg | 20:cdeed4dad690 | 502 | |
jrodenburg | 20:cdeed4dad690 | 503 | |
jrodenburg | 8:dbf8bd4815f8 | 504 | default: |
jrodenburg | 8:dbf8bd4815f8 | 505 | // Error |
jrodenburg | 8:dbf8bd4815f8 | 506 | break; |
jrodenburg | 2:bd118a724f03 | 507 | } |
jrodenburg | 1:0182b86f9bd4 | 508 | } |
jrodenburg | 0:a28a1035c31b | 509 | |
jrodenburg | 0:a28a1035c31b | 510 | /* Function: get_temp |
jrodenburg | 0:a28a1035c31b | 511 | ************************************************************** |
jrodenburg | 16:82d941b1ef21 | 512 | Description: Convert A/D count to temperature value |
jrodenburg | 16:82d941b1ef21 | 513 | Receives: ADC_val: the count from the A/D reading |
jrodenburg | 20:cdeed4dad690 | 514 | Returns: the temp. of the A/D reading |
jrodenburg | 0:a28a1035c31b | 515 | */ |
jrodenburg | 0:a28a1035c31b | 516 | |
jrodenburg | 16:82d941b1ef21 | 517 | float get_temp(float ADC_val){ |
jrodenburg | 1:0182b86f9bd4 | 518 | myled = 1; |
jrodenburg | 16:82d941b1ef21 | 519 | //ltc2487.setAddress(addrLUT[chn].adc); |
jrodenburg | 12:1cada1fe4743 | 520 | |
jrodenburg | 16:82d941b1ef21 | 521 | //float ADC_val = ltc2487.readOutput(port); //(65536*1.334)/2.5 |
jrodenburg | 12:1cada1fe4743 | 522 | |
jrodenburg | 0:a28a1035c31b | 523 | int i = 0; |
jrodenburg | 12:1cada1fe4743 | 524 | |
jrodenburg | 0:a28a1035c31b | 525 | while((i < sizeLUT) && (thermLUT[i].adc > ADC_val)){ |
jrodenburg | 12:1cada1fe4743 | 526 | i++; |
jrodenburg | 0:a28a1035c31b | 527 | } //find the temp. above therm temp |
jrodenburg | 12:1cada1fe4743 | 528 | |
jrodenburg | 12:1cada1fe4743 | 529 | //Point slope formula extrapolation: |
jrodenburg | 14:69cd53434783 | 530 | // m = (y1-y0)/(x1-x0)+ y0 , y = temp. value, x = adc value |
jrodenburg | 0:a28a1035c31b | 531 | // y1 = thermLUT[i-1].temp y0 = thermLUT[i].temp |
jrodenburg | 0:a28a1035c31b | 532 | // x1 = thermLUT[i-1].adc x0 =thermLUT[i].adc |
jrodenburg | 0:a28a1035c31b | 533 | float a = float(thermLUT[i-1].temp - thermLUT[i].temp); //slope of temp between points where therm temp is between (Tmax - Tmin) |
jrodenburg | 0:a28a1035c31b | 534 | float b = float(thermLUT[i-1].adc - thermLUT[i].adc); //slope of adc between points where therm adc is between (Amax - Amin) |
jrodenburg | 12:1cada1fe4743 | 535 | |
jrodenburg | 0:a28a1035c31b | 536 | float m = a/b; |
jrodenburg | 0:a28a1035c31b | 537 | float y = (m*(ADC_val-thermLUT[i].adc))+thermLUT[i].temp; |
jrodenburg | 12:1cada1fe4743 | 538 | |
jrodenburg | 20:cdeed4dad690 | 539 | if (debug_control & ADC_VAL_PRINT) |
jrodenburg | 20:cdeed4dad690 | 540 | pc.printf("DBG: ADC VAL: %f TEMP: %f \r\n", ADC_val, y); |
jrodenburg | 12:1cada1fe4743 | 541 | |
jrodenburg | 12:1cada1fe4743 | 542 | return y; |
jrodenburg | 0:a28a1035c31b | 543 | } |
jrodenburg | 0:a28a1035c31b | 544 | |
jrodenburg | 20:cdeed4dad690 | 545 | /* Function: get_front_temp_DATA |
jrodenburg | 16:82d941b1ef21 | 546 | ************************************************************** |
jrodenburg | 20:cdeed4dad690 | 547 | Description: Read A/D data from LTC2487 and set array with front temp. |
jrodenburg | 20:cdeed4dad690 | 548 | Save values in CHNL_TEMP data struct |
jrodenburg | 20:cdeed4dad690 | 549 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 550 | Returns: int If the write recieved an ACK |
jrodenburg | 20:cdeed4dad690 | 551 | */ |
jrodenburg | 20:cdeed4dad690 | 552 | void read_front_temp_data() |
jrodenburg | 20:cdeed4dad690 | 553 | { |
jrodenburg | 20:cdeed4dad690 | 554 | readThermistorTicker.detach(); |
jrodenburg | 20:cdeed4dad690 | 555 | //Write to all 8 channels selecting the front port to read |
jrodenburg | 20:cdeed4dad690 | 556 | for(int chnl = 0; chnl < CHAN_COUNT; chnl++){ |
jrodenburg | 21:f87464a7e7c6 | 557 | chnlStatus[chnl].LTCi2cAckRxed = 0; |
jrodenburg | 20:cdeed4dad690 | 558 | ltc2487.setAddress(addrLUT[chnl].adc); |
jrodenburg | 20:cdeed4dad690 | 559 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 560 | chnlStatus[chnl].LTCi2cAckRxed = !ltc2487.writePort(FRONT_THERM); |
jrodenburg | 20:cdeed4dad690 | 561 | } |
jrodenburg | 20:cdeed4dad690 | 562 | //wait until next clock cycle on LTC |
jrodenburg | 20:cdeed4dad690 | 563 | //wait(I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 564 | frontTempInProgTicker.attach(&update_front_temp_data, I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 565 | } |
jrodenburg | 20:cdeed4dad690 | 566 | |
jrodenburg | 21:f87464a7e7c6 | 567 | void update_front_temp_data(){ |
jrodenburg | 21:f87464a7e7c6 | 568 | float countVal; |
jrodenburg | 20:cdeed4dad690 | 569 | frontTempInProgTicker.detach(); |
jrodenburg | 20:cdeed4dad690 | 570 | for(int chnl = 0; chnl < CHAN_COUNT; chnl++){ |
jrodenburg | 20:cdeed4dad690 | 571 | ltc2487.setAddress(addrLUT[chnl].adc); |
jrodenburg | 21:f87464a7e7c6 | 572 | countVal = ltc2487.read(); |
jrodenburg | 21:f87464a7e7c6 | 573 | channelTempData[chnl].currADCFront = countVal; |
jrodenburg | 21:f87464a7e7c6 | 574 | channelTempData[chnl].currTempFront = get_temp(countVal); |
jrodenburg | 20:cdeed4dad690 | 575 | } |
jrodenburg | 20:cdeed4dad690 | 576 | //wait until next clock cycle on LTC |
jrodenburg | 20:cdeed4dad690 | 577 | //wait(0.08); |
jrodenburg | 20:cdeed4dad690 | 578 | frontTempDoneTicker.attach(&read_back_temp, I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 579 | } |
jrodenburg | 20:cdeed4dad690 | 580 | |
jrodenburg | 20:cdeed4dad690 | 581 | /* Function: get_back_temp_DATA |
jrodenburg | 20:cdeed4dad690 | 582 | ************************************************************** |
jrodenburg | 20:cdeed4dad690 | 583 | Description: Read A/D data from LTC2487 and set array with back temp. |
jrodenburg | 20:cdeed4dad690 | 584 | Save values in CHNL_TEMP data struct |
jrodenburg | 16:82d941b1ef21 | 585 | Receives: N/A |
jrodenburg | 16:82d941b1ef21 | 586 | Returns: N/A |
jrodenburg | 16:82d941b1ef21 | 587 | */ |
jrodenburg | 16:82d941b1ef21 | 588 | |
jrodenburg | 20:cdeed4dad690 | 589 | void read_back_temp() |
jrodenburg | 20:cdeed4dad690 | 590 | { |
jrodenburg | 20:cdeed4dad690 | 591 | frontTempDoneTicker.detach(); |
jrodenburg | 16:82d941b1ef21 | 592 | //Write to all 8 channels selecting the front port to read |
jrodenburg | 20:cdeed4dad690 | 593 | for(int chnl = 0; chnl < CHAN_COUNT; chnl++){ |
jrodenburg | 21:f87464a7e7c6 | 594 | chnlStatus[chnl].LTCi2cAckRxed = 0; |
jrodenburg | 16:82d941b1ef21 | 595 | ltc2487.setAddress(addrLUT[chnl].adc); |
jrodenburg | 20:cdeed4dad690 | 596 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 597 | chnlStatus[chnl].LTCi2cAckRxed = !ltc2487.writePort(BACK_THERM); |
jrodenburg | 16:82d941b1ef21 | 598 | } |
jrodenburg | 20:cdeed4dad690 | 599 | |
jrodenburg | 16:82d941b1ef21 | 600 | //wait until next clock cycle on LTC |
jrodenburg | 20:cdeed4dad690 | 601 | //wait(I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 602 | backTempInProgTicker.attach(&update_back_temp_data, I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 603 | } |
jrodenburg | 20:cdeed4dad690 | 604 | |
jrodenburg | 21:f87464a7e7c6 | 605 | void update_back_temp_data(){ |
jrodenburg | 21:f87464a7e7c6 | 606 | float countVal; |
jrodenburg | 20:cdeed4dad690 | 607 | backTempInProgTicker.detach(); |
jrodenburg | 20:cdeed4dad690 | 608 | for(int chnl = 0; chnl < CHAN_COUNT; chnl++){ |
jrodenburg | 16:82d941b1ef21 | 609 | ltc2487.setAddress(addrLUT[chnl].adc); |
jrodenburg | 21:f87464a7e7c6 | 610 | countVal = ltc2487.read(); |
jrodenburg | 21:f87464a7e7c6 | 611 | channelTempData[chnl].currADCBack = countVal; |
jrodenburg | 21:f87464a7e7c6 | 612 | channelTempData[chnl].currTempBack = get_temp(countVal); |
jrodenburg | 16:82d941b1ef21 | 613 | } |
jrodenburg | 20:cdeed4dad690 | 614 | //wait until next clock cycle on LTC |
jrodenburg | 20:cdeed4dad690 | 615 | //wait(0.08); |
jrodenburg | 20:cdeed4dad690 | 616 | backTempDoneTicker.attach(&temperatureDataReady, I2C_READ_WAIT_TIME); |
jrodenburg | 20:cdeed4dad690 | 617 | |
jrodenburg | 20:cdeed4dad690 | 618 | } |
jrodenburg | 20:cdeed4dad690 | 619 | |
jrodenburg | 20:cdeed4dad690 | 620 | /* Function: temperatureDataReady |
jrodenburg | 20:cdeed4dad690 | 621 | ************************************************************** |
jrodenburg | 20:cdeed4dad690 | 622 | Description: Flag that temperature data is ready to be |
jrodenburg | 20:cdeed4dad690 | 623 | processed |
jrodenburg | 20:cdeed4dad690 | 624 | Restart task timer |
jrodenburg | 20:cdeed4dad690 | 625 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 626 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 627 | */ |
jrodenburg | 20:cdeed4dad690 | 628 | void temperatureDataReady() |
jrodenburg | 20:cdeed4dad690 | 629 | { |
jrodenburg | 20:cdeed4dad690 | 630 | backTempDoneTicker.detach(); |
jrodenburg | 20:cdeed4dad690 | 631 | newTempDataAvailable = true; |
jrodenburg | 20:cdeed4dad690 | 632 | readThermistorTicker.attach(&read_front_temp_data, READ_TEMP_TASK_TIME); |
jrodenburg | 16:82d941b1ef21 | 633 | } |
jrodenburg | 16:82d941b1ef21 | 634 | |
jrodenburg | 0:a28a1035c31b | 635 | /* Function: get_heater_current |
jrodenburg | 0:a28a1035c31b | 636 | ************************************************************** |
jrodenburg | 0:a28a1035c31b | 637 | Description: Retrieve current into heater control MOSFET |
jrodenburg | 12:1cada1fe4743 | 638 | Receives: chn: the channel of the fixture to read current from |
jrodenburg | 0:a28a1035c31b | 639 | Returns: the current into the heater control MOSFET |
jrodenburg | 0:a28a1035c31b | 640 | */ |
jrodenburg | 20:cdeed4dad690 | 641 | void get_heater_current(int chn, int port){ |
jrodenburg | 16:82d941b1ef21 | 642 | ltc2487.setAddress(addrLUT[chn].adc); |
jrodenburg | 16:82d941b1ef21 | 643 | ltc2487.writePort(HEAT_FET_AMP); |
jrodenburg | 16:82d941b1ef21 | 644 | wait(0.08); |
jrodenburg | 16:82d941b1ef21 | 645 | ltc2487.read(); |
jrodenburg | 16:82d941b1ef21 | 646 | wait(0.08); |
jrodenburg | 0:a28a1035c31b | 647 | } |
jrodenburg | 0:a28a1035c31b | 648 | |
jrodenburg | 0:a28a1035c31b | 649 | /* Function: get_valve_current |
jrodenburg | 0:a28a1035c31b | 650 | ************************************************************** |
jrodenburg | 0:a28a1035c31b | 651 | Description: Retrieve current into valve control MOSFET |
jrodenburg | 12:1cada1fe4743 | 652 | Receives: chn: the channel of the fixture to read current from |
jrodenburg | 0:a28a1035c31b | 653 | Returns: the current into the valve control MOSFET |
jrodenburg | 0:a28a1035c31b | 654 | */ |
jrodenburg | 0:a28a1035c31b | 655 | |
jrodenburg | 20:cdeed4dad690 | 656 | void get_valve_current(int chn, int port){ |
jrodenburg | 16:82d941b1ef21 | 657 | ltc2487.setAddress(addrLUT[chn].adc); |
jrodenburg | 16:82d941b1ef21 | 658 | ltc2487.writePort(VALVE_FET_AMP); |
jrodenburg | 16:82d941b1ef21 | 659 | wait(0.08); |
jrodenburg | 16:82d941b1ef21 | 660 | ltc2487.read(); |
jrodenburg | 16:82d941b1ef21 | 661 | wait(0.08); |
jrodenburg | 0:a28a1035c31b | 662 | } |
jrodenburg | 0:a28a1035c31b | 663 | |
jrodenburg | 21:f87464a7e7c6 | 664 | /* Function: MCP_Control |
jrodenburg | 0:a28a1035c31b | 665 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 666 | Description: Controls valves/status LEDs |
jrodenburg | 12:1cada1fe4743 | 667 | Receives: chn: the channel of the fixture |
jrodenburg | 0:a28a1035c31b | 668 | status: the status of channel (good (1) or bad (0)) |
jrodenburg | 1:0182b86f9bd4 | 669 | Returns: N/A |
jrodenburg | 0:a28a1035c31b | 670 | */ |
jrodenburg | 0:a28a1035c31b | 671 | |
jrodenburg | 21:f87464a7e7c6 | 672 | void Chn_Control(int chn, int status){ |
jrodenburg | 21:f87464a7e7c6 | 673 | //writeOutput(VALVE, HEATER, GREEN STATUS LED, RED STATUS LED) |
jrodenburg | 21:f87464a7e7c6 | 674 | pc.printf("[%i] CHANNEL CONTROL \r\n", chn); |
jrodenburg | 21:f87464a7e7c6 | 675 | if(status == VALVE_ON){ |
jrodenburg | 21:f87464a7e7c6 | 676 | //valve ON, heater OFF, green status LED ON, red status led OFF |
jrodenburg | 21:f87464a7e7c6 | 677 | if(debug_control & LED_PRINT) pc.printf("VALVE ON %d \r\n", chn); |
jrodenburg | 21:f87464a7e7c6 | 678 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 21:f87464a7e7c6 | 679 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 680 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 681 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 682 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(1,0,1,0); |
jrodenburg | 21:f87464a7e7c6 | 683 | } |
jrodenburg | 21:f87464a7e7c6 | 684 | if(status == HEATER_ON){ |
jrodenburg | 21:f87464a7e7c6 | 685 | //valve ON, heater ON, green status LED ON, red status led OFF |
jrodenburg | 21:f87464a7e7c6 | 686 | if(debug_control & LED_PRINT) pc.printf("HEATER ON %d \r\n", chn); |
jrodenburg | 21:f87464a7e7c6 | 687 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 21:f87464a7e7c6 | 688 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 689 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 690 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 691 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,1,1,0); |
jrodenburg | 21:f87464a7e7c6 | 692 | } |
jrodenburg | 20:cdeed4dad690 | 693 | if(status == GREEN_STATUS_ON){ |
jrodenburg | 21:f87464a7e7c6 | 694 | //valve OFF, heater OFF, green status LED ON, red status led OFF |
jrodenburg | 20:cdeed4dad690 | 695 | if(debug_control & LED_PRINT) pc.printf("GREEN LED %d \r\n", chn); |
jrodenburg | 20:cdeed4dad690 | 696 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 20:cdeed4dad690 | 697 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 698 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 699 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 700 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,1,0); |
jrodenburg | 0:a28a1035c31b | 701 | } |
jrodenburg | 20:cdeed4dad690 | 702 | if(status == RED_STATUS_ON){ |
jrodenburg | 21:f87464a7e7c6 | 703 | //valve OFF, heater OFF, green status LED OFF, red status led ON |
jrodenburg | 20:cdeed4dad690 | 704 | if(debug_control & LED_PRINT) pc.printf("RED LED %d \r\n", chn); |
jrodenburg | 20:cdeed4dad690 | 705 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 20:cdeed4dad690 | 706 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 707 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 708 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 709 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,0,1); |
jrodenburg | 20:cdeed4dad690 | 710 | } |
jrodenburg | 20:cdeed4dad690 | 711 | if(status == ERROR_STATUS_ON){ |
jrodenburg | 21:f87464a7e7c6 | 712 | //valve ON, heater OFF, green status LED OFF, red status led ON |
jrodenburg | 20:cdeed4dad690 | 713 | if(debug_control & LED_PRINT) pc.printf("RED AND BLUE LED %d \r\n", chn); |
jrodenburg | 20:cdeed4dad690 | 714 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 20:cdeed4dad690 | 715 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 716 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 717 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 718 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(1,0,0,1); |
jrodenburg | 0:a28a1035c31b | 719 | } |
jrodenburg | 21:f87464a7e7c6 | 720 | if(status == ALL_OFF){ |
jrodenburg | 21:f87464a7e7c6 | 721 | //valve OFF, heater OFF, green status LED OFF, red status led OFF |
jrodenburg | 21:f87464a7e7c6 | 722 | if(debug_control & LED_PRINT) pc.printf("ALL OFF %d \r\n", chn); |
jrodenburg | 20:cdeed4dad690 | 723 | io_control.setAddress(addrLUT[chn].io); |
jrodenburg | 20:cdeed4dad690 | 724 | io_control.init(); |
jrodenburg | 21:f87464a7e7c6 | 725 | chnlStatus[chn].MCPi2cAckRxed = 0; |
jrodenburg | 21:f87464a7e7c6 | 726 | //Check if write was ack'ed (0 = ACK, (non)0 = NACK) |
jrodenburg | 21:f87464a7e7c6 | 727 | chnlStatus[chn].MCPi2cAckRxed = !io_control.writeOutput(0,0,0,0); |
jrodenburg | 20:cdeed4dad690 | 728 | } |
jrodenburg | 0:a28a1035c31b | 729 | } |
jrodenburg | 0:a28a1035c31b | 730 | |
jrodenburg | 2:bd118a724f03 | 731 | |
jrodenburg | 8:dbf8bd4815f8 | 732 | //*************************************************************** |
jrodenburg | 8:dbf8bd4815f8 | 733 | // Build packet with temperature readings to send to GUI |
jrodenburg | 8:dbf8bd4815f8 | 734 | //*************************************************************** |
jrodenburg | 20:cdeed4dad690 | 735 | void processTxUARTData() |
jrodenburg | 20:cdeed4dad690 | 736 | { |
jrodenburg | 16:82d941b1ef21 | 737 | RESPONSE_TEMP_CMD response; |
jrodenburg | 8:dbf8bd4815f8 | 738 | unsigned char *ptr = (unsigned char *)&response; |
jrodenburg | 8:dbf8bd4815f8 | 739 | int i; |
jrodenburg | 8:dbf8bd4815f8 | 740 | |
jrodenburg | 8:dbf8bd4815f8 | 741 | response.SOF_flag = TX_SOF; |
jrodenburg | 15:74a01aaeb60e | 742 | response.cmd_type = TEMP_DATA; |
jrodenburg | 16:82d941b1ef21 | 743 | response.len = 5+(sizeof(response.chTemp)); |
jrodenburg | 8:dbf8bd4815f8 | 744 | response.Delim = DELIMETER; |
jrodenburg | 16:82d941b1ef21 | 745 | response.chTemp[0] = channelTempData[0].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 746 | response.chTemp[1] = channelTempData[1].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 747 | response.chTemp[2] = channelTempData[2].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 748 | response.chTemp[3] = channelTempData[3].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 749 | response.chTemp[4] = channelTempData[4].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 750 | response.chTemp[5] = channelTempData[5].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 751 | response.chTemp[6] = channelTempData[6].currTempBack; |
jrodenburg | 16:82d941b1ef21 | 752 | response.chTemp[7] = channelTempData[7].currTempBack; |
jrodenburg | 20:cdeed4dad690 | 753 | |
jrodenburg | 20:cdeed4dad690 | 754 | // Send Errors Count/Info |
jrodenburg | 20:cdeed4dad690 | 755 | |
jrodenburg | 16:82d941b1ef21 | 756 | /*float *dst = (float *)&response.chTemp[0]; |
jrodenburg | 16:82d941b1ef21 | 757 | float *src = (float *)&channelTempData[0]; |
jrodenburg | 16:82d941b1ef21 | 758 | memcpy(dst, src, sizeof(channelTempData));*/ |
jrodenburg | 8:dbf8bd4815f8 | 759 | response.EOF_flag = TX_EOF; |
jrodenburg | 8:dbf8bd4815f8 | 760 | |
jrodenburg | 8:dbf8bd4815f8 | 761 | // Send response to GUI |
jrodenburg | 8:dbf8bd4815f8 | 762 | for (i=0; i < response.len; i++, ptr++) |
jrodenburg | 8:dbf8bd4815f8 | 763 | pc.printf("%02x", *ptr); |
jrodenburg | 8:dbf8bd4815f8 | 764 | pc.printf("\n"); |
jrodenburg | 8:dbf8bd4815f8 | 765 | } |
jrodenburg | 8:dbf8bd4815f8 | 766 | |
jrodenburg | 12:1cada1fe4743 | 767 | //*************************************************************** |
jrodenburg | 15:74a01aaeb60e | 768 | // Build packet with Board UID (Unique Identification) |
jrodenburg | 15:74a01aaeb60e | 769 | //*************************************************************** |
jrodenburg | 15:74a01aaeb60e | 770 | void sendUID () |
jrodenburg | 15:74a01aaeb60e | 771 | { |
jrodenburg | 15:74a01aaeb60e | 772 | UID_RESPONSE response; |
jrodenburg | 15:74a01aaeb60e | 773 | unsigned char *ptr = (unsigned char *)&response; |
jrodenburg | 15:74a01aaeb60e | 774 | int i; |
jrodenburg | 15:74a01aaeb60e | 775 | |
jrodenburg | 15:74a01aaeb60e | 776 | response.SOF_flag = TX_SOF; |
jrodenburg | 15:74a01aaeb60e | 777 | response.cmd_type = UID_DATA; |
jrodenburg | 15:74a01aaeb60e | 778 | response.len = 17; |
jrodenburg | 15:74a01aaeb60e | 779 | response.Delim = DELIMETER; |
jrodenburg | 15:74a01aaeb60e | 780 | response.UIDMH = (uint32_t)SIM->UIDMH; |
jrodenburg | 15:74a01aaeb60e | 781 | response.UIDML = (uint32_t)SIM->UIDML; |
jrodenburg | 15:74a01aaeb60e | 782 | response.UIDL = (uint32_t)SIM->UIDL; |
jrodenburg | 15:74a01aaeb60e | 783 | response.EOF_flag = TX_EOF; |
jrodenburg | 15:74a01aaeb60e | 784 | |
jrodenburg | 15:74a01aaeb60e | 785 | // Send response to GUI |
jrodenburg | 15:74a01aaeb60e | 786 | for (i=0; i < response.len; i++, ptr++) |
jrodenburg | 15:74a01aaeb60e | 787 | pc.printf("%02x", *ptr); |
jrodenburg | 15:74a01aaeb60e | 788 | pc.printf("\n"); |
jrodenburg | 15:74a01aaeb60e | 789 | } |
jrodenburg | 15:74a01aaeb60e | 790 | |
jrodenburg | 15:74a01aaeb60e | 791 | //*************************************************************** |
jrodenburg | 20:cdeed4dad690 | 792 | // Build packet with SW Version |
jrodenburg | 20:cdeed4dad690 | 793 | //*************************************************************** |
jrodenburg | 20:cdeed4dad690 | 794 | void sendFWVersion() |
jrodenburg | 20:cdeed4dad690 | 795 | { |
jrodenburg | 20:cdeed4dad690 | 796 | FW_VERSION_RESPONSE response; |
jrodenburg | 20:cdeed4dad690 | 797 | unsigned char *ptr = (unsigned char *)&response; |
jrodenburg | 20:cdeed4dad690 | 798 | int i; |
jrodenburg | 20:cdeed4dad690 | 799 | rLed = 1; |
jrodenburg | 20:cdeed4dad690 | 800 | |
jrodenburg | 20:cdeed4dad690 | 801 | for (i=0; i < 20; i++) |
jrodenburg | 20:cdeed4dad690 | 802 | rLed = 0; |
jrodenburg | 20:cdeed4dad690 | 803 | |
jrodenburg | 20:cdeed4dad690 | 804 | rLed = 1; |
jrodenburg | 20:cdeed4dad690 | 805 | |
jrodenburg | 20:cdeed4dad690 | 806 | response.SOF_flag = TX_SOF; |
jrodenburg | 20:cdeed4dad690 | 807 | response.cmd_type = FW_VERSION_DATA; |
jrodenburg | 20:cdeed4dad690 | 808 | response.len = 13; |
jrodenburg | 20:cdeed4dad690 | 809 | response.Delim = DELIMETER; |
jrodenburg | 20:cdeed4dad690 | 810 | memcpy(response.FW_Version, FW_Version, 8); |
jrodenburg | 20:cdeed4dad690 | 811 | response.FW_Version[7] = '\0'; |
jrodenburg | 20:cdeed4dad690 | 812 | response.EOF_flag = TX_EOF; |
jrodenburg | 20:cdeed4dad690 | 813 | |
jrodenburg | 20:cdeed4dad690 | 814 | // Send response to GUI |
jrodenburg | 20:cdeed4dad690 | 815 | for (i=0; i < response.len; i++, ptr++) |
jrodenburg | 20:cdeed4dad690 | 816 | pc.printf("%02x", *ptr); |
jrodenburg | 20:cdeed4dad690 | 817 | pc.printf("\n"); |
jrodenburg | 20:cdeed4dad690 | 818 | } |
jrodenburg | 20:cdeed4dad690 | 819 | |
jrodenburg | 20:cdeed4dad690 | 820 | //*************************************************************** |
jrodenburg | 12:1cada1fe4743 | 821 | // Build packet with errors to send to GUI |
jrodenburg | 12:1cada1fe4743 | 822 | //*************************************************************** |
jrodenburg | 12:1cada1fe4743 | 823 | void sendError (int chan, float error) |
jrodenburg | 12:1cada1fe4743 | 824 | { |
jrodenburg | 12:1cada1fe4743 | 825 | RESPONSE_CMD response; |
jrodenburg | 12:1cada1fe4743 | 826 | unsigned char *ptr = (unsigned char *)&response; |
jrodenburg | 12:1cada1fe4743 | 827 | int i; |
jrodenburg | 12:1cada1fe4743 | 828 | |
jrodenburg | 12:1cada1fe4743 | 829 | response.SOF_flag = TX_SOF; |
jrodenburg | 12:1cada1fe4743 | 830 | response.cmd_type = ERROR_DATA; |
jrodenburg | 20:cdeed4dad690 | 831 | response.len = 13; |
jrodenburg | 12:1cada1fe4743 | 832 | response.Delim = DELIMETER; |
jrodenburg | 20:cdeed4dad690 | 833 | response.channel = chan; |
jrodenburg | 12:1cada1fe4743 | 834 | response.data = (float)error; |
jrodenburg | 20:cdeed4dad690 | 835 | |
jrodenburg | 12:1cada1fe4743 | 836 | response.EOF_flag = TX_EOF; |
jrodenburg | 12:1cada1fe4743 | 837 | |
jrodenburg | 12:1cada1fe4743 | 838 | // Send response to GUI |
jrodenburg | 12:1cada1fe4743 | 839 | for (i=0; i < response.len; i++, ptr++) |
jrodenburg | 12:1cada1fe4743 | 840 | pc.printf("%02x", *ptr); |
jrodenburg | 12:1cada1fe4743 | 841 | pc.printf("\n"); |
jrodenburg | 20:cdeed4dad690 | 842 | |
jrodenburg | 20:cdeed4dad690 | 843 | } |
jrodenburg | 20:cdeed4dad690 | 844 | |
jrodenburg | 20:cdeed4dad690 | 845 | /* Function: toggleI2C |
jrodenburg | 20:cdeed4dad690 | 846 | ************************************************************** |
jrodenburg | 20:cdeed4dad690 | 847 | Description: Toggle the I2C line in an attempt to unfreeze it |
jrodenburg | 20:cdeed4dad690 | 848 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 849 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 850 | */ |
jrodenburg | 20:cdeed4dad690 | 851 | |
jrodenburg | 20:cdeed4dad690 | 852 | void toggleI2C(){ |
jrodenburg | 20:cdeed4dad690 | 853 | DigitalOut ioSDAIn(PTC9); |
jrodenburg | 20:cdeed4dad690 | 854 | DigitalOut adcSDAIn(PTC11); |
jrodenburg | 20:cdeed4dad690 | 855 | DigitalOut ioSCLIn(PTC8); |
jrodenburg | 20:cdeed4dad690 | 856 | DigitalOut adcSCLIn(PTC10); |
jrodenburg | 20:cdeed4dad690 | 857 | |
jrodenburg | 20:cdeed4dad690 | 858 | ioSDAIn = 1; |
jrodenburg | 20:cdeed4dad690 | 859 | adcSDAIn = 1; |
jrodenburg | 20:cdeed4dad690 | 860 | ioSCLIn = 1; |
jrodenburg | 20:cdeed4dad690 | 861 | adcSCLIn = 1; |
jrodenburg | 20:cdeed4dad690 | 862 | wait(0.5); |
jrodenburg | 20:cdeed4dad690 | 863 | ioSDAIn = 0; |
jrodenburg | 20:cdeed4dad690 | 864 | adcSDAIn = 0; |
jrodenburg | 20:cdeed4dad690 | 865 | ioSCLIn = 0; |
jrodenburg | 20:cdeed4dad690 | 866 | adcSCLIn = 0; |
jrodenburg | 20:cdeed4dad690 | 867 | wait(0.5); |
jrodenburg | 20:cdeed4dad690 | 868 | ioSDAIn = 1; |
jrodenburg | 20:cdeed4dad690 | 869 | adcSDAIn = 1; |
jrodenburg | 20:cdeed4dad690 | 870 | ioSCLIn = 1; |
jrodenburg | 20:cdeed4dad690 | 871 | adcSCLIn = 1; |
jrodenburg | 20:cdeed4dad690 | 872 | wait(0.5); |
jrodenburg | 20:cdeed4dad690 | 873 | ioSDAIn = 0; |
jrodenburg | 20:cdeed4dad690 | 874 | adcSDAIn = 0; |
jrodenburg | 20:cdeed4dad690 | 875 | ioSCLIn = 0; |
jrodenburg | 20:cdeed4dad690 | 876 | adcSCLIn = 0; |
jrodenburg | 20:cdeed4dad690 | 877 | wait(0.5); |
jrodenburg | 20:cdeed4dad690 | 878 | |
jrodenburg | 20:cdeed4dad690 | 879 | MCP23008 io_control(PTC9, PTC8, 0x10, 100000); //sda, scl |
jrodenburg | 20:cdeed4dad690 | 880 | LTC2487 ltc2487(PTC11, PTC10, 0x23, 100000); //sda, scl |
jrodenburg | 20:cdeed4dad690 | 881 | |
jrodenburg | 20:cdeed4dad690 | 882 | } |
jrodenburg | 20:cdeed4dad690 | 883 | |
jrodenburg | 21:f87464a7e7c6 | 884 | /* Function: sendErrorEmail |
jrodenburg | 21:f87464a7e7c6 | 885 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 886 | Description: sends error email |
jrodenburg | 21:f87464a7e7c6 | 887 | Receives: chn: channel to check error on |
jrodenburg | 21:f87464a7e7c6 | 888 | Returns: N/A |
jrodenburg | 21:f87464a7e7c6 | 889 | */ |
jrodenburg | 21:f87464a7e7c6 | 890 | |
jrodenburg | 21:f87464a7e7c6 | 891 | void sendErrorEmail(int chn){ |
jrodenburg | 21:f87464a7e7c6 | 892 | int error; |
jrodenburg | 21:f87464a7e7c6 | 893 | |
jrodenburg | 21:f87464a7e7c6 | 894 | for (error=0; error < ERROR_COUNT; error++){ |
jrodenburg | 21:f87464a7e7c6 | 895 | if((errorCount[chn][error] == MAX_ERROR_CNT) && (!errorEmailSent[chn][error])){ |
jrodenburg | 21:f87464a7e7c6 | 896 | sendError(chn, error); |
jrodenburg | 21:f87464a7e7c6 | 897 | errorEmailSent[chn][error] = 1; |
jrodenburg | 21:f87464a7e7c6 | 898 | } |
jrodenburg | 21:f87464a7e7c6 | 899 | } |
jrodenburg | 21:f87464a7e7c6 | 900 | } |
jrodenburg | 21:f87464a7e7c6 | 901 | |
jrodenburg | 21:f87464a7e7c6 | 902 | /* Function: errorCheck |
jrodenburg | 21:f87464a7e7c6 | 903 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 904 | Description: Updates error count for the channel |
jrodenburg | 21:f87464a7e7c6 | 905 | Receives: chn: channel to update |
jrodenburg | 21:f87464a7e7c6 | 906 | errorFlag: if the error was encountered |
jrodenburg | 21:f87464a7e7c6 | 907 | errorNum: number of error encountered |
jrodenburg | 21:f87464a7e7c6 | 908 | Returns: N/A |
jrodenburg | 21:f87464a7e7c6 | 909 | */ |
jrodenburg | 21:f87464a7e7c6 | 910 | |
jrodenburg | 21:f87464a7e7c6 | 911 | void errorCheck(int chn, bool errorFlag, int errorNum){ |
jrodenburg | 21:f87464a7e7c6 | 912 | if(errorFlag){ |
jrodenburg | 21:f87464a7e7c6 | 913 | if(errorCount[chn][errorNum] < MAX_ERROR_CNT){ |
jrodenburg | 21:f87464a7e7c6 | 914 | //increase error count |
jrodenburg | 21:f87464a7e7c6 | 915 | errorCount[chn][errorNum]++; |
jrodenburg | 21:f87464a7e7c6 | 916 | pc.printf("[%i] ERROR ENCOUNTERED: %i %i \r\n", chn, errorNum, errorCount[chn][errorNum]); |
jrodenburg | 21:f87464a7e7c6 | 917 | } |
jrodenburg | 21:f87464a7e7c6 | 918 | else{ |
jrodenburg | 21:f87464a7e7c6 | 919 | //this is an error, set error flag |
jrodenburg | 21:f87464a7e7c6 | 920 | chnlStatus[chn].error = true; |
jrodenburg | 21:f87464a7e7c6 | 921 | //pc.printf("[%i] ERROR FLAGGED: %i %i\r\n", chn, errorNum, errorCount[chn][errorNum]); |
jrodenburg | 21:f87464a7e7c6 | 922 | } |
jrodenburg | 21:f87464a7e7c6 | 923 | } |
jrodenburg | 21:f87464a7e7c6 | 924 | else{ |
jrodenburg | 21:f87464a7e7c6 | 925 | if(errorCount[chn][errorNum] > 0){ |
jrodenburg | 21:f87464a7e7c6 | 926 | //decrease error count |
jrodenburg | 21:f87464a7e7c6 | 927 | errorCount[chn][errorNum]--; |
jrodenburg | 21:f87464a7e7c6 | 928 | } |
jrodenburg | 21:f87464a7e7c6 | 929 | //pc.printf("[%i] NO ERROR FLAGGED: %i \r\n\n", chn, errorNum); |
jrodenburg | 21:f87464a7e7c6 | 930 | } |
jrodenburg | 21:f87464a7e7c6 | 931 | } |
jrodenburg | 21:f87464a7e7c6 | 932 | |
jrodenburg | 20:cdeed4dad690 | 933 | /* Function: softwareReset |
jrodenburg | 20:cdeed4dad690 | 934 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 935 | Description: soft reset |
jrodenburg | 20:cdeed4dad690 | 936 | Recieves: N/A |
jrodenburg | 20:cdeed4dad690 | 937 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 938 | */ |
jrodenburg | 20:cdeed4dad690 | 939 | |
jrodenburg | 20:cdeed4dad690 | 940 | void softwareReset(void){ |
jrodenburg | 20:cdeed4dad690 | 941 | SCB->AIRCR = (0x5FA<<SCB_AIRCR_VECTKEY_Pos)|SCB_AIRCR_SYSRESETREQ_Msk; |
jrodenburg | 20:cdeed4dad690 | 942 | for(;;){} |
jrodenburg | 20:cdeed4dad690 | 943 | } |
jrodenburg | 20:cdeed4dad690 | 944 | |
jrodenburg | 21:f87464a7e7c6 | 945 | /* Function: SP_Time_Check |
jrodenburg | 21:f87464a7e7c6 | 946 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 947 | Description: Reset the SP time for each channel every minute |
jrodenburg | 21:f87464a7e7c6 | 948 | (minutes since SP has been set and SP hasn't been reach) |
jrodenburg | 21:f87464a7e7c6 | 949 | Recieves: N/A |
jrodenburg | 21:f87464a7e7c6 | 950 | Returns: N/A |
jrodenburg | 21:f87464a7e7c6 | 951 | */ |
jrodenburg | 21:f87464a7e7c6 | 952 | |
jrodenburg | 21:f87464a7e7c6 | 953 | void SP_Time_Check(){ |
jrodenburg | 21:f87464a7e7c6 | 954 | int chan; |
jrodenburg | 21:f87464a7e7c6 | 955 | |
jrodenburg | 21:f87464a7e7c6 | 956 | for (chan=0; chan < CHAN_COUNT; chan++){ |
jrodenburg | 21:f87464a7e7c6 | 957 | if(chnlStatus[chan].status == 1){ |
jrodenburg | 21:f87464a7e7c6 | 958 | if(!chnlStatus[chan].SPReached){ |
jrodenburg | 21:f87464a7e7c6 | 959 | if(chnlStatus[chan].SPTime != MAX_TIME_TO_SP){ |
jrodenburg | 21:f87464a7e7c6 | 960 | chnlStatus[chan].SPTime++; |
jrodenburg | 21:f87464a7e7c6 | 961 | } |
jrodenburg | 21:f87464a7e7c6 | 962 | } |
jrodenburg | 21:f87464a7e7c6 | 963 | } |
jrodenburg | 21:f87464a7e7c6 | 964 | } |
jrodenburg | 21:f87464a7e7c6 | 965 | } |
jrodenburg | 21:f87464a7e7c6 | 966 | |
jrodenburg | 20:cdeed4dad690 | 967 | /* Function: read I2C Line |
jrodenburg | 20:cdeed4dad690 | 968 | ************************************************************** |
jrodenburg | 20:cdeed4dad690 | 969 | Description: Read the I2C line to check if pulled high |
jrodenburg | 20:cdeed4dad690 | 970 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 971 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 972 | */ |
jrodenburg | 20:cdeed4dad690 | 973 | |
jrodenburg | 20:cdeed4dad690 | 974 | int readI2CLine(int line) |
jrodenburg | 20:cdeed4dad690 | 975 | { |
jrodenburg | 20:cdeed4dad690 | 976 | if(line == IO_I2C_LINE){ |
jrodenburg | 20:cdeed4dad690 | 977 | DigitalIn ioSDAIn(PTC9); |
jrodenburg | 20:cdeed4dad690 | 978 | int ioSDA = ioSDAIn.read(); |
jrodenburg | 20:cdeed4dad690 | 979 | if(I2C_PRINT) pc.printf("DBG: TEMPERATURE SDA LINE: %d \r\n", ioSDA); |
jrodenburg | 20:cdeed4dad690 | 980 | MCP23008 io_control(PTC9, PTC8, 0x10, 100000); //sda, scl |
jrodenburg | 20:cdeed4dad690 | 981 | return ioSDA; |
jrodenburg | 20:cdeed4dad690 | 982 | } |
jrodenburg | 20:cdeed4dad690 | 983 | if(line == ADC_I2C_LINE){ |
jrodenburg | 20:cdeed4dad690 | 984 | DigitalIn adcSDAIn(PTC11); |
jrodenburg | 20:cdeed4dad690 | 985 | int adcSDA = adcSDAIn.read(); |
jrodenburg | 20:cdeed4dad690 | 986 | if(I2C_PRINT) pc.printf("DBG: IO SDA LINE: %d \r\n", adcSDA); |
jrodenburg | 20:cdeed4dad690 | 987 | LTC2487 ltc2487(PTC11, PTC10, 0x23, 100000); //sda, scl |
jrodenburg | 20:cdeed4dad690 | 988 | return adcSDA; |
jrodenburg | 20:cdeed4dad690 | 989 | } |
jrodenburg | 20:cdeed4dad690 | 990 | return 0; |
jrodenburg | 12:1cada1fe4743 | 991 | } |
jrodenburg | 6:c980535393ed | 992 | |
jrodenburg | 6:c980535393ed | 993 | |
jrodenburg | 20:cdeed4dad690 | 994 | /* Function: systemLogic |
jrodenburg | 20:cdeed4dad690 | 995 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 996 | Description: Sets setting for fixture needed to maintain temperature at SP |
jrodenburg | 21:f87464a7e7c6 | 997 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 998 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 999 | */ |
jrodenburg | 20:cdeed4dad690 | 1000 | |
jrodenburg | 20:cdeed4dad690 | 1001 | void systemLogic(){ |
jrodenburg | 20:cdeed4dad690 | 1002 | int chan; |
jrodenburg | 20:cdeed4dad690 | 1003 | float currTemp; |
jrodenburg | 20:cdeed4dad690 | 1004 | |
jrodenburg | 20:cdeed4dad690 | 1005 | for (chan=0; chan < CHAN_COUNT; chan++) |
jrodenburg | 20:cdeed4dad690 | 1006 | { |
jrodenburg | 20:cdeed4dad690 | 1007 | if(chnlStatus[chan].status == 1){ |
jrodenburg | 20:cdeed4dad690 | 1008 | //Current Temperature |
jrodenburg | 20:cdeed4dad690 | 1009 | currTemp = channelTempData[chan].currTempBack; |
jrodenburg | 20:cdeed4dad690 | 1010 | |
jrodenburg | 20:cdeed4dad690 | 1011 | if(currTemp > ((chnlStatus[chan].setTemp)+HYST_HIGH)){ |
jrodenburg | 20:cdeed4dad690 | 1012 | //TURN COOLING ON |
jrodenburg | 20:cdeed4dad690 | 1013 | chnlStatus[chan].state = STATUS_COOLING; |
jrodenburg | 20:cdeed4dad690 | 1014 | } |
jrodenburg | 20:cdeed4dad690 | 1015 | else if(currTemp < ((chnlStatus[chan].setTemp)-HYST_LOW)){ |
jrodenburg | 20:cdeed4dad690 | 1016 | //TURN HEATER ON |
jrodenburg | 20:cdeed4dad690 | 1017 | chnlStatus[chan].state = STATUS_HEATING; |
jrodenburg | 20:cdeed4dad690 | 1018 | } |
jrodenburg | 20:cdeed4dad690 | 1019 | else{ |
jrodenburg | 20:cdeed4dad690 | 1020 | //FIXTURE INACTIVE |
jrodenburg | 20:cdeed4dad690 | 1021 | chnlStatus[chan].state = STATUS_INACTIVE; |
jrodenburg | 20:cdeed4dad690 | 1022 | } |
jrodenburg | 20:cdeed4dad690 | 1023 | } |
jrodenburg | 20:cdeed4dad690 | 1024 | else{ |
jrodenburg | 20:cdeed4dad690 | 1025 | //FIXTURE STANDBY |
jrodenburg | 21:f87464a7e7c6 | 1026 | pc.printf("FIXTURE IN STANDBY \r\n"); |
jrodenburg | 20:cdeed4dad690 | 1027 | chnlStatus[chan].state = STATUS_STANDBY; |
jrodenburg | 20:cdeed4dad690 | 1028 | } |
jrodenburg | 20:cdeed4dad690 | 1029 | } |
jrodenburg | 20:cdeed4dad690 | 1030 | |
jrodenburg | 20:cdeed4dad690 | 1031 | } |
jrodenburg | 20:cdeed4dad690 | 1032 | |
jrodenburg | 20:cdeed4dad690 | 1033 | /* Function: systemControl |
jrodenburg | 20:cdeed4dad690 | 1034 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 1035 | Description: Changes fixture setting in accordance to logic set in systemLOGIC function |
jrodenburg | 21:f87464a7e7c6 | 1036 | Receives: N/A |
jrodenburg | 20:cdeed4dad690 | 1037 | Returns: N/A |
jrodenburg | 20:cdeed4dad690 | 1038 | */ |
jrodenburg | 20:cdeed4dad690 | 1039 | |
jrodenburg | 20:cdeed4dad690 | 1040 | void systemControl() |
jrodenburg | 20:cdeed4dad690 | 1041 | { |
jrodenburg | 20:cdeed4dad690 | 1042 | int chan; |
jrodenburg | 21:f87464a7e7c6 | 1043 | |
jrodenburg | 20:cdeed4dad690 | 1044 | for (chan=0; chan < CHAN_COUNT; chan++){ |
jrodenburg | 21:f87464a7e7c6 | 1045 | pc.printf("[%i] CHANNEL ERRORS: %d \r\n", chan, chnlStatus[chan].error); |
jrodenburg | 21:f87464a7e7c6 | 1046 | if(!chnlStatus[chan].error){ |
jrodenburg | 21:f87464a7e7c6 | 1047 | //pc.printf("[%i] CHANNEL NO ERRORS \r\n", chan); |
jrodenburg | 21:f87464a7e7c6 | 1048 | if(errorCount[chan][ERR_ACK_LTC] == 0){ |
jrodenburg | 21:f87464a7e7c6 | 1049 | if(chnlStatus[chan].state == STATUS_INACTIVE){ |
jrodenburg | 21:f87464a7e7c6 | 1050 | //FIXTURE INACTIVE |
jrodenburg | 21:f87464a7e7c6 | 1051 | Chn_Control(chan, GREEN_STATUS_ON); |
jrodenburg | 21:f87464a7e7c6 | 1052 | //SP reached |
jrodenburg | 21:f87464a7e7c6 | 1053 | chnlStatus[chan].SPReached = true; |
jrodenburg | 21:f87464a7e7c6 | 1054 | } |
jrodenburg | 21:f87464a7e7c6 | 1055 | else if(chnlStatus[chan].state == STATUS_COOLING){ |
jrodenburg | 21:f87464a7e7c6 | 1056 | //TURN COOLING ON |
jrodenburg | 21:f87464a7e7c6 | 1057 | Chn_Control(chan, VALVE_ON); |
jrodenburg | 21:f87464a7e7c6 | 1058 | } |
jrodenburg | 21:f87464a7e7c6 | 1059 | else if(chnlStatus[chan].state == STATUS_HEATING){ |
jrodenburg | 21:f87464a7e7c6 | 1060 | //TURN HEATER ON (have to toggle bc of charge pump in circuit) |
jrodenburg | 21:f87464a7e7c6 | 1061 | Chn_Control(chan, GREEN_STATUS_ON); //turn heater off |
jrodenburg | 21:f87464a7e7c6 | 1062 | Chn_Control(chan, HEATER_ON); |
jrodenburg | 21:f87464a7e7c6 | 1063 | } |
jrodenburg | 21:f87464a7e7c6 | 1064 | else if(chnlStatus[chan].state == STATUS_STANDBY){ |
jrodenburg | 21:f87464a7e7c6 | 1065 | //FIXTURE IN STANDBY (i.e. off) |
jrodenburg | 21:f87464a7e7c6 | 1066 | if(standbyLED[chan]){ |
jrodenburg | 21:f87464a7e7c6 | 1067 | Chn_Control(chan, GREEN_STATUS_ON); |
jrodenburg | 21:f87464a7e7c6 | 1068 | standbyLED[chan] = !standbyLED[chan]; |
jrodenburg | 21:f87464a7e7c6 | 1069 | } |
jrodenburg | 21:f87464a7e7c6 | 1070 | else{ |
jrodenburg | 21:f87464a7e7c6 | 1071 | Chn_Control(chan, ALL_OFF); |
jrodenburg | 21:f87464a7e7c6 | 1072 | standbyLED[chan] = !standbyLED[chan]; |
jrodenburg | 21:f87464a7e7c6 | 1073 | } |
jrodenburg | 21:f87464a7e7c6 | 1074 | } |
jrodenburg | 20:cdeed4dad690 | 1075 | } |
jrodenburg | 20:cdeed4dad690 | 1076 | } |
jrodenburg | 21:f87464a7e7c6 | 1077 | else{ |
jrodenburg | 21:f87464a7e7c6 | 1078 | sendErrorEmail(chan); |
jrodenburg | 20:cdeed4dad690 | 1079 | } |
jrodenburg | 20:cdeed4dad690 | 1080 | } |
jrodenburg | 20:cdeed4dad690 | 1081 | } |
jrodenburg | 20:cdeed4dad690 | 1082 | |
jrodenburg | 21:f87464a7e7c6 | 1083 | /* Function: systemDiagnostic |
jrodenburg | 21:f87464a7e7c6 | 1084 | ************************************************************** |
jrodenburg | 21:f87464a7e7c6 | 1085 | Description: Checks for any system errors |
jrodenburg | 21:f87464a7e7c6 | 1086 | Receives: chn: Channel to modify |
jrodenburg | 21:f87464a7e7c6 | 1087 | Returns: N/A |
jrodenburg | 21:f87464a7e7c6 | 1088 | */ |
jrodenburg | 21:f87464a7e7c6 | 1089 | |
jrodenburg | 21:f87464a7e7c6 | 1090 | void systemDiagnostic(){ |
jrodenburg | 21:f87464a7e7c6 | 1091 | int chan; |
jrodenburg | 21:f87464a7e7c6 | 1092 | float backCount; |
jrodenburg | 21:f87464a7e7c6 | 1093 | float frontCount; |
jrodenburg | 21:f87464a7e7c6 | 1094 | float backTemp; |
jrodenburg | 21:f87464a7e7c6 | 1095 | float frontTemp; |
jrodenburg | 21:f87464a7e7c6 | 1096 | bool errorFlag; |
jrodenburg | 21:f87464a7e7c6 | 1097 | float tempDiff; |
jrodenburg | 21:f87464a7e7c6 | 1098 | int LTC_Ack; |
jrodenburg | 21:f87464a7e7c6 | 1099 | int MCP_Ack; |
jrodenburg | 21:f87464a7e7c6 | 1100 | int timeToSP; |
jrodenburg | 21:f87464a7e7c6 | 1101 | bool reachedSP; |
jrodenburg | 21:f87464a7e7c6 | 1102 | |
jrodenburg | 21:f87464a7e7c6 | 1103 | for (chan=0; chan < CHAN_COUNT; chan++){ |
jrodenburg | 21:f87464a7e7c6 | 1104 | backCount = channelTempData[chan].currADCBack; |
jrodenburg | 21:f87464a7e7c6 | 1105 | frontCount = channelTempData[chan].currADCFront; |
jrodenburg | 21:f87464a7e7c6 | 1106 | frontTemp = channelTempData[chan].currTempFront; |
jrodenburg | 21:f87464a7e7c6 | 1107 | backTemp = channelTempData[chan].currTempBack; |
jrodenburg | 21:f87464a7e7c6 | 1108 | LTC_Ack = chnlStatus[chan].LTCi2cAckRxed; |
jrodenburg | 21:f87464a7e7c6 | 1109 | MCP_Ack = chnlStatus[chan].MCPi2cAckRxed; |
jrodenburg | 21:f87464a7e7c6 | 1110 | timeToSP = chnlStatus[chan].SPTime; |
jrodenburg | 21:f87464a7e7c6 | 1111 | reachedSP = chnlStatus[chan].SPReached; |
jrodenburg | 21:f87464a7e7c6 | 1112 | |
jrodenburg | 21:f87464a7e7c6 | 1113 | if(PRINT_ERROR_CHECK_VALS){ |
jrodenburg | 21:f87464a7e7c6 | 1114 | pc.printf("BAKC COUNT: %f \r\n", backCount); |
jrodenburg | 21:f87464a7e7c6 | 1115 | pc.printf("FRONT COUNT: %f \r\n", frontCount); |
jrodenburg | 21:f87464a7e7c6 | 1116 | pc.printf("TEMP DIFF: %f \r\n", abs(frontTemp-backTemp)); |
jrodenburg | 21:f87464a7e7c6 | 1117 | pc.printf("LTC ACK: %f \r\n", LTC_Ack); |
jrodenburg | 21:f87464a7e7c6 | 1118 | pc.printf("MCP ACK: %f \r\n", MCP_Ack); |
jrodenburg | 21:f87464a7e7c6 | 1119 | } |
jrodenburg | 21:f87464a7e7c6 | 1120 | |
jrodenburg | 21:f87464a7e7c6 | 1121 | //Check if the ADC temperature is too high (low ADC count) |
jrodenburg | 21:f87464a7e7c6 | 1122 | errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1123 | if((backCount < MIN_AD_COUNT) || (frontCount < MIN_AD_COUNT)) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1124 | errorCheck(chan, errorFlag, ERR_OVER_TEMP); |
jrodenburg | 21:f87464a7e7c6 | 1125 | |
jrodenburg | 21:f87464a7e7c6 | 1126 | //Check if the ADC temperature is too low (high ADC count), valve stuck on |
jrodenburg | 21:f87464a7e7c6 | 1127 | errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1128 | if((backCount > MAX_AD_COUNT) || (frontCount > MAX_AD_COUNT)) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1129 | errorCheck(chan, errorFlag, ERR_UNDER_TEMP); |
jrodenburg | 21:f87464a7e7c6 | 1130 | |
jrodenburg | 21:f87464a7e7c6 | 1131 | //Check for a substantial temp. diff. |b| the front & back of the fixture |
jrodenburg | 21:f87464a7e7c6 | 1132 | errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1133 | tempDiff = abs(frontTemp-backTemp); |
jrodenburg | 21:f87464a7e7c6 | 1134 | if(tempDiff > TEMP_MARGIN) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1135 | errorCheck(chan, errorFlag, ERR_TEMP_DIFF); |
jrodenburg | 21:f87464a7e7c6 | 1136 | |
jrodenburg | 21:f87464a7e7c6 | 1137 | //Check for ACK from the LTC2487 chip (temperature reading) |
jrodenburg | 21:f87464a7e7c6 | 1138 | errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1139 | if(!LTC_Ack) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1140 | errorCheck(chan, errorFlag, ERR_ACK_LTC); |
jrodenburg | 21:f87464a7e7c6 | 1141 | |
jrodenburg | 21:f87464a7e7c6 | 1142 | //Check for ACK from the MCP23008 chip (valve/heater controller) |
jrodenburg | 21:f87464a7e7c6 | 1143 | /*errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1144 | if(!MCP_Ack) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1145 | errorCheck(chan, errorFlag, ERR_ACK_MCP);*/ |
jrodenburg | 21:f87464a7e7c6 | 1146 | |
jrodenburg | 21:f87464a7e7c6 | 1147 | //Check if the fixture has not reached SP in X amount of time |
jrodenburg | 21:f87464a7e7c6 | 1148 | errorFlag = false; |
jrodenburg | 21:f87464a7e7c6 | 1149 | if(!reachedSP && (timeToSP == MAX_TIME_TO_SP)) errorFlag = true; |
jrodenburg | 21:f87464a7e7c6 | 1150 | errorCheck(chan, errorFlag, ERR_SP_TIME); |
jrodenburg | 21:f87464a7e7c6 | 1151 | |
jrodenburg | 21:f87464a7e7c6 | 1152 | } |
jrodenburg | 20:cdeed4dad690 | 1153 | } |
jrodenburg | 20:cdeed4dad690 | 1154 | |
jrodenburg | 6:c980535393ed | 1155 | /*************************************************************/ |
jrodenburg | 20:cdeed4dad690 | 1156 | /* NEW MAIN FUNCTION */ |
jrodenburg | 6:c980535393ed | 1157 | /*************************************************************/ |
jrodenburg | 0:a28a1035c31b | 1158 | |
jrodenburg | 20:cdeed4dad690 | 1159 | int main(){ |
jrodenburg | 20:cdeed4dad690 | 1160 | /* INITIALIZATION CODE */ |
jrodenburg | 8:dbf8bd4815f8 | 1161 | // Setup serial port |
jrodenburg | 8:dbf8bd4815f8 | 1162 | // Look for RX_EOF |
jrodenburg | 20:cdeed4dad690 | 1163 | uint32_t UIDMH, UIDML, UIDL; |
jrodenburg | 20:cdeed4dad690 | 1164 | int UID_print_count = 0; |
jrodenburg | 21:f87464a7e7c6 | 1165 | //resetErrorCount(); |
jrodenburg | 20:cdeed4dad690 | 1166 | |
jrodenburg | 20:cdeed4dad690 | 1167 | |
jrodenburg | 20:cdeed4dad690 | 1168 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1169 | // Initial thermistors readings |
jrodenburg | 21:f87464a7e7c6 | 1170 | // Kick of SP time updates |
jrodenburg | 21:f87464a7e7c6 | 1171 | // Kick off temperature reading |
jrodenburg | 20:cdeed4dad690 | 1172 | // state machine |
jrodenburg | 20:cdeed4dad690 | 1173 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1174 | readThermistorTicker.attach(&read_front_temp_data, .0001); |
jrodenburg | 21:f87464a7e7c6 | 1175 | //setPointTimeTicker.attach(&SP_Time_Check, 60); |
jrodenburg | 20:cdeed4dad690 | 1176 | |
jrodenburg | 8:dbf8bd4815f8 | 1177 | pc.baud(9600); |
jrodenburg | 8:dbf8bd4815f8 | 1178 | pc.autoDetectChar(RX_EOF); |
jrodenburg | 8:dbf8bd4815f8 | 1179 | pc.attach(&rxInterrupt, MODSERIAL::RxAutoDetect); |
jrodenburg | 8:dbf8bd4815f8 | 1180 | |
jrodenburg | 15:74a01aaeb60e | 1181 | UIDMH = (uint32_t)SIM->UIDMH; |
jrodenburg | 15:74a01aaeb60e | 1182 | UIDML = (uint32_t)SIM->UIDML; |
jrodenburg | 15:74a01aaeb60e | 1183 | UIDL = (uint32_t)SIM->UIDL; |
jrodenburg | 15:74a01aaeb60e | 1184 | |
jrodenburg | 20:cdeed4dad690 | 1185 | //print UID three times on start-up to ID Mbed board |
jrodenburg | 20:cdeed4dad690 | 1186 | if(UID_print_count++ < 3) |
jrodenburg | 20:cdeed4dad690 | 1187 | pc.printf("DBG: [UID: %04X%08X%08X]\n", UIDMH, UIDML, UIDL); |
jrodenburg | 20:cdeed4dad690 | 1188 | |
jrodenburg | 18:aaec99ca68c3 | 1189 | |
jrodenburg | 0:a28a1035c31b | 1190 | while(1) { |
jrodenburg | 20:cdeed4dad690 | 1191 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1192 | // Process Rx UART data from GUI |
jrodenburg | 20:cdeed4dad690 | 1193 | //********************************* |
jrodenburg | 21:f87464a7e7c6 | 1194 | //pc.printf("LOOP \r\n"); |
jrodenburg | 20:cdeed4dad690 | 1195 | if (dataReceived) |
jrodenburg | 20:cdeed4dad690 | 1196 | { |
jrodenburg | 20:cdeed4dad690 | 1197 | dataReceived = false; |
jrodenburg | 20:cdeed4dad690 | 1198 | if (debug_control & RXDATA_PRINT) |
jrodenburg | 20:cdeed4dad690 | 1199 | pc.printf("DBG: %d bytes Rx'd\n", pc.rxBufferGetCount()); |
jrodenburg | 14:69cd53434783 | 1200 | |
jrodenburg | 20:cdeed4dad690 | 1201 | pc.move(rxBuf, 50); |
jrodenburg | 20:cdeed4dad690 | 1202 | processRxUARTData(); |
jrodenburg | 20:cdeed4dad690 | 1203 | pc.rxBufferFlush(); |
jrodenburg | 13:604e6933366f | 1204 | } |
jrodenburg | 14:69cd53434783 | 1205 | |
jrodenburg | 20:cdeed4dad690 | 1206 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1207 | // Logic Loop |
jrodenburg | 20:cdeed4dad690 | 1208 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1209 | // System Logic/Control |
jrodenburg | 20:cdeed4dad690 | 1210 | if (newTempDataAvailable) |
jrodenburg | 20:cdeed4dad690 | 1211 | systemLogic(); |
jrodenburg | 12:1cada1fe4743 | 1212 | |
jrodenburg | 20:cdeed4dad690 | 1213 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1214 | // System Diagnostic & Error Check |
jrodenburg | 20:cdeed4dad690 | 1215 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1216 | systemDiagnostic(); |
jrodenburg | 12:1cada1fe4743 | 1217 | |
jrodenburg | 20:cdeed4dad690 | 1218 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1219 | // Process Tx UART data |
jrodenburg | 20:cdeed4dad690 | 1220 | // Send Temperature Data/Error to GUI |
jrodenburg | 20:cdeed4dad690 | 1221 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1222 | if (newTempDataAvailable) |
jrodenburg | 20:cdeed4dad690 | 1223 | { |
jrodenburg | 20:cdeed4dad690 | 1224 | processTxUARTData(); |
jrodenburg | 20:cdeed4dad690 | 1225 | |
jrodenburg | 20:cdeed4dad690 | 1226 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1227 | //Actuate Loop |
jrodenburg | 20:cdeed4dad690 | 1228 | //********************************* |
jrodenburg | 20:cdeed4dad690 | 1229 | systemControl(); |
jrodenburg | 20:cdeed4dad690 | 1230 | newTempDataAvailable = false; |
jrodenburg | 2:bd118a724f03 | 1231 | } |
jrodenburg | 0:a28a1035c31b | 1232 | } |
jrodenburg | 21:f87464a7e7c6 | 1233 | } |