Aes encryption code

Dependencies:   Crypto USBDevice mbed

Fork of larada by MZJ

Committer:
elmbed
Date:
Tue Mar 08 20:38:38 2016 +0000
Revision:
3:cff2f80f0a42
Parent:
2:35e620097381
Child:
4:11520c01d65f
Added tip serial connection & ability to pause/restart treatment cycle.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stupid 0:aaf22a04f350 1 #include "mbed.h"
stupid 0:aaf22a04f350 2 #include "USBSerial.h"
stupid 0:aaf22a04f350 3 #include "IAP.h"
stupid 0:aaf22a04f350 4
elmbed 3:cff2f80f0a42 5 #define FAKE_HW
elmbed 3:cff2f80f0a42 6
elmbed 3:cff2f80f0a42 7 #define SERIAL //comment for USB operation, uncomment for serial
stupid 0:aaf22a04f350 8 #define CALIBRATE 0
stupid 0:aaf22a04f350 9 #define FUNCTION_CHECK 0
stupid 0:aaf22a04f350 10
stupid 1:ccb26dd9845a 11 // debounce duration for ON/OFF switch
stupid 1:ccb26dd9845a 12 #define ON_OFF_DEBOUNCE 3000
stupid 1:ccb26dd9845a 13
stupid 0:aaf22a04f350 14 // longest user command we will accept
stupid 0:aaf22a04f350 15 #define MAX_COMMAND_LEN 64
stupid 0:aaf22a04f350 16
stupid 0:aaf22a04f350 17 // where to start reading stored values from the EEPROM
stupid 0:aaf22a04f350 18 #define BASE_ADDRESS 1
stupid 0:aaf22a04f350 19
stupid 1:ccb26dd9845a 20 // temperature control stuff //
stupid 0:aaf22a04f350 21 // fixed values
stupid 0:aaf22a04f350 22 #define CONTROL_INTERRUPT 1000 // every 1ms
stupid 0:aaf22a04f350 23 #define MAX_DUTY 100 // This is both the number of times the heater_control interrupt will run per control period and the max amount of interrupts the heater triac can be on.
stupid 0:aaf22a04f350 24
stupid 0:aaf22a04f350 25 // adjustable values
stupid 0:aaf22a04f350 26 #define DEFAULT_FILTER 0.05 // first order digital filter parameter, should be [0.0 - 1]. less means filter more, a value of 1 should turn it off
stupid 0:aaf22a04f350 27 //#define INITIAL_DUTY 25 // 25% duty generally results in a few degrees under 57C output for the ambient temperatures I've been testing at
stupid 0:aaf22a04f350 28 #define DEFAULT_INITIAL_DUTY 45
stupid 1:ccb26dd9845a 29 #define DEFAULT_NOMINAL_DUTY 28 // 11% duty is a good set point for Beta init (testing at 20C ambient)
stupid 0:aaf22a04f350 30 //#define SETPOINT 435 // this results in roughly 57C at the tines on the Alphas (really 53)
stupid 1:ccb26dd9845a 31 #define DEFAULT_SETPOINT 58 //seems like there is a ~4C temperature drop between the sensor and the outside of the tips
stupid 0:aaf22a04f350 32 #define DEFAULT_TOLERANCE 2 // if we are within this many ADC counts of the setpoint don't make any changes to the duty cycle
stupid 0:aaf22a04f350 33 //#define DUTY_TOO_LARGE 40 // If the duty gets larger than this we have problems (Alphas)
stupid 0:aaf22a04f350 34 #define DEFAULT_DUTY_TOO_LARGE 70 // If the duty gets larger than this we have problems (Betas) -> 65 duty should result in roughly 62C tip temps
stupid 0:aaf22a04f350 35 //#define DUTY_TOO_LARGE 85 // For testing
stupid 1:ccb26dd9845a 36 #define DEFAULT_TEMP_LIMIT_LOWER 12 // If the temperature measures too low during operation we are either doing a bad job or have a faulty temperature sensor
stupid 1:ccb26dd9845a 37 //#define DEFAULT_TEMP_LIMIT_LOWER 0 // For testing
stupid 0:aaf22a04f350 38 //#define TEMP_LIMIT_UPPER 485 // No burning allowed (Alphas)
stupid 1:ccb26dd9845a 39 #define DEFAULT_TEMP_LIMIT_UPPER 65 // No burning allowed (Betas)
stupid 0:aaf22a04f350 40
elmbed 3:cff2f80f0a42 41 #define CRYPT_BUFF_SZ 16
elmbed 3:cff2f80f0a42 42 #define BYTES_PER_100_MS 8 // the number of bytes to send per 100 ms
elmbed 3:cff2f80f0a42 43 #define TIP_UPDATE_INTERVAL_S 3 // Update the tip remaining time every x seconds
elmbed 3:cff2f80f0a42 44
stupid 0:aaf22a04f350 45 float filter = DEFAULT_FILTER;
stupid 0:aaf22a04f350 46 uint8_t initial_duty = DEFAULT_INITIAL_DUTY;
stupid 0:aaf22a04f350 47 uint8_t nominal_duty = DEFAULT_NOMINAL_DUTY;
stupid 0:aaf22a04f350 48 uint16_t setpoint = DEFAULT_SETPOINT;
stupid 0:aaf22a04f350 49 uint8_t tolerance = DEFAULT_TOLERANCE;
stupid 0:aaf22a04f350 50 uint8_t duty_too_large = DEFAULT_DUTY_TOO_LARGE;
stupid 0:aaf22a04f350 51 uint16_t temp_limit_lower = DEFAULT_TEMP_LIMIT_LOWER;
stupid 0:aaf22a04f350 52 uint16_t temp_limit_upper = DEFAULT_TEMP_LIMIT_UPPER;
stupid 0:aaf22a04f350 53
stupid 0:aaf22a04f350 54 enum State {
stupid 0:aaf22a04f350 55 IDLE,
stupid 0:aaf22a04f350 56 WAIT_FOR_TIP,
elmbed 3:cff2f80f0a42 57 GET_TIP_CONFIG,
stupid 0:aaf22a04f350 58 INITIAL_RAMP,
stupid 0:aaf22a04f350 59 ACTIVE,
stupid 1:ccb26dd9845a 60 DONE,
elmbed 3:cff2f80f0a42 61 PAUSED,
stupid 0:aaf22a04f350 62 ERROR,
stupid 0:aaf22a04f350 63 };
stupid 0:aaf22a04f350 64
stupid 0:aaf22a04f350 65 enum Heater_State {
stupid 0:aaf22a04f350 66 ON,
stupid 0:aaf22a04f350 67 OFF,
stupid 0:aaf22a04f350 68 };
stupid 0:aaf22a04f350 69
stupid 0:aaf22a04f350 70 // not used yet
stupid 0:aaf22a04f350 71 enum Error {
stupid 0:aaf22a04f350 72 NONE,
stupid 0:aaf22a04f350 73 TEMP_TOO_LOW,
stupid 0:aaf22a04f350 74 TEMP_TOO_HIGH,
stupid 0:aaf22a04f350 75 DUTY_TOO_LARGE,
stupid 0:aaf22a04f350 76 };
stupid 0:aaf22a04f350 77
elmbed 3:cff2f80f0a42 78 enum
elmbed 3:cff2f80f0a42 79 {
elmbed 3:cff2f80f0a42 80 READ_TIME_REMAINING=1,
elmbed 3:cff2f80f0a42 81 WRITE_TIME_REMAINING,
elmbed 3:cff2f80f0a42 82 RESET_BUFFER // This is a local command, resets the rx buffer
elmbed 3:cff2f80f0a42 83 }tip_command;
elmbed 3:cff2f80f0a42 84
elmbed 3:cff2f80f0a42 85 struct tip_message
elmbed 3:cff2f80f0a42 86 {
elmbed 3:cff2f80f0a42 87 int command __attribute__((packed));
elmbed 3:cff2f80f0a42 88 long value __attribute__((packed));
elmbed 3:cff2f80f0a42 89 };
elmbed 3:cff2f80f0a42 90
stupid 0:aaf22a04f350 91 // Heater control pins
stupid 0:aaf22a04f350 92 DigitalOut fan(P0_22);
stupid 0:aaf22a04f350 93 DigitalOut heater_pin(P1_27);
stupid 0:aaf22a04f350 94 AnalogIn temp_sense(P0_16);
stupid 0:aaf22a04f350 95
stupid 0:aaf22a04f350 96 // LED pins
stupid 0:aaf22a04f350 97 DigitalInOut empty_led(P0_10);
stupid 0:aaf22a04f350 98 DigitalInOut fuel_gage_1(P0_9);
stupid 0:aaf22a04f350 99 DigitalInOut fuel_gage_2(P0_8);
stupid 0:aaf22a04f350 100 DigitalInOut fuel_gage_3(P1_21);
stupid 0:aaf22a04f350 101 DigitalInOut fuel_gage_4(P1_31);
stupid 0:aaf22a04f350 102 DigitalOut tip_light(P1_14);
stupid 0:aaf22a04f350 103
stupid 1:ccb26dd9845a 104 // Other pins
elmbed 3:cff2f80f0a42 105 #ifdef FAKE_HW
elmbed 3:cff2f80f0a42 106 bool tip_sensor = false;
elmbed 3:cff2f80f0a42 107 bool on_off = false;
elmbed 3:cff2f80f0a42 108 #else
stupid 0:aaf22a04f350 109 DigitalIn tip_sensor(P0_14);
stupid 1:ccb26dd9845a 110 DigitalIn on_off(P1_28);
elmbed 3:cff2f80f0a42 111 #endif
stupid 0:aaf22a04f350 112
stupid 0:aaf22a04f350 113 #define ON_TIME_S 2700L // The device is active for 45 minutes
stupid 0:aaf22a04f350 114 //#define ON_TIME_S 150L
stupid 0:aaf22a04f350 115 #define RED_LED_ON_TIME_S 300L // The red LED is active for the last 5 minutes
stupid 0:aaf22a04f350 116 //#define RED_LED_ON_TIME_S 30L
stupid 1:ccb26dd9845a 117 #define TIP_FLASH_INTERVAL_S 25L // How often the tip will flash
stupid 0:aaf22a04f350 118 //Serial pc(0x1f00, 0x2012, 0x0001, false);
stupid 0:aaf22a04f350 119
stupid 0:aaf22a04f350 120 #ifdef SERIAL
stupid 0:aaf22a04f350 121 Serial pc(P0_19, P0_18); // tx, rx
stupid 0:aaf22a04f350 122 #else
stupid 0:aaf22a04f350 123 USBSerial pc(0x1f00, 0x2012, 0x0001);
stupid 0:aaf22a04f350 124 #endif
stupid 0:aaf22a04f350 125
stupid 0:aaf22a04f350 126 Ticker control_interrupt;
stupid 0:aaf22a04f350 127 Ticker check_limits_interrupt;
stupid 0:aaf22a04f350 128 Ticker temperature_interrupt;
stupid 0:aaf22a04f350 129 Ticker tick_interrupt;
stupid 0:aaf22a04f350 130
stupid 0:aaf22a04f350 131 volatile Heater_State heater = OFF;
stupid 1:ccb26dd9845a 132 volatile State state = IDLE;
stupid 0:aaf22a04f350 133 volatile Error error_state = NONE;
stupid 0:aaf22a04f350 134
stupid 0:aaf22a04f350 135 volatile uint8_t duty = DEFAULT_INITIAL_DUTY;
stupid 0:aaf22a04f350 136 volatile float temperature = 0.0;
stupid 0:aaf22a04f350 137 unsigned long start_time = 0L;
stupid 0:aaf22a04f350 138 unsigned long current_time = 0L;
elmbed 3:cff2f80f0a42 139 uint32_t tip_start_value_s = 0L; // The number of seconds remaing on the tip at the start of the cycle
elmbed 3:cff2f80f0a42 140 uint32_t current_cycle_on_time_s = 0; // The number of seconds this cycle has been operational
elmbed 3:cff2f80f0a42 141 uint32_t last_serial_send = 0;
stupid 0:aaf22a04f350 142 bool connected = false;
stupid 0:aaf22a04f350 143 volatile uint32_t millis = 0;
stupid 0:aaf22a04f350 144
stupid 0:aaf22a04f350 145 void loop(void);
stupid 0:aaf22a04f350 146 void calibrate(bool first);
stupid 0:aaf22a04f350 147 void interpret(char parameter, int value);
stupid 0:aaf22a04f350 148 void spin_lights(bool first);
stupid 0:aaf22a04f350 149
elmbed 3:cff2f80f0a42 150 void do_get_tip_config(bool first);
elmbed 3:cff2f80f0a42 151 bool get_message_from_tip(struct tip_message *tm);
elmbed 3:cff2f80f0a42 152
elmbed 3:cff2f80f0a42 153
stupid 1:ccb26dd9845a 154 //INTERRUPT - increment this every ms since the normal mbed timer returns an int and we need an unsigned type
stupid 0:aaf22a04f350 155 void tick(void) {millis++;}
stupid 0:aaf22a04f350 156
stupid 0:aaf22a04f350 157 uint32_t get_time(void){
stupid 0:aaf22a04f350 158 uint32_t copy = 0;
stupid 0:aaf22a04f350 159 __disable_irq();
stupid 0:aaf22a04f350 160 copy = millis;
stupid 0:aaf22a04f350 161 __enable_irq();
stupid 0:aaf22a04f350 162 return copy;
stupid 0:aaf22a04f350 163 }
stupid 0:aaf22a04f350 164
stupid 0:aaf22a04f350 165 uint8_t get_duty(void){
stupid 0:aaf22a04f350 166 __disable_irq();
stupid 0:aaf22a04f350 167 uint8_t duty_copy = duty;
stupid 0:aaf22a04f350 168 __enable_irq();
stupid 0:aaf22a04f350 169 return duty_copy;
stupid 0:aaf22a04f350 170 }
stupid 0:aaf22a04f350 171
stupid 0:aaf22a04f350 172 void set_duty(uint8_t new_duty){
stupid 0:aaf22a04f350 173 __disable_irq();
stupid 0:aaf22a04f350 174 duty = new_duty;
stupid 0:aaf22a04f350 175 __enable_irq();
stupid 0:aaf22a04f350 176 }
stupid 0:aaf22a04f350 177
stupid 0:aaf22a04f350 178 float get_temperature(void){
stupid 0:aaf22a04f350 179 __disable_irq();
stupid 0:aaf22a04f350 180 float temperature_copy = temperature;
stupid 0:aaf22a04f350 181 __enable_irq();
elmbed 3:cff2f80f0a42 182
elmbed 3:cff2f80f0a42 183 #ifdef FAKE_HW
elmbed 3:cff2f80f0a42 184 return setpoint;
elmbed 3:cff2f80f0a42 185 #else
stupid 0:aaf22a04f350 186 return temperature_copy;
elmbed 3:cff2f80f0a42 187 #endif
elmbed 3:cff2f80f0a42 188 }
elmbed 3:cff2f80f0a42 189
elmbed 3:cff2f80f0a42 190 /**
elmbed 3:cff2f80f0a42 191 * Packs the message into a string whic can be sent.
elmbed 3:cff2f80f0a42 192 *
elmbed 3:cff2f80f0a42 193 * @param *buff - buffer to populate
elmbed 3:cff2f80f0a42 194 * @param buff_sz - the size of the output buffer
elmbed 3:cff2f80f0a42 195 * @param *tm - the message to convert into a string
elmbed 3:cff2f80f0a42 196 */
elmbed 3:cff2f80f0a42 197 bool pack_message(char *buff, int buff_sz, struct tip_message *tm)
elmbed 3:cff2f80f0a42 198 {
elmbed 3:cff2f80f0a42 199 memset(buff, 0x00, buff_sz);
elmbed 3:cff2f80f0a42 200
elmbed 3:cff2f80f0a42 201 if (buff_sz != CRYPT_BUFF_SZ)
elmbed 3:cff2f80f0a42 202 {
elmbed 3:cff2f80f0a42 203 return false;
elmbed 3:cff2f80f0a42 204 }
elmbed 3:cff2f80f0a42 205
elmbed 3:cff2f80f0a42 206 snprintf(buff, buff_sz, "%d:%ld\r\n", tm->command, tm->value);
elmbed 3:cff2f80f0a42 207
elmbed 3:cff2f80f0a42 208 return true;
elmbed 3:cff2f80f0a42 209 }
elmbed 3:cff2f80f0a42 210
elmbed 3:cff2f80f0a42 211 /**
elmbed 3:cff2f80f0a42 212 * Waits 100ms from the last send.
elmbed 3:cff2f80f0a42 213 *
elmbed 3:cff2f80f0a42 214 * @param last_send - time of last 8 byte send
elmbed 3:cff2f80f0a42 215 */
elmbed 3:cff2f80f0a42 216 void wait_until_can_send_tip_message(uint32_t last_send)
elmbed 3:cff2f80f0a42 217 {
elmbed 3:cff2f80f0a42 218 uint32_t counter = 0;
elmbed 3:cff2f80f0a42 219
elmbed 3:cff2f80f0a42 220 while (get_time() - last_send < 100)
elmbed 3:cff2f80f0a42 221 {
elmbed 3:cff2f80f0a42 222 wait_ms(1);
elmbed 3:cff2f80f0a42 223 ++counter;
elmbed 3:cff2f80f0a42 224 }
elmbed 3:cff2f80f0a42 225 }
elmbed 3:cff2f80f0a42 226
elmbed 3:cff2f80f0a42 227 /**
elmbed 3:cff2f80f0a42 228 * Sends a message to the tip. This accounts for the
elmbed 3:cff2f80f0a42 229 * max number of bytes which can be sent per 100ms.
elmbed 3:cff2f80f0a42 230 *
elmbed 3:cff2f80f0a42 231 * @param *tm - the message to send
elmbed 3:cff2f80f0a42 232 * @returns true if sent successfully
elmbed 3:cff2f80f0a42 233 */
elmbed 3:cff2f80f0a42 234 bool send_message_to_tip(struct tip_message *tm)
elmbed 3:cff2f80f0a42 235 {
elmbed 3:cff2f80f0a42 236 static char buff[CRYPT_BUFF_SZ] = {0};
elmbed 3:cff2f80f0a42 237 static char send_buff[BYTES_PER_100_MS + 1] = {0};
elmbed 3:cff2f80f0a42 238 static uint32_t last_send = 0;
elmbed 3:cff2f80f0a42 239
elmbed 3:cff2f80f0a42 240 int bytes_sent = 0;
elmbed 3:cff2f80f0a42 241
elmbed 3:cff2f80f0a42 242 pack_message(buff, sizeof(buff), tm);
elmbed 3:cff2f80f0a42 243
elmbed 3:cff2f80f0a42 244 bytes_sent = 0;
elmbed 3:cff2f80f0a42 245
elmbed 3:cff2f80f0a42 246 wait_until_can_send_tip_message(last_send);
elmbed 3:cff2f80f0a42 247
elmbed 3:cff2f80f0a42 248 if (tm->command == RESET_BUFFER)
elmbed 3:cff2f80f0a42 249 {
elmbed 3:cff2f80f0a42 250 pc.printf("\r\n");
elmbed 3:cff2f80f0a42 251 return true;
elmbed 3:cff2f80f0a42 252 }
elmbed 3:cff2f80f0a42 253
elmbed 3:cff2f80f0a42 254 if (strlen(buff) > BYTES_PER_100_MS)
elmbed 3:cff2f80f0a42 255 {
elmbed 3:cff2f80f0a42 256 memcpy(send_buff, buff, BYTES_PER_100_MS);
elmbed 3:cff2f80f0a42 257
elmbed 3:cff2f80f0a42 258 pc.printf("!%s", send_buff);
elmbed 3:cff2f80f0a42 259 bytes_sent = BYTES_PER_100_MS;
elmbed 3:cff2f80f0a42 260 last_send = get_time();
elmbed 3:cff2f80f0a42 261
elmbed 3:cff2f80f0a42 262 while (bytes_sent < strlen(buff))
elmbed 3:cff2f80f0a42 263 {
elmbed 3:cff2f80f0a42 264 wait_until_can_send_tip_message(last_send);
elmbed 3:cff2f80f0a42 265
elmbed 3:cff2f80f0a42 266 memcpy(send_buff, buff+bytes_sent, BYTES_PER_100_MS);
elmbed 3:cff2f80f0a42 267 pc.printf("%s", send_buff);
elmbed 3:cff2f80f0a42 268 bytes_sent = BYTES_PER_100_MS;
elmbed 3:cff2f80f0a42 269 last_send = get_time();
elmbed 3:cff2f80f0a42 270 }
elmbed 3:cff2f80f0a42 271 }
elmbed 3:cff2f80f0a42 272 else
elmbed 3:cff2f80f0a42 273 {
elmbed 3:cff2f80f0a42 274 pc.printf("!%s", buff);
elmbed 3:cff2f80f0a42 275 last_send = get_time();
elmbed 3:cff2f80f0a42 276 }
elmbed 3:cff2f80f0a42 277
elmbed 3:cff2f80f0a42 278 last_serial_send = get_time();
elmbed 3:cff2f80f0a42 279
elmbed 3:cff2f80f0a42 280 return true;
elmbed 3:cff2f80f0a42 281 }
elmbed 3:cff2f80f0a42 282
elmbed 3:cff2f80f0a42 283 /**
elmbed 3:cff2f80f0a42 284 * Reads a message from the tip and populates the
elmbed 3:cff2f80f0a42 285 * struct given.
elmbed 3:cff2f80f0a42 286 *
elmbed 3:cff2f80f0a42 287 * @param *tm - storage for message
elmbed 3:cff2f80f0a42 288 * @returns true when message read, else false
elmbed 3:cff2f80f0a42 289 */
elmbed 3:cff2f80f0a42 290 bool get_message_from_tip(struct tip_message *tm)
elmbed 3:cff2f80f0a42 291 {
elmbed 3:cff2f80f0a42 292 static char buff[CRYPT_BUFF_SZ] = {0};
elmbed 3:cff2f80f0a42 293 static int pos = 0;
elmbed 3:cff2f80f0a42 294 bool rval = false;
elmbed 3:cff2f80f0a42 295
elmbed 3:cff2f80f0a42 296 if (tm->command == RESET_BUFFER)
elmbed 3:cff2f80f0a42 297 {
elmbed 3:cff2f80f0a42 298 memset(buff, 0x00, sizeof(buff));
elmbed 3:cff2f80f0a42 299 pos = 0;
elmbed 3:cff2f80f0a42 300
elmbed 3:cff2f80f0a42 301 return false;
elmbed 3:cff2f80f0a42 302 }
elmbed 3:cff2f80f0a42 303
elmbed 3:cff2f80f0a42 304 while (pc.readable())
elmbed 3:cff2f80f0a42 305 {
elmbed 3:cff2f80f0a42 306 char t = pc.getc();
elmbed 3:cff2f80f0a42 307
elmbed 3:cff2f80f0a42 308 if (get_time() - last_serial_send < 100)
elmbed 3:cff2f80f0a42 309 {
elmbed 3:cff2f80f0a42 310 continue; // Ignore for 100ms
elmbed 3:cff2f80f0a42 311 }
elmbed 3:cff2f80f0a42 312
elmbed 3:cff2f80f0a42 313 if (t == '\r' || t == '\n')
elmbed 3:cff2f80f0a42 314 {
elmbed 3:cff2f80f0a42 315 if (pos >= 4 && buff[0] == '!')
elmbed 3:cff2f80f0a42 316 {
elmbed 3:cff2f80f0a42 317 tm->command = (int)(buff[1]-'0');
elmbed 3:cff2f80f0a42 318 tm->value = atol(buff+3);
elmbed 3:cff2f80f0a42 319 rval = true;
elmbed 3:cff2f80f0a42 320
elmbed 3:cff2f80f0a42 321 break;
elmbed 3:cff2f80f0a42 322 }
elmbed 3:cff2f80f0a42 323
elmbed 3:cff2f80f0a42 324 pos = 0;
elmbed 3:cff2f80f0a42 325 memset(buff, 0x00, sizeof(buff));
elmbed 3:cff2f80f0a42 326 }
elmbed 3:cff2f80f0a42 327 else
elmbed 3:cff2f80f0a42 328 {
elmbed 3:cff2f80f0a42 329 if (pos > sizeof(buff))
elmbed 3:cff2f80f0a42 330 {
elmbed 3:cff2f80f0a42 331 pos = 0;
elmbed 3:cff2f80f0a42 332 }
elmbed 3:cff2f80f0a42 333
elmbed 3:cff2f80f0a42 334 buff[pos++] = t;
elmbed 3:cff2f80f0a42 335 }
elmbed 3:cff2f80f0a42 336 }
elmbed 3:cff2f80f0a42 337
elmbed 3:cff2f80f0a42 338 if (rval)
elmbed 3:cff2f80f0a42 339 {
elmbed 3:cff2f80f0a42 340 pos = 0;
elmbed 3:cff2f80f0a42 341 memset(buff, 0x00, sizeof(buff));
elmbed 3:cff2f80f0a42 342 }
elmbed 3:cff2f80f0a42 343
elmbed 3:cff2f80f0a42 344 return rval;
stupid 0:aaf22a04f350 345 }
stupid 0:aaf22a04f350 346
stupid 0:aaf22a04f350 347 //pull the settings saved to flash into memory
stupid 0:aaf22a04f350 348 void read_settings(void){
stupid 0:aaf22a04f350 349 uint8_t address = BASE_ADDRESS;
stupid 0:aaf22a04f350 350 uint16_t filter_temp = 0;
stupid 0:aaf22a04f350 351
stupid 0:aaf22a04f350 352 IAP iap;
stupid 0:aaf22a04f350 353
stupid 0:aaf22a04f350 354 iap.read_eeprom((char*)address, (char*)&filter_temp, sizeof(filter_temp));
stupid 0:aaf22a04f350 355 address += sizeof(filter_temp);
stupid 0:aaf22a04f350 356 filter = (float)filter_temp/100;
stupid 0:aaf22a04f350 357 iap.read_eeprom((char*)address, (char*)&initial_duty, sizeof(initial_duty));
stupid 0:aaf22a04f350 358 address += sizeof(initial_duty);
stupid 0:aaf22a04f350 359 iap.read_eeprom((char*)address, (char*)&setpoint, sizeof(setpoint));
stupid 0:aaf22a04f350 360 address += sizeof(setpoint);
stupid 0:aaf22a04f350 361 iap.read_eeprom((char*)address, (char*)&tolerance, sizeof(tolerance));
stupid 0:aaf22a04f350 362 address += sizeof(tolerance);
stupid 0:aaf22a04f350 363 iap.read_eeprom((char*)address, (char*)&duty_too_large, sizeof(duty_too_large));
stupid 0:aaf22a04f350 364 address += sizeof(duty_too_large);
stupid 0:aaf22a04f350 365 iap.read_eeprom((char*)address, (char*)&temp_limit_lower, sizeof(temp_limit_lower));
stupid 0:aaf22a04f350 366 address += sizeof(temp_limit_lower);
stupid 0:aaf22a04f350 367 iap.read_eeprom((char*)address, (char*)&temp_limit_upper, sizeof(temp_limit_upper));
stupid 0:aaf22a04f350 368 address += sizeof(temp_limit_upper);
stupid 0:aaf22a04f350 369 iap.read_eeprom((char*)address, (char*)&nominal_duty, sizeof(nominal_duty));
stupid 0:aaf22a04f350 370 address += sizeof(nominal_duty);
stupid 0:aaf22a04f350 371 }
stupid 0:aaf22a04f350 372
stupid 0:aaf22a04f350 373 //write settings to persistent memory
stupid 0:aaf22a04f350 374 void write_settings(void){
stupid 0:aaf22a04f350 375 IAP iap;
stupid 0:aaf22a04f350 376 uint8_t address = 1; //BASE_ADDRESS;
stupid 0:aaf22a04f350 377 uint16_t filter_temp = 0;
stupid 0:aaf22a04f350 378
stupid 0:aaf22a04f350 379 filter_temp = (int)(filter*100);
stupid 0:aaf22a04f350 380
stupid 0:aaf22a04f350 381 iap.write_eeprom((char*)&filter_temp, (char*)address, sizeof(filter_temp));
stupid 0:aaf22a04f350 382 address += sizeof(filter_temp);
stupid 0:aaf22a04f350 383 iap.write_eeprom((char*)&initial_duty, (char*)address, sizeof(initial_duty));
stupid 0:aaf22a04f350 384 address += sizeof(initial_duty);
stupid 0:aaf22a04f350 385 iap.write_eeprom((char*)&setpoint, (char*)address, sizeof(setpoint));
stupid 0:aaf22a04f350 386 address += sizeof(setpoint);
stupid 0:aaf22a04f350 387 iap.write_eeprom((char*)&tolerance, (char*)address, sizeof(tolerance));
stupid 0:aaf22a04f350 388 address += sizeof(tolerance);
stupid 0:aaf22a04f350 389 iap.write_eeprom((char*)&duty_too_large, (char*)address, sizeof(duty_too_large));
stupid 0:aaf22a04f350 390 address += sizeof(duty_too_large);
stupid 0:aaf22a04f350 391 iap.write_eeprom((char*)&temp_limit_lower, (char*)address, sizeof(temp_limit_lower));
stupid 0:aaf22a04f350 392 address += sizeof(temp_limit_lower);
stupid 0:aaf22a04f350 393 iap.write_eeprom((char*)&temp_limit_upper, (char*)address, sizeof(temp_limit_upper));
stupid 0:aaf22a04f350 394 address += sizeof(temp_limit_upper);
stupid 0:aaf22a04f350 395 iap.write_eeprom((char*)&nominal_duty, (char*)address, sizeof(nominal_duty));
stupid 0:aaf22a04f350 396 address += sizeof(nominal_duty);
stupid 0:aaf22a04f350 397 }
stupid 0:aaf22a04f350 398
stupid 0:aaf22a04f350 399 //parse commands. commands take the form of a character followed by a number, delimited by "\r|\n|;"
stupid 0:aaf22a04f350 400 void getInput(void){
stupid 0:aaf22a04f350 401 static int i = 0;
stupid 0:aaf22a04f350 402 static char parameter = '_';
stupid 0:aaf22a04f350 403 static char buffer[MAX_COMMAND_LEN + 1];
stupid 0:aaf22a04f350 404 int value = 0;
stupid 0:aaf22a04f350 405 //char *endp = NULL;
stupid 0:aaf22a04f350 406
stupid 0:aaf22a04f350 407 if(!connected) return;
stupid 0:aaf22a04f350 408
stupid 0:aaf22a04f350 409 // listen for commands coming in
stupid 0:aaf22a04f350 410 #ifdef SERIAL
stupid 0:aaf22a04f350 411 while (pc.readable()){
stupid 0:aaf22a04f350 412 char ch = pc.getc();
stupid 0:aaf22a04f350 413 #else
stupid 0:aaf22a04f350 414 while (pc.available()){
stupid 0:aaf22a04f350 415 char ch = pc._getc();
stupid 0:aaf22a04f350 416 #endif
stupid 0:aaf22a04f350 417 if((ch == '\r' || ch == ';' || ch == '\n') && parameter != '_'){
stupid 0:aaf22a04f350 418 if(i > 1){
stupid 0:aaf22a04f350 419 buffer[i-1] = 0;
stupid 0:aaf22a04f350 420 value = atoi(buffer);
stupid 0:aaf22a04f350 421 }
elmbed 3:cff2f80f0a42 422
stupid 0:aaf22a04f350 423 //Serial.println("not _");
stupid 0:aaf22a04f350 424 interpret(parameter, value);
stupid 0:aaf22a04f350 425 parameter = '_';
stupid 0:aaf22a04f350 426 buffer[0] = 0;
stupid 0:aaf22a04f350 427 i=0;
stupid 0:aaf22a04f350 428 break;
stupid 0:aaf22a04f350 429 }
stupid 0:aaf22a04f350 430 else{
stupid 0:aaf22a04f350 431 if(i==0) parameter = ch;
stupid 0:aaf22a04f350 432 else buffer[i-1] = ch;
stupid 0:aaf22a04f350 433 i++;
stupid 0:aaf22a04f350 434 }
stupid 0:aaf22a04f350 435
stupid 0:aaf22a04f350 436 if(ch == '_' || ch == '\r' || ch == ';' || ch == '\n'){
stupid 0:aaf22a04f350 437 parameter = '_';
stupid 0:aaf22a04f350 438 buffer[0] = 0;
stupid 0:aaf22a04f350 439 i=0;
stupid 0:aaf22a04f350 440 }
stupid 0:aaf22a04f350 441 }
stupid 0:aaf22a04f350 442 }
stupid 0:aaf22a04f350 443
stupid 0:aaf22a04f350 444 //print usage info
stupid 0:aaf22a04f350 445 void usage(void){
stupid 0:aaf22a04f350 446 if(!connected)return;
stupid 0:aaf22a04f350 447 pc.printf("\r\nCommands are a character followed by a number.\r\n");
stupid 0:aaf22a04f350 448 wait_ms(1);
stupid 0:aaf22a04f350 449 pc.printf("Available commands are:\r\n");
stupid 0:aaf22a04f350 450 wait_ms(1);
stupid 0:aaf22a04f350 451 pc.printf("'c': duty cap [1-100]\r\n");
stupid 0:aaf22a04f350 452 wait_ms(1);
stupid 0:aaf22a04f350 453 pc.printf("'d': set the initial duty used on startup [1-100]\r\n");
stupid 0:aaf22a04f350 454 wait_ms(1);
stupid 0:aaf22a04f350 455 pc.printf("'f': set the smoothing filter for the temperature sensor.");
stupid 0:aaf22a04f350 456 wait_ms(1);
stupid 0:aaf22a04f350 457 pc.printf(" smaller is more smoothing. [1-100]\r\n");
stupid 0:aaf22a04f350 458 wait_ms(1);
stupid 0:aaf22a04f350 459 pc.printf("'l': lower temperature limit. arbitrary units. [1-1000]\r\n");
stupid 0:aaf22a04f350 460 wait_ms(1);
stupid 0:aaf22a04f350 461 pc.printf("'r': reset all parameters to default values.\r\n");
stupid 0:aaf22a04f350 462 wait_ms(1);
stupid 0:aaf22a04f350 463 pc.printf("'n': set the nominal duty used on control cycle start [1-100]\r\n");
stupid 0:aaf22a04f350 464 wait_ms(1);
stupid 0:aaf22a04f350 465 pc.printf("'s': setpoint. same units as upper and lower temperature");
stupid 0:aaf22a04f350 466 wait_ms(1);
stupid 0:aaf22a04f350 467 pc.printf(" limit [1-1000]\r\n");
stupid 0:aaf22a04f350 468 wait_ms(1);
stupid 0:aaf22a04f350 469 pc.printf("'t': tolerance. no control action within this band. same ");
stupid 0:aaf22a04f350 470 wait_ms(1);
stupid 0:aaf22a04f350 471 pc.printf("units as upper and lower temperature limit [1-1000]\r\n");
stupid 0:aaf22a04f350 472 wait_ms(1);
stupid 0:aaf22a04f350 473 pc.printf("'u': upper temperature limit. arbitrary units. [1-1000]\r\n");
stupid 0:aaf22a04f350 474 wait_ms(1);
stupid 0:aaf22a04f350 475 pc.printf("'w': write the current control parameters to permanent memory\r\n");
stupid 0:aaf22a04f350 476 wait_ms(1);
stupid 0:aaf22a04f350 477 pc.printf("\r\n\r\n");
stupid 0:aaf22a04f350 478 wait_ms(1);
stupid 0:aaf22a04f350 479
stupid 0:aaf22a04f350 480 pc.printf("Values can be modified by entering a ");
stupid 0:aaf22a04f350 481 pc.printf("command followed by a number.");
stupid 0:aaf22a04f350 482 wait_ms(1);
stupid 0:aaf22a04f350 483 pc.printf(" For example, entering 'c50' <enter> would limit the duty");
stupid 0:aaf22a04f350 484 wait_ms(1);
stupid 0:aaf22a04f350 485 pc.printf(" to 50%\r\n\r\n");
stupid 0:aaf22a04f350 486 wait_ms(1);
stupid 0:aaf22a04f350 487
stupid 0:aaf22a04f350 488 pc.printf("Status of individual variables can be queried by entering ");
stupid 0:aaf22a04f350 489 wait_ms(1);
stupid 0:aaf22a04f350 490 pc.printf("that command name (no number afterwards), or typing any ");
stupid 0:aaf22a04f350 491 wait_ms(1);
stupid 0:aaf22a04f350 492 pc.printf("unrecognised command (which prints this message).\r\n\r\n");
stupid 0:aaf22a04f350 493 wait_ms(1);
stupid 0:aaf22a04f350 494 }
stupid 0:aaf22a04f350 495
stupid 0:aaf22a04f350 496 void print_active_settings(void){
stupid 0:aaf22a04f350 497 if(!connected)return;
stupid 0:aaf22a04f350 498 pc.printf("Duty capped at: %u%\r\n", duty_too_large);
stupid 0:aaf22a04f350 499 wait_ms(1);
stupid 0:aaf22a04f350 500 pc.printf("Initial duty is: %u\r\n", initial_duty);
stupid 0:aaf22a04f350 501 wait_ms(1);
stupid 0:aaf22a04f350 502 pc.printf("Nominal duty is: %u\r\n", nominal_duty);
stupid 0:aaf22a04f350 503 wait_ms(1);
stupid 0:aaf22a04f350 504 pc.printf("Temperature filter is: %d\r\n", (int)(filter * 100));
stupid 0:aaf22a04f350 505 wait_ms(1);
stupid 0:aaf22a04f350 506 pc.printf("Lower temperature limit is: %u\r\n", temp_limit_lower);
stupid 0:aaf22a04f350 507 wait_ms(1);
stupid 0:aaf22a04f350 508 pc.printf("Upper temperature limit is: %u\r\n", temp_limit_upper);
stupid 0:aaf22a04f350 509 wait_ms(1);
stupid 0:aaf22a04f350 510 pc.printf("Setpoint is: %u\r\n", setpoint);
stupid 0:aaf22a04f350 511 wait_ms(1);
stupid 0:aaf22a04f350 512 pc.printf("Tolerance is %u\r\n\r\n", tolerance);
stupid 0:aaf22a04f350 513 wait_ms(1);
stupid 2:35e620097381 514 //pc.printf("Spot treatment time is %d\r\n\r\n", TIP_FLASH_INTERVAL_S);
stupid 2:35e620097381 515 //wait_ms(1);
stupid 0:aaf22a04f350 516 }
stupid 0:aaf22a04f350 517
stupid 0:aaf22a04f350 518 //interpret a user command
stupid 0:aaf22a04f350 519 void interpret(char parameter, int value){
stupid 0:aaf22a04f350 520 switch(parameter){
stupid 0:aaf22a04f350 521 case 'c':
stupid 0:aaf22a04f350 522 if(value != 0) duty_too_large = value;
stupid 0:aaf22a04f350 523 pc.printf("Duty cap is %u\r\n", duty_too_large);
stupid 0:aaf22a04f350 524 break;
stupid 0:aaf22a04f350 525 case 'd':
stupid 0:aaf22a04f350 526 if(value != 0) initial_duty = value;
stupid 0:aaf22a04f350 527 pc.printf("Initial duty is %u\r\n", initial_duty);
stupid 0:aaf22a04f350 528 break;
stupid 0:aaf22a04f350 529 case 'f':
stupid 0:aaf22a04f350 530 if(value != 0) filter = ((float)value) / 100.0;
stupid 0:aaf22a04f350 531 pc.printf("Filter is %d\r\n", (int)(filter * 100));
stupid 0:aaf22a04f350 532 break;
stupid 0:aaf22a04f350 533 case 'r':
stupid 0:aaf22a04f350 534 filter = DEFAULT_FILTER;
stupid 0:aaf22a04f350 535 initial_duty = DEFAULT_INITIAL_DUTY;
stupid 0:aaf22a04f350 536 nominal_duty = DEFAULT_NOMINAL_DUTY;
stupid 0:aaf22a04f350 537 setpoint = DEFAULT_SETPOINT;
stupid 0:aaf22a04f350 538 tolerance = DEFAULT_TOLERANCE;
stupid 0:aaf22a04f350 539 duty_too_large = DEFAULT_DUTY_TOO_LARGE;
stupid 0:aaf22a04f350 540 temp_limit_lower = DEFAULT_TEMP_LIMIT_LOWER;
stupid 0:aaf22a04f350 541 temp_limit_upper = DEFAULT_TEMP_LIMIT_UPPER;
stupid 0:aaf22a04f350 542 write_settings();
stupid 0:aaf22a04f350 543 pc.printf("All parameters reset to default values:\r\n");
stupid 0:aaf22a04f350 544 print_active_settings();
stupid 0:aaf22a04f350 545 break;
stupid 0:aaf22a04f350 546 case 'l':
stupid 0:aaf22a04f350 547 if(value != 0) temp_limit_lower = value;
stupid 0:aaf22a04f350 548 pc.printf("Lower temperature limit is %u\r\n", temp_limit_lower);
stupid 0:aaf22a04f350 549 break;
stupid 0:aaf22a04f350 550 case 'n':
stupid 0:aaf22a04f350 551 if(value != 0) nominal_duty = value;
stupid 0:aaf22a04f350 552 pc.printf("Nominal duty is %u\r\n", nominal_duty);
stupid 0:aaf22a04f350 553 break;
stupid 0:aaf22a04f350 554 case 's':
stupid 0:aaf22a04f350 555 if(value != 0) setpoint = value;
stupid 0:aaf22a04f350 556 pc.printf("Setpoint is %u\r\n", setpoint);
stupid 0:aaf22a04f350 557 break;
stupid 0:aaf22a04f350 558 case 't':
stupid 0:aaf22a04f350 559 if(value != 0) tolerance = value;
stupid 0:aaf22a04f350 560 pc.printf("Tolerance is %u\r\n", tolerance);
stupid 0:aaf22a04f350 561 break;
stupid 0:aaf22a04f350 562 case 'u':
stupid 0:aaf22a04f350 563 if(value != 0) temp_limit_upper = value;
stupid 0:aaf22a04f350 564 pc.printf("Upper temperature limit is %u\r\n", temp_limit_upper);
stupid 0:aaf22a04f350 565 break;
stupid 0:aaf22a04f350 566 case 'w':
stupid 0:aaf22a04f350 567 write_settings();
stupid 0:aaf22a04f350 568 pc.printf("Wrote the current control parameters to memory.\r\n");
stupid 0:aaf22a04f350 569 break;
elmbed 3:cff2f80f0a42 570 case 'x':
elmbed 3:cff2f80f0a42 571 tip_sensor = !tip_sensor;
elmbed 3:cff2f80f0a42 572 pc.printf("tip_sensor = %d\r\n", tip_sensor);
elmbed 3:cff2f80f0a42 573 break;
stupid 0:aaf22a04f350 574
stupid 0:aaf22a04f350 575 default:
stupid 0:aaf22a04f350 576 usage();
stupid 0:aaf22a04f350 577 print_active_settings();
stupid 0:aaf22a04f350 578 break;
stupid 0:aaf22a04f350 579 }
stupid 0:aaf22a04f350 580 }
stupid 0:aaf22a04f350 581
stupid 0:aaf22a04f350 582 //put everything into a low power/off state. control loop will be unaffected by this command, so that will also need to be disabled before the heater will stay off
stupid 0:aaf22a04f350 583 void all_off(){
stupid 0:aaf22a04f350 584 heater_pin = 0;
stupid 0:aaf22a04f350 585 heater = OFF; //need to treat this as volatile
stupid 0:aaf22a04f350 586 fan = 0;
stupid 0:aaf22a04f350 587 empty_led.input(); //
stupid 0:aaf22a04f350 588 fuel_gage_1.input(); // = 1;
stupid 0:aaf22a04f350 589 fuel_gage_2.input(); // = 1;
stupid 0:aaf22a04f350 590 fuel_gage_3.input(); // = 1;
stupid 0:aaf22a04f350 591 fuel_gage_4.input(); // = 1;
stupid 0:aaf22a04f350 592 tip_light = 0;
stupid 0:aaf22a04f350 593 }
stupid 0:aaf22a04f350 594
stupid 0:aaf22a04f350 595 // run this to manually check the hardware works
stupid 0:aaf22a04f350 596 // probably best to disable the heater on the first try
stupid 0:aaf22a04f350 597 void functional_check(void){
stupid 1:ccb26dd9845a 598 all_off();
stupid 0:aaf22a04f350 599 if(connected)pc.printf("Tip light\r\n");
stupid 0:aaf22a04f350 600 tip_light = 1;
stupid 0:aaf22a04f350 601 wait_ms(1000);
stupid 0:aaf22a04f350 602 all_off();
stupid 0:aaf22a04f350 603 if(connected)pc.printf("Empty\r\n");
stupid 0:aaf22a04f350 604 empty_led.output();
stupid 0:aaf22a04f350 605 empty_led = 0;
stupid 0:aaf22a04f350 606 wait_ms(1000);
stupid 0:aaf22a04f350 607 all_off();
stupid 0:aaf22a04f350 608 if(connected)pc.printf("Fuel Gage 1\r\n");
stupid 0:aaf22a04f350 609 fuel_gage_1.output();
stupid 0:aaf22a04f350 610 fuel_gage_1 = 0;
stupid 0:aaf22a04f350 611 wait_ms(1000);
stupid 0:aaf22a04f350 612 all_off();
stupid 0:aaf22a04f350 613 if(connected)pc.printf("Fuel Gage 2\r\n");
stupid 0:aaf22a04f350 614 fuel_gage_2.output();
stupid 0:aaf22a04f350 615 fuel_gage_2 = 0;
stupid 0:aaf22a04f350 616 wait_ms(1000);
stupid 0:aaf22a04f350 617 all_off();
stupid 0:aaf22a04f350 618 if(connected)pc.printf("Fuel Gage 3\r\n");
stupid 0:aaf22a04f350 619 fuel_gage_3.output();
stupid 0:aaf22a04f350 620 fuel_gage_3 = 0;
stupid 0:aaf22a04f350 621 wait_ms(1000);
stupid 0:aaf22a04f350 622 all_off();
stupid 0:aaf22a04f350 623 if(connected)pc.printf("Fuel Gage 4\r\n");
stupid 0:aaf22a04f350 624 fuel_gage_4.output();
stupid 0:aaf22a04f350 625 fuel_gage_4 = 0;
stupid 0:aaf22a04f350 626 wait_ms(1000);
stupid 0:aaf22a04f350 627 all_off();
stupid 0:aaf22a04f350 628 if(connected)pc.printf("Fan\r\n");
stupid 0:aaf22a04f350 629 fan = 1;
stupid 0:aaf22a04f350 630 wait_ms(5000);
stupid 0:aaf22a04f350 631 if(connected)pc.printf("Heater\r\n");
stupid 0:aaf22a04f350 632 heater_pin = 1;
stupid 0:aaf22a04f350 633
stupid 0:aaf22a04f350 634 while(1){
stupid 0:aaf22a04f350 635 if(connected)pc.printf("Temp: %u\r\n", temp_sense.read_u16()>>6);
stupid 0:aaf22a04f350 636 wait_ms(50);
stupid 0:aaf22a04f350 637 tip_light = 1;
stupid 0:aaf22a04f350 638 wait_ms(50);
stupid 0:aaf22a04f350 639 tip_light = 0;
stupid 0:aaf22a04f350 640 }
stupid 0:aaf22a04f350 641 }
stupid 0:aaf22a04f350 642
stupid 0:aaf22a04f350 643 // INTERRUPT - called every 4ms, samples the ADC and filters the value with a low pass first order digital filter
stupid 0:aaf22a04f350 644 void get_temp(void){
stupid 0:aaf22a04f350 645 // not bothering with units, this means we need to keep the update constant at once every 4ms or we will need to set the filter again
stupid 0:aaf22a04f350 646 //temperature = filter * (temp_sense.read_u16()>>6) + (1 - filter) * temperature;
stupid 0:aaf22a04f350 647 // temperature is now in degrees C (value is at sensor, not at tips)
stupid 0:aaf22a04f350 648 temperature = filter * (51.282 * (temp_sense.read()*3.3 - 0.4)) + (1 - filter) * temperature;
stupid 0:aaf22a04f350 649 }
stupid 0:aaf22a04f350 650
stupid 0:aaf22a04f350 651 // INTERRUPT - called every millisecond to handle maintaining the on/off state of the triac
stupid 0:aaf22a04f350 652 void heater_control(void){
stupid 0:aaf22a04f350 653 static uint8_t count = 0;
stupid 0:aaf22a04f350 654
stupid 0:aaf22a04f350 655 // count up once per interrupt.
stupid 0:aaf22a04f350 656 // safety: check to make sure we haven't exceeded MAX_DUTY safety limit
stupid 0:aaf22a04f350 657 // after duty is reached for this control period, turn the heat off
stupid 0:aaf22a04f350 658 count++;
stupid 0:aaf22a04f350 659
stupid 0:aaf22a04f350 660 if(heater == ON && fan.read()){
stupid 0:aaf22a04f350 661 if(count > MAX_DUTY){
stupid 0:aaf22a04f350 662 count = 0;
stupid 0:aaf22a04f350 663 heater_pin = 1;
stupid 0:aaf22a04f350 664 }
stupid 0:aaf22a04f350 665 if(count > duty)heater_pin = 0;
stupid 0:aaf22a04f350 666 }
stupid 0:aaf22a04f350 667 else heater_pin = 0;
stupid 0:aaf22a04f350 668 }
stupid 0:aaf22a04f350 669
stupid 0:aaf22a04f350 670 // bail, something is wrong
stupid 0:aaf22a04f350 671 void abort(bool error){
stupid 0:aaf22a04f350 672 uint16_t period = 1000;
stupid 0:aaf22a04f350 673 if(error) period = 250;
stupid 0:aaf22a04f350 674 // turn everything off, leave the fan on for a few seconds and flash the red LED
stupid 0:aaf22a04f350 675 control_interrupt.detach();
stupid 0:aaf22a04f350 676 all_off();
stupid 0:aaf22a04f350 677 empty_led.input();
stupid 0:aaf22a04f350 678 fan = 1;
stupid 0:aaf22a04f350 679 wait_ms(3000);
stupid 0:aaf22a04f350 680 fan = 0;
stupid 0:aaf22a04f350 681 while(1){
stupid 0:aaf22a04f350 682 empty_led.output();
stupid 0:aaf22a04f350 683 empty_led = 0;
stupid 0:aaf22a04f350 684 heater_pin = 0;
stupid 0:aaf22a04f350 685 wait_ms(period);
stupid 0:aaf22a04f350 686 heater_pin = 0;
stupid 0:aaf22a04f350 687 empty_led.input();
stupid 0:aaf22a04f350 688 heater_pin = 0;
stupid 0:aaf22a04f350 689 wait_ms(period);
stupid 0:aaf22a04f350 690 }
stupid 0:aaf22a04f350 691 }
stupid 0:aaf22a04f350 692
stupid 0:aaf22a04f350 693 // INTERRUPT - monitor stuff that might indicate an error condition
stupid 0:aaf22a04f350 694 void check_limits(void){
stupid 0:aaf22a04f350 695 // need to move printing to the main loop
stupid 0:aaf22a04f350 696 if(duty >= duty_too_large){
stupid 0:aaf22a04f350 697 if(connected){
stupid 0:aaf22a04f350 698 pc.printf("Error!!! Duty cycle has become unreasonably ");
stupid 0:aaf22a04f350 699 pc.printf("large, Aborting.\r\n");
stupid 0:aaf22a04f350 700 }
stupid 0:aaf22a04f350 701 abort(true);
stupid 0:aaf22a04f350 702 }
stupid 0:aaf22a04f350 703
stupid 0:aaf22a04f350 704 if(get_temperature() > temp_limit_upper){
stupid 0:aaf22a04f350 705 if(connected)pc.printf("Error!!! Temperature is too high, Aborting.\r\n");
stupid 0:aaf22a04f350 706 abort(true);
stupid 0:aaf22a04f350 707 }
stupid 0:aaf22a04f350 708
stupid 0:aaf22a04f350 709 if((state == ACTIVE || state == INITIAL_RAMP) && (get_temperature() < temp_limit_lower)){
stupid 0:aaf22a04f350 710 if(connected){
stupid 0:aaf22a04f350 711 pc.printf("%f\r\n", get_temperature());
stupid 0:aaf22a04f350 712 pc.printf("Error!!! Abnormally low temperature detected. ");
stupid 0:aaf22a04f350 713 pc.printf("Please check the sensor, Aborting.\r\n");
stupid 0:aaf22a04f350 714 }
stupid 0:aaf22a04f350 715 abort(true);
stupid 0:aaf22a04f350 716 }
stupid 0:aaf22a04f350 717 }
stupid 0:aaf22a04f350 718
stupid 0:aaf22a04f350 719 // values pulled from the MCP9701T-E/LT datasheet
stupid 0:aaf22a04f350 720 // 19.5mV/deg-C, 400mV @ 0C
stupid 0:aaf22a04f350 721 float adc_to_temp(float adc_value){
stupid 0:aaf22a04f350 722 //return 0.195 * adc_value -
stupid 0:aaf22a04f350 723 return 0.196 * adc_value - 31.322;
stupid 0:aaf22a04f350 724 }
stupid 0:aaf22a04f350 725
stupid 0:aaf22a04f350 726 void init(void){
stupid 0:aaf22a04f350 727 #ifdef SERIAL
elmbed 3:cff2f80f0a42 728 pc.baud(4800);
stupid 0:aaf22a04f350 729 connected = true;
stupid 0:aaf22a04f350 730 #else
stupid 0:aaf22a04f350 731 pc.connect();
stupid 0:aaf22a04f350 732 connected = pc.vbusDetected();
stupid 0:aaf22a04f350 733 #endif
stupid 0:aaf22a04f350 734
stupid 0:aaf22a04f350 735 if(connected)pc.printf("hello\r\n");
stupid 0:aaf22a04f350 736
stupid 0:aaf22a04f350 737 tick_interrupt.attach(&tick, 0.001);
stupid 0:aaf22a04f350 738 control_interrupt.attach(&heater_control, 0.001);
stupid 0:aaf22a04f350 739 temperature_interrupt.attach(&get_temp, 0.004);
stupid 0:aaf22a04f350 740 if(!CALIBRATE)check_limits_interrupt.attach(&check_limits, 0.5);
stupid 0:aaf22a04f350 741
elmbed 3:cff2f80f0a42 742 //read_settings();
elmbed 3:cff2f80f0a42 743 //set_duty(initial_duty);
elmbed 3:cff2f80f0a42 744 //all_off();
stupid 0:aaf22a04f350 745 }
stupid 0:aaf22a04f350 746
stupid 1:ccb26dd9845a 747 void check_on_off(void){
stupid 1:ccb26dd9845a 748 static uint32_t count = 0;
stupid 1:ccb26dd9845a 749
stupid 1:ccb26dd9845a 750 // debounce
stupid 1:ccb26dd9845a 751 if(on_off){
stupid 1:ccb26dd9845a 752 count++;
stupid 1:ccb26dd9845a 753 if(count > ON_OFF_DEBOUNCE){
stupid 1:ccb26dd9845a 754 all_off();
stupid 1:ccb26dd9845a 755 state = IDLE;
stupid 1:ccb26dd9845a 756 }
stupid 1:ccb26dd9845a 757 }
stupid 1:ccb26dd9845a 758 else count = 0;
stupid 1:ccb26dd9845a 759 }
stupid 1:ccb26dd9845a 760
stupid 1:ccb26dd9845a 761 void do_idle(bool first){
stupid 1:ccb26dd9845a 762 if(!on_off) state = WAIT_FOR_TIP;
stupid 1:ccb26dd9845a 763 }
stupid 1:ccb26dd9845a 764
elmbed 3:cff2f80f0a42 765 void do_paused(bool first)
elmbed 3:cff2f80f0a42 766 {
elmbed 3:cff2f80f0a42 767 all_off();
elmbed 3:cff2f80f0a42 768 state = WAIT_FOR_TIP;
elmbed 3:cff2f80f0a42 769 }
elmbed 3:cff2f80f0a42 770
stupid 0:aaf22a04f350 771 // tip neeeds to be present before we can start the cycle
stupid 1:ccb26dd9845a 772 // later we should also abort the cycle if the tip is removed
stupid 0:aaf22a04f350 773 void do_wait_for_tip(bool first){
stupid 0:aaf22a04f350 774 unsigned long time = get_time();
stupid 0:aaf22a04f350 775 unsigned long time_increment = time % 1800;
stupid 0:aaf22a04f350 776
stupid 0:aaf22a04f350 777 if(first){
stupid 0:aaf22a04f350 778 if(connected)pc.printf("Looking for tip\r\n");
stupid 0:aaf22a04f350 779 }
stupid 0:aaf22a04f350 780 if(!tip_sensor){ //tip present is low == present
stupid 0:aaf22a04f350 781 tip_light = 1;
stupid 0:aaf22a04f350 782 fuel_gage_1.output();
stupid 0:aaf22a04f350 783 fuel_gage_1 = 0;
stupid 0:aaf22a04f350 784 fuel_gage_2.output();
stupid 0:aaf22a04f350 785 fuel_gage_2 = 0;
stupid 0:aaf22a04f350 786 fuel_gage_3.output();
stupid 0:aaf22a04f350 787 fuel_gage_3 = 0;
stupid 0:aaf22a04f350 788 fuel_gage_4.output();
stupid 0:aaf22a04f350 789 fuel_gage_4 = 0;
stupid 0:aaf22a04f350 790 empty_led.input();
elmbed 3:cff2f80f0a42 791 state = GET_TIP_CONFIG;
stupid 0:aaf22a04f350 792 if(connected)pc.printf("Found the tip\r\n");
stupid 0:aaf22a04f350 793 return;
stupid 0:aaf22a04f350 794 }
stupid 0:aaf22a04f350 795
stupid 0:aaf22a04f350 796 if(time_increment < 300){
stupid 0:aaf22a04f350 797 fuel_gage_1.input(); // = 1;
stupid 0:aaf22a04f350 798 fuel_gage_2.input(); // = 1;
stupid 0:aaf22a04f350 799 fuel_gage_3.input(); // = 1;
stupid 0:aaf22a04f350 800 fuel_gage_4.input(); // = 1;
stupid 0:aaf22a04f350 801 }
stupid 0:aaf22a04f350 802 if(time_increment > 600){
stupid 0:aaf22a04f350 803 fuel_gage_1.output();
stupid 0:aaf22a04f350 804 fuel_gage_1 = 0;
stupid 0:aaf22a04f350 805 }
stupid 0:aaf22a04f350 806 if(time_increment > 900){
stupid 0:aaf22a04f350 807 fuel_gage_2.output();
stupid 0:aaf22a04f350 808 fuel_gage_2 = 0;
stupid 0:aaf22a04f350 809 }
stupid 0:aaf22a04f350 810 if(time_increment > 1200){
stupid 0:aaf22a04f350 811 fuel_gage_3.output();
stupid 0:aaf22a04f350 812 fuel_gage_3 = 0;
stupid 0:aaf22a04f350 813 }
stupid 0:aaf22a04f350 814 if(time_increment > 1500){
stupid 0:aaf22a04f350 815 fuel_gage_4.output();
stupid 0:aaf22a04f350 816 fuel_gage_4 = 0;
stupid 0:aaf22a04f350 817 }
stupid 0:aaf22a04f350 818 }
stupid 0:aaf22a04f350 819
elmbed 3:cff2f80f0a42 820 /**
elmbed 3:cff2f80f0a42 821 * Get the configuration data from the tip. Currently just
elmbed 3:cff2f80f0a42 822 * reads the time remaining parameter.
elmbed 3:cff2f80f0a42 823 *
elmbed 3:cff2f80f0a42 824 * @param first - true when state just changed, else false
elmbed 3:cff2f80f0a42 825 */
elmbed 3:cff2f80f0a42 826 void do_get_tip_config(bool first)
elmbed 3:cff2f80f0a42 827 {
elmbed 3:cff2f80f0a42 828 static int _state = 1;
elmbed 3:cff2f80f0a42 829 static uint32_t last_print = 0;
elmbed 3:cff2f80f0a42 830 static uint32_t sent_time = 0;
elmbed 3:cff2f80f0a42 831
elmbed 3:cff2f80f0a42 832 if (first)
elmbed 3:cff2f80f0a42 833 {
elmbed 3:cff2f80f0a42 834 _state = 1;
elmbed 3:cff2f80f0a42 835 sent_time = 0;
elmbed 3:cff2f80f0a42 836 last_print = get_time();
elmbed 3:cff2f80f0a42 837 }
elmbed 3:cff2f80f0a42 838
elmbed 3:cff2f80f0a42 839 if (connected && get_time() - last_print > 5000)
elmbed 3:cff2f80f0a42 840 {
elmbed 3:cff2f80f0a42 841 pc.printf("tip_config: %d\r\n", _state);
elmbed 3:cff2f80f0a42 842 last_print = get_time();
elmbed 3:cff2f80f0a42 843 }
elmbed 3:cff2f80f0a42 844
elmbed 3:cff2f80f0a42 845 switch (_state)
elmbed 3:cff2f80f0a42 846 {
elmbed 3:cff2f80f0a42 847 case 1:
elmbed 3:cff2f80f0a42 848 {
elmbed 3:cff2f80f0a42 849 tip_message tm;
elmbed 3:cff2f80f0a42 850
elmbed 3:cff2f80f0a42 851 tm.command = READ_TIME_REMAINING;
elmbed 3:cff2f80f0a42 852 tm.value = 10L;
elmbed 3:cff2f80f0a42 853
elmbed 3:cff2f80f0a42 854 if (send_message_to_tip(&tm))
elmbed 3:cff2f80f0a42 855 {
elmbed 3:cff2f80f0a42 856 _state = 2;
elmbed 3:cff2f80f0a42 857 sent_time = get_time();
elmbed 3:cff2f80f0a42 858 }
elmbed 3:cff2f80f0a42 859 else
elmbed 3:cff2f80f0a42 860 {
elmbed 3:cff2f80f0a42 861 _state = -1;
elmbed 3:cff2f80f0a42 862 }
elmbed 3:cff2f80f0a42 863 break;
elmbed 3:cff2f80f0a42 864 }
elmbed 3:cff2f80f0a42 865 case 2:
elmbed 3:cff2f80f0a42 866 {
elmbed 3:cff2f80f0a42 867 tip_message tm;
elmbed 3:cff2f80f0a42 868 tm.command = 0;
elmbed 3:cff2f80f0a42 869
elmbed 3:cff2f80f0a42 870 if (get_message_from_tip(&tm))
elmbed 3:cff2f80f0a42 871 {
elmbed 3:cff2f80f0a42 872 tip_start_value_s = tm.value;
elmbed 3:cff2f80f0a42 873
elmbed 3:cff2f80f0a42 874 if (connected)
elmbed 3:cff2f80f0a42 875 {
elmbed 3:cff2f80f0a42 876 pc.printf("TIP_START_VAL: %ld\r\n", tip_start_value_s);
elmbed 3:cff2f80f0a42 877 }
elmbed 3:cff2f80f0a42 878
elmbed 3:cff2f80f0a42 879 if (tip_start_value_s <= 0)
elmbed 3:cff2f80f0a42 880 {
elmbed 3:cff2f80f0a42 881 if (connected)
elmbed 3:cff2f80f0a42 882 {
elmbed 3:cff2f80f0a42 883 pc.printf("TIP HAS ZERO VAL\r\n");
elmbed 3:cff2f80f0a42 884 }
elmbed 3:cff2f80f0a42 885
elmbed 3:cff2f80f0a42 886 state = PAUSED;
elmbed 3:cff2f80f0a42 887 }
elmbed 3:cff2f80f0a42 888 else
elmbed 3:cff2f80f0a42 889 {
elmbed 3:cff2f80f0a42 890 state = INITIAL_RAMP;
elmbed 3:cff2f80f0a42 891 }
elmbed 3:cff2f80f0a42 892 }
elmbed 3:cff2f80f0a42 893 else if (get_time() - sent_time > 3000) // Wait 3s for reply
elmbed 3:cff2f80f0a42 894 {
elmbed 3:cff2f80f0a42 895 // Try again
elmbed 3:cff2f80f0a42 896 tm.command = RESET_BUFFER;
elmbed 3:cff2f80f0a42 897 get_message_from_tip(&tm);
elmbed 3:cff2f80f0a42 898
elmbed 3:cff2f80f0a42 899 if (connected)
elmbed 3:cff2f80f0a42 900 {
elmbed 3:cff2f80f0a42 901 pc.printf("TIP TIMEOUT\r\n");
elmbed 3:cff2f80f0a42 902 }
elmbed 3:cff2f80f0a42 903
elmbed 3:cff2f80f0a42 904 _state = 1;
elmbed 3:cff2f80f0a42 905 }
elmbed 3:cff2f80f0a42 906 break;
elmbed 3:cff2f80f0a42 907 }
elmbed 3:cff2f80f0a42 908 }
elmbed 3:cff2f80f0a42 909 }
elmbed 3:cff2f80f0a42 910
stupid 0:aaf22a04f350 911 //This should quickly take us up from ambient to the setpoint.
stupid 0:aaf22a04f350 912 void do_initial_ramp(bool first){
stupid 0:aaf22a04f350 913 // set duty to initial_duty and wait to reach the setpoint to break out
stupid 0:aaf22a04f350 914 static uint32_t start_time = 0;
stupid 0:aaf22a04f350 915 static uint32_t last_print = get_time();
stupid 0:aaf22a04f350 916
stupid 0:aaf22a04f350 917 if(first){
stupid 1:ccb26dd9845a 918 print_active_settings();
stupid 0:aaf22a04f350 919 start_time = get_time();
stupid 0:aaf22a04f350 920 fan = 1;
stupid 0:aaf22a04f350 921 set_duty(initial_duty);
stupid 0:aaf22a04f350 922 heater = ON;
stupid 0:aaf22a04f350 923 if(connected)pc.printf("Initial ramp up. Duty will be held constant until setpoint is reached.\r\n");
stupid 0:aaf22a04f350 924 }
stupid 0:aaf22a04f350 925
stupid 0:aaf22a04f350 926 if(get_time() - start_time > 60000){
stupid 0:aaf22a04f350 927 if(connected)pc.printf("Took too long to reach setpoint, aborting.\r\n");
stupid 0:aaf22a04f350 928 abort(true);
stupid 0:aaf22a04f350 929 }
stupid 0:aaf22a04f350 930
stupid 0:aaf22a04f350 931 if(get_time() - last_print > 5000){
stupid 1:ccb26dd9845a 932 if(connected)pc.printf("Duty: %u, Temp: %.2f, Time: %.2fs\r\n", get_duty(), get_temperature(), (float)get_time()/1000);
stupid 0:aaf22a04f350 933 last_print = get_time();
stupid 0:aaf22a04f350 934 }
stupid 0:aaf22a04f350 935
stupid 0:aaf22a04f350 936 if(get_temperature() > setpoint - tolerance){
stupid 0:aaf22a04f350 937 //now we are roughly up to temperature
stupid 0:aaf22a04f350 938 set_duty(nominal_duty);
stupid 0:aaf22a04f350 939 state = ACTIVE;
stupid 0:aaf22a04f350 940 return;
stupid 0:aaf22a04f350 941 }
stupid 0:aaf22a04f350 942 }
stupid 0:aaf22a04f350 943
stupid 0:aaf22a04f350 944 void do_treatment_cycle(bool first){
stupid 0:aaf22a04f350 945 static uint32_t start_time = 0;
stupid 0:aaf22a04f350 946 static uint32_t control_timer = 0;
elmbed 3:cff2f80f0a42 947 static uint32_t last_tip_update = 0;
stupid 0:aaf22a04f350 948 uint8_t duty_copy;
stupid 0:aaf22a04f350 949 float temperature_copy;
stupid 0:aaf22a04f350 950
stupid 0:aaf22a04f350 951 if(first){
stupid 0:aaf22a04f350 952 start_time = get_time();
stupid 0:aaf22a04f350 953 control_timer = start_time;
elmbed 3:cff2f80f0a42 954 last_tip_update = 0;
stupid 0:aaf22a04f350 955 }
stupid 0:aaf22a04f350 956
stupid 0:aaf22a04f350 957 uint32_t current_time = get_time() - start_time;
stupid 0:aaf22a04f350 958
elmbed 3:cff2f80f0a42 959 // Check if we should update the tip time remaining
elmbed 3:cff2f80f0a42 960 if (current_time - last_tip_update > TIP_UPDATE_INTERVAL_S * 1000L)
elmbed 3:cff2f80f0a42 961 {
elmbed 3:cff2f80f0a42 962 struct tip_message tm;
elmbed 3:cff2f80f0a42 963 tm.command = WRITE_TIME_REMAINING;
elmbed 3:cff2f80f0a42 964 tm.value = tip_start_value_s - (current_time / 1000);
elmbed 3:cff2f80f0a42 965
elmbed 3:cff2f80f0a42 966 send_message_to_tip(&tm);
elmbed 3:cff2f80f0a42 967 last_tip_update = current_time;
elmbed 3:cff2f80f0a42 968 }
elmbed 3:cff2f80f0a42 969
stupid 0:aaf22a04f350 970 // check if we're done
elmbed 3:cff2f80f0a42 971 if((current_time / 1000L) + current_cycle_on_time_s >= ON_TIME_S){
stupid 0:aaf22a04f350 972 if(connected)pc.printf("Done!\r\n");
stupid 1:ccb26dd9845a 973 //abort(false);
stupid 1:ccb26dd9845a 974 set_duty(0);
stupid 1:ccb26dd9845a 975 fan = 0;
stupid 1:ccb26dd9845a 976 state = DONE;
stupid 0:aaf22a04f350 977 }
stupid 0:aaf22a04f350 978
elmbed 3:cff2f80f0a42 979 if (tip_sensor || current_time > tip_start_value_s * 1000L)
elmbed 3:cff2f80f0a42 980 {
elmbed 3:cff2f80f0a42 981 struct tip_message tm;
elmbed 3:cff2f80f0a42 982 tm.command = WRITE_TIME_REMAINING;
elmbed 3:cff2f80f0a42 983 tm.value = tip_start_value_s - (current_time / 1000);
elmbed 3:cff2f80f0a42 984
elmbed 3:cff2f80f0a42 985 send_message_to_tip(&tm);
elmbed 3:cff2f80f0a42 986
elmbed 3:cff2f80f0a42 987 // The tip has been removed or is out of juice
elmbed 3:cff2f80f0a42 988 current_cycle_on_time_s += current_time / 1000L;
elmbed 3:cff2f80f0a42 989
elmbed 3:cff2f80f0a42 990 if (connected)
elmbed 3:cff2f80f0a42 991 {
elmbed 3:cff2f80f0a42 992 pc.printf("ACTIVE -> PAUSED: %d %ld %ld %ld\r\n", tip_sensor, current_time, current_cycle_on_time_s, tip_start_value_s);
elmbed 3:cff2f80f0a42 993 }
elmbed 3:cff2f80f0a42 994
elmbed 3:cff2f80f0a42 995 state = PAUSED;
elmbed 3:cff2f80f0a42 996 return;
elmbed 3:cff2f80f0a42 997 }
elmbed 3:cff2f80f0a42 998
stupid 0:aaf22a04f350 999 if(current_time - control_timer > 5000){ // run the control loop every 5 seconds
stupid 0:aaf22a04f350 1000 control_timer = current_time;
stupid 0:aaf22a04f350 1001 duty_copy = get_duty();
stupid 0:aaf22a04f350 1002 temperature_copy = get_temperature();
stupid 0:aaf22a04f350 1003 if(temperature_copy > setpoint + tolerance) duty_copy--;
stupid 0:aaf22a04f350 1004 if(temperature_copy < setpoint - tolerance) duty_copy++;
stupid 0:aaf22a04f350 1005 set_duty(duty_copy);
stupid 0:aaf22a04f350 1006
stupid 1:ccb26dd9845a 1007 if(connected)pc.printf("Duty: %u, Temp: %.2f, Time: %.2fs\r\n", get_duty(), get_temperature(), ((float)get_time() - (float)start_time)/1000);
stupid 1:ccb26dd9845a 1008 }
stupid 1:ccb26dd9845a 1009 }
stupid 1:ccb26dd9845a 1010
stupid 1:ccb26dd9845a 1011 void do_done(bool first){
stupid 1:ccb26dd9845a 1012 static uint32_t start_time = 0;
stupid 1:ccb26dd9845a 1013
stupid 1:ccb26dd9845a 1014 if(first){
stupid 1:ccb26dd9845a 1015 start_time = get_time();
stupid 1:ccb26dd9845a 1016 //control_interrupt.detach();
stupid 1:ccb26dd9845a 1017 all_off();
stupid 1:ccb26dd9845a 1018 if(connected)pc.printf("Done!\r\n");
stupid 1:ccb26dd9845a 1019 }
stupid 1:ccb26dd9845a 1020
stupid 1:ccb26dd9845a 1021 heater_pin = 0;
stupid 1:ccb26dd9845a 1022 uint32_t current_time = get_time() - start_time;
stupid 1:ccb26dd9845a 1023
stupid 1:ccb26dd9845a 1024 if(current_time % 2000 > 1000){
stupid 1:ccb26dd9845a 1025 empty_led.input();
stupid 1:ccb26dd9845a 1026 }
stupid 1:ccb26dd9845a 1027 else{
stupid 1:ccb26dd9845a 1028 empty_led.output();
stupid 1:ccb26dd9845a 1029 empty_led = 0;
stupid 0:aaf22a04f350 1030 }
elmbed 3:cff2f80f0a42 1031
elmbed 3:cff2f80f0a42 1032 current_cycle_on_time_s = 0;
stupid 0:aaf22a04f350 1033 }
stupid 0:aaf22a04f350 1034
stupid 0:aaf22a04f350 1035 void print_state(void){
stupid 0:aaf22a04f350 1036 if(!connected)return;
stupid 1:ccb26dd9845a 1037 printf("State:\t");
stupid 0:aaf22a04f350 1038 switch(state){
stupid 0:aaf22a04f350 1039 case IDLE:
stupid 0:aaf22a04f350 1040 printf("IDLE\r\n");
stupid 0:aaf22a04f350 1041 break;
stupid 0:aaf22a04f350 1042 case WAIT_FOR_TIP:
stupid 0:aaf22a04f350 1043 printf("WAIT_FOR_TIP\r\n");
stupid 0:aaf22a04f350 1044 break;
stupid 0:aaf22a04f350 1045 case INITIAL_RAMP:
stupid 0:aaf22a04f350 1046 printf("INITIAL_RAMP\r\n");
stupid 0:aaf22a04f350 1047 break;
stupid 0:aaf22a04f350 1048 case ACTIVE:
stupid 0:aaf22a04f350 1049 printf("ACTIVE\r\n");
stupid 0:aaf22a04f350 1050 break;
stupid 1:ccb26dd9845a 1051 case DONE:
stupid 1:ccb26dd9845a 1052 printf("DONE\r\n");
stupid 1:ccb26dd9845a 1053 break;
stupid 0:aaf22a04f350 1054 case ERROR:
stupid 0:aaf22a04f350 1055 printf("ERROR\r\n");
stupid 0:aaf22a04f350 1056 break;
elmbed 3:cff2f80f0a42 1057 case PAUSED:
elmbed 3:cff2f80f0a42 1058 printf("PAUSED\r\n");
elmbed 3:cff2f80f0a42 1059 break;
elmbed 3:cff2f80f0a42 1060 case GET_TIP_CONFIG:
elmbed 3:cff2f80f0a42 1061 printf("GET_TIP_CONFIG\r\n");
elmbed 3:cff2f80f0a42 1062 break;
stupid 0:aaf22a04f350 1063 default: break;
stupid 0:aaf22a04f350 1064 }
stupid 0:aaf22a04f350 1065 }
stupid 0:aaf22a04f350 1066
stupid 0:aaf22a04f350 1067 int main(){
elmbed 3:cff2f80f0a42 1068 wait_ms(8000);
elmbed 3:cff2f80f0a42 1069
stupid 0:aaf22a04f350 1070 static State last_state = IDLE;
elmbed 3:cff2f80f0a42 1071
stupid 0:aaf22a04f350 1072 init();
elmbed 3:cff2f80f0a42 1073 #if 0
stupid 1:ccb26dd9845a 1074 if(FUNCTION_CHECK) functional_check();
stupid 0:aaf22a04f350 1075 if(CALIBRATE){
stupid 0:aaf22a04f350 1076 calibrate(true);
stupid 0:aaf22a04f350 1077 while(1)calibrate(false);
stupid 0:aaf22a04f350 1078 }
elmbed 3:cff2f80f0a42 1079 #endif
stupid 0:aaf22a04f350 1080
stupid 0:aaf22a04f350 1081 while(1){
elmbed 3:cff2f80f0a42 1082
elmbed 3:cff2f80f0a42 1083 //getInput();
stupid 1:ccb26dd9845a 1084
stupid 1:ccb26dd9845a 1085 check_on_off();
stupid 0:aaf22a04f350 1086
stupid 0:aaf22a04f350 1087 bool state_change = false;
stupid 0:aaf22a04f350 1088 if(state != last_state){
stupid 0:aaf22a04f350 1089 state_change = true;
stupid 0:aaf22a04f350 1090 last_state = state;
stupid 0:aaf22a04f350 1091 print_state();
stupid 0:aaf22a04f350 1092 }
elmbed 3:cff2f80f0a42 1093
stupid 0:aaf22a04f350 1094 switch(state){
stupid 0:aaf22a04f350 1095 case IDLE:
stupid 1:ccb26dd9845a 1096 do_idle(state_change);
stupid 0:aaf22a04f350 1097 break;
stupid 0:aaf22a04f350 1098 case WAIT_FOR_TIP:
stupid 0:aaf22a04f350 1099 do_wait_for_tip(state_change);
stupid 0:aaf22a04f350 1100 break;
elmbed 3:cff2f80f0a42 1101 case GET_TIP_CONFIG:
elmbed 3:cff2f80f0a42 1102 do_get_tip_config(state_change);
elmbed 3:cff2f80f0a42 1103 break;
stupid 0:aaf22a04f350 1104 case INITIAL_RAMP:
stupid 0:aaf22a04f350 1105 do_initial_ramp(state_change);
stupid 0:aaf22a04f350 1106 spin_lights(state_change);
stupid 0:aaf22a04f350 1107 break;
stupid 0:aaf22a04f350 1108 case ACTIVE:
stupid 0:aaf22a04f350 1109 do_treatment_cycle(state_change);
stupid 0:aaf22a04f350 1110 spin_lights(false);
stupid 0:aaf22a04f350 1111 break;
stupid 1:ccb26dd9845a 1112 case DONE:
stupid 1:ccb26dd9845a 1113 do_done(state_change);
stupid 1:ccb26dd9845a 1114 break;
stupid 0:aaf22a04f350 1115 case ERROR:
stupid 0:aaf22a04f350 1116 abort(true);
stupid 0:aaf22a04f350 1117 break;
elmbed 3:cff2f80f0a42 1118 case PAUSED:
elmbed 3:cff2f80f0a42 1119 do_paused(state_change);
stupid 0:aaf22a04f350 1120 default: break;
elmbed 3:cff2f80f0a42 1121 }
elmbed 3:cff2f80f0a42 1122
stupid 0:aaf22a04f350 1123 }
elmbed 3:cff2f80f0a42 1124
stupid 0:aaf22a04f350 1125 }
stupid 0:aaf22a04f350 1126
stupid 0:aaf22a04f350 1127 void spin_lights(bool first){
stupid 0:aaf22a04f350 1128 static uint32_t start_time = 0;
stupid 0:aaf22a04f350 1129
stupid 0:aaf22a04f350 1130 if(first) start_time = get_time();
stupid 0:aaf22a04f350 1131 uint32_t current_time = get_time() - start_time;
stupid 0:aaf22a04f350 1132
stupid 1:ccb26dd9845a 1133 // tip should be solid for TIP_FLASH_INTERVAL_S seconds, then flash for 3 seconds
stupid 1:ccb26dd9845a 1134 uint32_t tip_time = current_time % (TIP_FLASH_INTERVAL_S * 1000 + 3000);
stupid 1:ccb26dd9845a 1135 if(tip_time < (TIP_FLASH_INTERVAL_S * 1000)) tip_light = 1;
stupid 0:aaf22a04f350 1136 else tip_light = (tip_time % 100 < 50)?1:0;
stupid 0:aaf22a04f350 1137
stupid 1:ccb26dd9845a 1138 // handle fuel gage LEDs
stupid 0:aaf22a04f350 1139 // this should be more directly linked to the treatment stop condition
stupid 0:aaf22a04f350 1140 uint32_t step = (ON_TIME_S - RED_LED_ON_TIME_S)/5;
stupid 0:aaf22a04f350 1141 step *= 1000;
stupid 0:aaf22a04f350 1142
stupid 0:aaf22a04f350 1143 if(current_time > step) fuel_gage_4.input();
stupid 0:aaf22a04f350 1144 else{
stupid 0:aaf22a04f350 1145 fuel_gage_4.output();
stupid 0:aaf22a04f350 1146 fuel_gage_4 = 0;
stupid 0:aaf22a04f350 1147 }
stupid 0:aaf22a04f350 1148 if(current_time > 2*step) fuel_gage_3.input();
stupid 0:aaf22a04f350 1149 else{
stupid 0:aaf22a04f350 1150 fuel_gage_3.output();
stupid 0:aaf22a04f350 1151 fuel_gage_3 = 0;
stupid 0:aaf22a04f350 1152 }
stupid 0:aaf22a04f350 1153 if(current_time > 3*step) fuel_gage_2.input();
stupid 0:aaf22a04f350 1154 else{
stupid 0:aaf22a04f350 1155 fuel_gage_2.output();
stupid 0:aaf22a04f350 1156 fuel_gage_2 = 0;
stupid 0:aaf22a04f350 1157 }
stupid 0:aaf22a04f350 1158 if(current_time > 4*step) fuel_gage_1.input();
stupid 0:aaf22a04f350 1159 else{
stupid 0:aaf22a04f350 1160 fuel_gage_1.output();
stupid 0:aaf22a04f350 1161 fuel_gage_1 = 0;
stupid 0:aaf22a04f350 1162 }
stupid 0:aaf22a04f350 1163 if(current_time > 5*step){
stupid 0:aaf22a04f350 1164 empty_led.output();
stupid 0:aaf22a04f350 1165 empty_led = 0;
stupid 0:aaf22a04f350 1166 }
stupid 0:aaf22a04f350 1167 else empty_led.input();
stupid 0:aaf22a04f350 1168 }
stupid 0:aaf22a04f350 1169
stupid 0:aaf22a04f350 1170 void calibrate(bool first){
stupid 0:aaf22a04f350 1171 static uint32_t start_time = 0;
stupid 0:aaf22a04f350 1172 static uint32_t control_timer = 0;
stupid 0:aaf22a04f350 1173 uint8_t duty_copy;
stupid 0:aaf22a04f350 1174
stupid 0:aaf22a04f350 1175 if(first){
stupid 0:aaf22a04f350 1176 start_time = get_time();
stupid 0:aaf22a04f350 1177 control_timer = start_time;
stupid 0:aaf22a04f350 1178 fan = 1;
stupid 0:aaf22a04f350 1179 set_duty(5);
stupid 0:aaf22a04f350 1180 heater = ON;
stupid 0:aaf22a04f350 1181 }
stupid 0:aaf22a04f350 1182
stupid 0:aaf22a04f350 1183 uint32_t current_time = get_time() - start_time;
stupid 0:aaf22a04f350 1184
stupid 0:aaf22a04f350 1185 if(current_time - control_timer > 15000){ // increase the duty by 5% every 15 seconds
stupid 0:aaf22a04f350 1186 if(connected)pc.printf("Duty: %u, Temp: %f, Time: %.2fs\r\n", get_duty(), get_temperature(), ((float)get_time() - (float)start_time)/1000);
stupid 0:aaf22a04f350 1187 control_timer = current_time;
stupid 0:aaf22a04f350 1188 duty_copy = get_duty();
stupid 0:aaf22a04f350 1189 duty_copy += 5;
stupid 0:aaf22a04f350 1190 // check if we're done
stupid 0:aaf22a04f350 1191 if(duty > 75 && connected){
stupid 0:aaf22a04f350 1192 set_duty(1);
stupid 0:aaf22a04f350 1193 pc.printf("Done!\r\n");
stupid 0:aaf22a04f350 1194 abort(false);
stupid 0:aaf22a04f350 1195 }
stupid 0:aaf22a04f350 1196 set_duty(duty_copy);
stupid 0:aaf22a04f350 1197 }
stupid 0:aaf22a04f350 1198 }
stupid 0:aaf22a04f350 1199
stupid 0:aaf22a04f350 1200 /*
stupid 0:aaf22a04f350 1201 void calibrate(void){
stupid 0:aaf22a04f350 1202 // this is really not necessary because all we care about is the temperature we need to hold the sensor at,
stupid 0:aaf22a04f350 1203 // which we are assuming directly correlates to output air temp.
stupid 0:aaf22a04f350 1204 // in reality it will probably be affected by ambient temperature,
stupid 0:aaf22a04f350 1205 // humidity, air flow rate, elevation (air density), and other factors
stupid 0:aaf22a04f350 1206 static uint16_t count = 0;
stupid 0:aaf22a04f350 1207 static uint8_t duty_copy = 5; //inital duty
stupid 0:aaf22a04f350 1208 float temperature_copy;
stupid 0:aaf22a04f350 1209 static int tester_count = 0;
stupid 0:aaf22a04f350 1210
stupid 0:aaf22a04f350 1211 current_time = get_time();
stupid 0:aaf22a04f350 1212 count++;
stupid 0:aaf22a04f350 1213
stupid 0:aaf22a04f350 1214 check_limits();
stupid 0:aaf22a04f350 1215
stupid 0:aaf22a04f350 1216 if(count > 200){ // run the control loop every second
stupid 0:aaf22a04f350 1217 count = 0;
stupid 0:aaf22a04f350 1218 tester_count++;
stupid 0:aaf22a04f350 1219 if(tester_count % 30 == 0){ //30 seconds each duty cycle
stupid 0:aaf22a04f350 1220 duty_copy += 5;
stupid 0:aaf22a04f350 1221 if(duty > 85)abort(false);
stupid 0:aaf22a04f350 1222 if(connected)pc.printf("Duty: %u\r\nTemps:\r\n", duty_copy);
stupid 0:aaf22a04f350 1223 }
stupid 0:aaf22a04f350 1224 __disable_irq();
stupid 0:aaf22a04f350 1225 duty = duty_copy;
stupid 0:aaf22a04f350 1226 temperature_copy = temperature;
stupid 0:aaf22a04f350 1227 __enable_irq();
stupid 0:aaf22a04f350 1228
stupid 1:ccb26dd9845a 1229 if(connected && (tester_count % 30) > 24)pc.printf("\t%f\t%u\t%f\r\n", temperature_copy, temp_sense.read_u16(), temp_sense.read());
stupid 0:aaf22a04f350 1230 }
stupid 0:aaf22a04f350 1231 }*/