Aes encryption code

Dependencies:   Crypto USBDevice mbed

Fork of larada by MZJ

Committer:
elmbed
Date:
Wed Mar 09 20:50:13 2016 +0000
Revision:
5:7214d56ee5ae
Parent:
4:11520c01d65f
Child:
6:634306947b58
Added AES encryption for tip comms

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