Aes encryption code

Dependencies:   Crypto USBDevice mbed

Fork of larada by MZJ

Committer:
elmbed
Date:
Sat Mar 12 10:20:20 2016 +0000
Revision:
6:634306947b58
Parent:
5:7214d56ee5ae
Child:
7:ed473cf0afaf
added min time between message sends

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