LEX_Threaded_Programming

Dependencies:   Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC

Committer:
omatthews
Date:
Thu Aug 29 16:08:04 2019 +0000
Revision:
5:702b32ead94e
Parent:
4:63d7f2a0dec6
Child:
6:ef2bcc5fe3af
Edits made

Who changed what in which revision?

UserRevisionLine numberNew contents of line
omatthews 0:54bedd3964e2 1 #include "mbed.h"
omatthews 0:54bedd3964e2 2 #include "pb.h"
omatthews 0:54bedd3964e2 3 #include "pb_decode.h"
omatthews 0:54bedd3964e2 4 #include "pb_encode.h"
omatthews 0:54bedd3964e2 5 #include "MODSERIAL.h"
omatthews 0:54bedd3964e2 6 #include "ADS8568_ADC.h"
omatthews 0:54bedd3964e2 7 #include "Heater.h"
omatthews 0:54bedd3964e2 8 #include "FastPWM.h"
omatthews 0:54bedd3964e2 9 #include "memspcr.pb.h"
omatthews 0:54bedd3964e2 10 #include <vector>
omatthews 0:54bedd3964e2 11 #include <iterator>
omatthews 0:54bedd3964e2 12
omatthews 0:54bedd3964e2 13 Heater * heater;
intrinseca 4:63d7f2a0dec6 14 float r_gradient; //setpoint setting
omatthews 5:702b32ead94e 15
omatthews 0:54bedd3964e2 16
omatthews 0:54bedd3964e2 17 MODSERIAL pc(PA_9, PA_10, 512); //mcu TX, RX, 512 byte TX and RX buffers
omatthews 0:54bedd3964e2 18 ADS8568_ADC adc(PB_15, PB_14, PB_13, PB_12, PC_15, PC_0, PC_1, PC_2, PC_3);
omatthews 0:54bedd3964e2 19 I2C i2c(PB_7, PB_8); //SDA, SCL
omatthews 0:54bedd3964e2 20 Timer timer;
omatthews 0:54bedd3964e2 21 DigitalIn adc_busy(PA_8); //Busy interrupt sig#
omatthews 5:702b32ead94e 22
omatthews 0:54bedd3964e2 23
omatthews 0:54bedd3964e2 24 //Heater Control
omatthews 5:702b32ead94e 25 FastPWM drive_main(PC_9);
omatthews 5:702b32ead94e 26 FastPWM drive_lysis(PC_8);
omatthews 5:702b32ead94e 27 FastPWM guard_main(PC_7);
omatthews 5:702b32ead94e 28 FastPWM guard_lysis(PC_6);
omatthews 5:702b32ead94e 29 int i_port_main = 0;
omatthews 5:702b32ead94e 30 int i_port_lysis = 2;
omatthews 5:702b32ead94e 31 int v_port_main = 1;
omatthews 5:702b32ead94e 32 int v_port_lysis = 3;
omatthews 0:54bedd3964e2 33
omatthews 0:54bedd3964e2 34
omatthews 0:54bedd3964e2 35
omatthews 0:54bedd3964e2 36 //indicator LEDs
omatthews 0:54bedd3964e2 37 DigitalOut hb_led(PC_13); //Green
omatthews 0:54bedd3964e2 38 DigitalOut led_0(PC_4); //Red
omatthews 0:54bedd3964e2 39 DigitalOut led_1(PC_5); //Green
omatthews 0:54bedd3964e2 40
omatthews 0:54bedd3964e2 41 //User buttons
omatthews 0:54bedd3964e2 42 DigitalIn user_0(PB_0);
omatthews 0:54bedd3964e2 43 DigitalIn user_1(PB_1);
omatthews 0:54bedd3964e2 44
omatthews 0:54bedd3964e2 45 BusOut converts(PC_0, PC_1, PC_2, PC_3);
omatthews 0:54bedd3964e2 46
omatthews 0:54bedd3964e2 47
omatthews 0:54bedd3964e2 48 //Threads
omatthews 0:54bedd3964e2 49 Thread heater_control;
omatthews 2:b27d8f9a6e49 50 Thread logging_thread;
omatthews 0:54bedd3964e2 51
omatthews 0:54bedd3964e2 52 //Tickers
omatthews 0:54bedd3964e2 53 Ticker heat_tick;
omatthews 0:54bedd3964e2 54 Ticker pressure_tick;
omatthews 0:54bedd3964e2 55 Ticker log_tick;
omatthews 0:54bedd3964e2 56
omatthews 0:54bedd3964e2 57
omatthews 0:54bedd3964e2 58 //Flags
omatthews 5:702b32ead94e 59 EventFlags flags; //Flags:
omatthews 5:702b32ead94e 60 // 0 => update heater
omatthews 5:702b32ead94e 61 // 1 => log state
omatthews 5:702b32ead94e 62 bool triggered_flag;
omatthews 0:54bedd3964e2 63 bool status = true;
omatthews 0:54bedd3964e2 64
omatthews 0:54bedd3964e2 65 //Configuration data
omatthews 0:54bedd3964e2 66 memspcr_ExperimentConfiguration exp_config = memspcr_ExperimentConfiguration_init_zero;
omatthews 0:54bedd3964e2 67 int buffer_length;
omatthews 0:54bedd3964e2 68 size_t message_length;
omatthews 5:702b32ead94e 69 uint8_t buffer[512]; //FIXME: Needs to be longer
omatthews 0:54bedd3964e2 70
omatthews 0:54bedd3964e2 71
omatthews 0:54bedd3964e2 72
omatthews 0:54bedd3964e2 73
omatthews 0:54bedd3964e2 74 //Functions for reading and decoding the message__________________________________________________
omatthews 0:54bedd3964e2 75
omatthews 0:54bedd3964e2 76 void read_message()
omatthews 0:54bedd3964e2 77 {
omatthews 0:54bedd3964e2 78 if (pc.scanf("%d",&message_length) < 0){pc.printf("Error reading message length");}
omatthews 5:702b32ead94e 79 size_t buffer_length = sizeof(buffer);
omatthews 5:702b32ead94e 80 if (message_length > buffer_length)
omatthews 5:702b32ead94e 81 {
omatthews 5:702b32ead94e 82 pc.printf("Message length exceeds buffer. \n Input configuration file\n");
omatthews 5:702b32ead94e 83 read_message();
omatthews 5:702b32ead94e 84 return;
omatthews 5:702b32ead94e 85 }
omatthews 0:54bedd3964e2 86 pc.printf("Message is %d chars long, buffer length is %d\n",message_length,buffer_length);
omatthews 5:702b32ead94e 87 unsigned int c;
omatthews 5:702b32ead94e 88 for (int i = 0; i < message_length; i++)
omatthews 0:54bedd3964e2 89 {
omatthews 0:54bedd3964e2 90 pc.scanf("%02X",&c);
omatthews 0:54bedd3964e2 91 buffer[i] = (char) c;
omatthews 0:54bedd3964e2 92 }
omatthews 0:54bedd3964e2 93 }
omatthews 0:54bedd3964e2 94
omatthews 0:54bedd3964e2 95 void decode_message()
omatthews 0:54bedd3964e2 96 {
omatthews 5:702b32ead94e 97 // Create a stream that reads from the buffer.
omatthews 5:702b32ead94e 98
omatthews 0:54bedd3964e2 99 pb_istream_t istream = pb_istream_from_buffer(buffer, message_length);
omatthews 0:54bedd3964e2 100
omatthews 5:702b32ead94e 101 //Now we are ready to decode the message.
omatthews 0:54bedd3964e2 102 status = pb_decode(&istream, memspcr_ExperimentConfiguration_fields, &exp_config);
omatthews 0:54bedd3964e2 103
omatthews 5:702b32ead94e 104 // Check for errors...
omatthews 5:702b32ead94e 105 if (!status) {
omatthews 0:54bedd3964e2 106 pc.printf("Decoding failed: %s\n", PB_GET_ERROR(&istream));
omatthews 0:54bedd3964e2 107 }
omatthews 0:54bedd3964e2 108 }
omatthews 0:54bedd3964e2 109
omatthews 0:54bedd3964e2 110 bool decode_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
omatthews 0:54bedd3964e2 111 {
omatthews 0:54bedd3964e2 112 vector <memspcr_ThermalStep> * dest = (vector <memspcr_ThermalStep> *)(*arg);
omatthews 0:54bedd3964e2 113 memspcr_ThermalStep result = memspcr_ThermalStep_init_zero;
omatthews 0:54bedd3964e2 114 status = pb_decode(stream, memspcr_ThermalStep_fields, & result);
omatthews 5:702b32ead94e 115
omatthews 5:702b32ead94e 116 if (!status) {
omatthews 0:54bedd3964e2 117 pc.printf("Decode callback failed\n");
omatthews 0:54bedd3964e2 118 }
omatthews 0:54bedd3964e2 119
intrinseca 4:63d7f2a0dec6 120 dest->push_back(result); //CHECK: Does result get copied into the vector?
omatthews 0:54bedd3964e2 121 return true;
omatthews 0:54bedd3964e2 122 }
omatthews 0:54bedd3964e2 123
omatthews 0:54bedd3964e2 124
omatthews 0:54bedd3964e2 125 //Ticking functions_________________________________________________________________
omatthews 0:54bedd3964e2 126
omatthews 5:702b32ead94e 127 void temp_trigger()
omatthews 0:54bedd3964e2 128 {
omatthews 5:702b32ead94e 129 //This function triggers a temperature update.
omatthews 5:702b32ead94e 130 //N.B. update cannot be called directly from a ticker as tickers and
omatthews 0:54bedd3964e2 131 //reading the ADC both rely on interrupts.
omatthews 5:702b32ead94e 132 flags.set(0x1);
omatthews 5:702b32ead94e 133 led_0 = !led_0;
omatthews 5:702b32ead94e 134
omatthews 0:54bedd3964e2 135 }
omatthews 0:54bedd3964e2 136
omatthews 2:b27d8f9a6e49 137 void log_trigger()
omatthews 2:b27d8f9a6e49 138 {
omatthews 5:702b32ead94e 139 flags.set(0x2);
omatthews 2:b27d8f9a6e49 140 }
omatthews 5:702b32ead94e 141 void pressure_control()
omatthews 0:54bedd3964e2 142 {
omatthews 0:54bedd3964e2 143 //Input pressure control function here
omatthews 0:54bedd3964e2 144 //i.e.
omatthews 0:54bedd3964e2 145 //read_pressure();
omatthews 0:54bedd3964e2 146 //if (pressure < lower_bound) {
omatthews 5:702b32ead94e 147 //pump_turn_on();
omatthews 5:702b32ead94e 148 //}
omatthews 0:54bedd3964e2 149 //else if (pressure > upper_bound) {
omatthews 5:702b32ead94e 150 //pump_turn_off();
omatthews 5:702b32ead94e 151 //}
omatthews 0:54bedd3964e2 152 led_1 = !led_1;
omatthews 0:54bedd3964e2 153 }
omatthews 0:54bedd3964e2 154
omatthews 2:b27d8f9a6e49 155
omatthews 0:54bedd3964e2 156
omatthews 0:54bedd3964e2 157
omatthews 5:702b32ead94e 158 //Other functions__________________________________________________________________
omatthews 0:54bedd3964e2 159
omatthews 0:54bedd3964e2 160
omatthews 0:54bedd3964e2 161 void temp_control() {
omatthews 0:54bedd3964e2 162 while(1){
omatthews 5:702b32ead94e 163 flags.wait_any(0x1);
omatthews 5:702b32ead94e 164 led_1 = !led_1;
omatthews 5:702b32ead94e 165
omatthews 5:702b32ead94e 166 flags.clear(0x1);
omatthews 5:702b32ead94e 167
omatthews 0:54bedd3964e2 168 heater->read();
omatthews 0:54bedd3964e2 169 heater->update();
omatthews 0:54bedd3964e2 170 }
omatthews 0:54bedd3964e2 171 }
omatthews 5:702b32ead94e 172
omatthews 2:b27d8f9a6e49 173 void log_state()
omatthews 2:b27d8f9a6e49 174 {
omatthews 2:b27d8f9a6e49 175 while(1){
omatthews 5:702b32ead94e 176 flags.wait_any(0x2);
omatthews 5:702b32ead94e 177 flags.clear(0x2);
omatthews 2:b27d8f9a6e49 178 heater->log();
omatthews 2:b27d8f9a6e49 179 }
omatthews 2:b27d8f9a6e49 180 }
omatthews 5:702b32ead94e 181
omatthews 5:702b32ead94e 182 void set_point_routine(std::vector<memspcr_ThermalStep> profile) {
omatthews 5:702b32ead94e 183 int curr_time;
omatthews 5:702b32ead94e 184 vector <memspcr_ThermalStep>::iterator it_prev, it = profile.begin();
omatthews 5:702b32ead94e 185 if (it->elapsed_time_ms != 0)
omatthews 5:702b32ead94e 186 {
omatthews 5:702b32ead94e 187 pc.printf("\nError: the first point in the profile should be at time 0.\n");
omatthews 5:702b32ead94e 188 return;
omatthews 5:702b32ead94e 189 }
omatthews 2:b27d8f9a6e49 190 it++;
omatthews 0:54bedd3964e2 191
omatthews 0:54bedd3964e2 192 for (it_prev = profile.begin(); it < profile.end(); it ++, it_prev++){
omatthews 0:54bedd3964e2 193 triggered_flag = false;
omatthews 0:54bedd3964e2 194 r_gradient = (it->resistance - it_prev->resistance)/(it->elapsed_time_ms - it_prev->elapsed_time_ms);
omatthews 0:54bedd3964e2 195 while ((curr_time = timer.read_ms()) <= it->elapsed_time_ms){
omatthews 5:702b32ead94e 196 heater->Set_ref(it_prev->resistance + r_gradient * (curr_time - it_prev->elapsed_time_ms));
omatthews 0:54bedd3964e2 197
omatthews 5:702b32ead94e 198
omatthews 0:54bedd3964e2 199 if (!triggered_flag && curr_time > it_prev->elapsed_time_ms + it->camera_offset_ms)
omatthews 0:54bedd3964e2 200 {
omatthews 0:54bedd3964e2 201 //Start camera trigger
omatthews 0:54bedd3964e2 202 //trigger_out = 1;
omatthews 0:54bedd3964e2 203 triggered_flag = true;
omatthews 0:54bedd3964e2 204 }
omatthews 5:702b32ead94e 205 else
omatthews 5:702b32ead94e 206 {
omatthews 5:702b32ead94e 207 //trigger_out = 0;
intrinseca 4:63d7f2a0dec6 208 }
omatthews 0:54bedd3964e2 209
intrinseca 4:63d7f2a0dec6 210 wait_us(200);
omatthews 0:54bedd3964e2 211 }
omatthews 0:54bedd3964e2 212
omatthews 0:54bedd3964e2 213 }
omatthews 0:54bedd3964e2 214 }
omatthews 0:54bedd3964e2 215
omatthews 0:54bedd3964e2 216
omatthews 5:702b32ead94e 217
omatthews 5:702b32ead94e 218
omatthews 0:54bedd3964e2 219
omatthews 5:702b32ead94e 220
omatthews 5:702b32ead94e 221 int main()
omatthews 5:702b32ead94e 222 {
omatthews 0:54bedd3964e2 223 pc.baud(115200);
omatthews 0:54bedd3964e2 224 adc.init();
omatthews 5:702b32ead94e 225
omatthews 0:54bedd3964e2 226 buffer_length = sizeof(buffer)/sizeof(uint8_t);
omatthews 5:702b32ead94e 227 pc.printf("\n\nInput configuration file\n");
omatthews 5:702b32ead94e 228
intrinseca 4:63d7f2a0dec6 229 //set up nanopb
omatthews 5:702b32ead94e 230 std::vector<memspcr_ThermalStep> profile;
omatthews 5:702b32ead94e 231 exp_config.profile.funcs.decode = decode_callback;
omatthews 5:702b32ead94e 232 exp_config.profile.arg = &profile;
omatthews 5:702b32ead94e 233
omatthews 5:702b32ead94e 234
intrinseca 4:63d7f2a0dec6 235 //read and decode configuration
intrinseca 4:63d7f2a0dec6 236 read_message();
omatthews 5:702b32ead94e 237 pc.printf("\nMessage read\n");
omatthews 0:54bedd3964e2 238 decode_message();
omatthews 0:54bedd3964e2 239 printf("\nMessage decoded\n");
omatthews 5:702b32ead94e 240
omatthews 5:702b32ead94e 241
omatthews 5:702b32ead94e 242
omatthews 5:702b32ead94e 243 Heater * heater_main = new Heater(i_port_main, v_port_main, & drive_main, & guard_main, exp_config.thermal);
omatthews 5:702b32ead94e 244 Heater * heater_lysis = new Heater(i_port_lysis, v_port_lysis, & drive_lysis, & guard_lysis, exp_config.thermal);
omatthews 5:702b32ead94e 245
omatthews 5:702b32ead94e 246 //Select heater. Put control times in us for ticker functions
omatthews 5:702b32ead94e 247 if (exp_config.selected_heater == memspcr_ExperimentConfiguration_Heater_MAIN) {
omatthews 5:702b32ead94e 248 heater = heater_main;
omatthews 5:702b32ead94e 249 } else if (exp_config.selected_heater == memspcr_ExperimentConfiguration_Heater_LYSIS) {
omatthews 5:702b32ead94e 250 heater = heater_lysis;
omatthews 5:702b32ead94e 251 } else {
omatthews 5:702b32ead94e 252 pc.printf("Error - no heater has been selected");
omatthews 5:702b32ead94e 253 return 1;
omatthews 5:702b32ead94e 254 }
omatthews 5:702b32ead94e 255
omatthews 0:54bedd3964e2 256 pc.printf("\nStarting pressure control\n");
omatthews 0:54bedd3964e2 257 pressure_tick.attach(& pressure_control, 1);
omatthews 2:b27d8f9a6e49 258 pc.printf("\nWaiting for start signal to begin temperature control (type in an s or press button 0)\n");
omatthews 0:54bedd3964e2 259
omatthews 2:b27d8f9a6e49 260 while (pc.getcNb()!='s' && !user_0);
omatthews 5:702b32ead94e 261
omatthews 0:54bedd3964e2 262 pc.printf("Start signal received");
omatthews 0:54bedd3964e2 263 heater_control.start(& temp_control);
omatthews 5:702b32ead94e 264
omatthews 5:702b32ead94e 265 heat_tick.attach_us(& temp_trigger,exp_config.thermal.control_loop_interval_ms * 500);
omatthews 0:54bedd3964e2 266
omatthews 2:b27d8f9a6e49 267 logging_thread.start(& log_state);
omatthews 5:702b32ead94e 268 log_tick.attach_us(& log_trigger,exp_config.logging_interval_ms * 500);
omatthews 0:54bedd3964e2 269
omatthews 5:702b32ead94e 270
omatthews 0:54bedd3964e2 271 pc.printf("\nStarting routine\n");
omatthews 2:b27d8f9a6e49 272 timer.start();
omatthews 5:702b32ead94e 273 set_point_routine(profile);
omatthews 5:702b32ead94e 274 heat_tick.detach();
omatthews 5:702b32ead94e 275 log_tick.detach();
omatthews 5:702b32ead94e 276 wait(1);
omatthews 2:b27d8f9a6e49 277 heater->turn_off();
omatthews 5:702b32ead94e 278
omatthews 0:54bedd3964e2 279 pc.printf("Finished");
omatthews 5:702b32ead94e 280
omatthews 5:702b32ead94e 281
omatthews 5:702b32ead94e 282 return 0;
omatthews 5:702b32ead94e 283 }