Aes encryption code
Dependencies: Crypto USBDevice mbed
Fork of larada by
main.cpp@5:7214d56ee5ae, 2016-03-09 (annotated)
- 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?
User | Revision | Line number | New 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 | }*/ |