![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
LEX_Threaded_Programming
Dependencies: Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC
Diff: main.cpp
- Revision:
- 5:702b32ead94e
- Parent:
- 4:63d7f2a0dec6
- Child:
- 6:ef2bcc5fe3af
--- a/main.cpp Wed Aug 28 15:38:19 2019 +0000 +++ b/main.cpp Thu Aug 29 16:08:04 2019 +0000 @@ -12,24 +12,25 @@ Heater * heater; float r_gradient; //setpoint setting -int curr_time; //FIXME: make local + MODSERIAL pc(PA_9, PA_10, 512); //mcu TX, RX, 512 byte TX and RX buffers ADS8568_ADC adc(PB_15, PB_14, PB_13, PB_12, PC_15, PC_0, PC_1, PC_2, PC_3); I2C i2c(PB_7, PB_8); //SDA, SCL Timer timer; DigitalIn adc_busy(PA_8); //Busy interrupt sig# -int i; //FIXME: separate i for every time it's used + //Heater Control -FastPWM drive_1(PC_9); -FastPWM drive_2(PC_8); -FastPWM guard_1(PC_7); -FastPWM guard_2(PC_6); +FastPWM drive_main(PC_9); +FastPWM drive_lysis(PC_8); +FastPWM guard_main(PC_7); +FastPWM guard_lysis(PC_6); +int i_port_main = 0; +int i_port_lysis = 2; +int v_port_main = 1; +int v_port_lysis = 3; -Heater* main_heater; -Heater* lysis_heater; -Heater* heater; //indicator LEDs @@ -55,21 +56,17 @@ //Flags -bool start_flag = false; -bool config_flag = false; -volatile bool heater_flag = false; -volatile bool log_flag = false; -bool triggered_flag = false; -bool untriggered_flag = false; +EventFlags flags; //Flags: + // 0 => update heater + // 1 => log state +bool triggered_flag; bool status = true; //Configuration data memspcr_ExperimentConfiguration exp_config = memspcr_ExperimentConfiguration_init_zero; int buffer_length; -std::vector<memspcr_ThermalStep> profile; -unsigned int c = 0; //FIXME: not global size_t message_length; -uint8_t buffer[256]; //FIXME: Needs to be longer +uint8_t buffer[512]; //FIXME: Needs to be longer @@ -78,13 +75,18 @@ void read_message() { - //FIXME: This should work with binary data if (pc.scanf("%d",&message_length) < 0){pc.printf("Error reading message length");} + size_t buffer_length = sizeof(buffer); + if (message_length > buffer_length) + { + pc.printf("Message length exceeds buffer. \n Input configuration file\n"); + read_message(); + return; + } pc.printf("Message is %d chars long, buffer length is %d\n",message_length,buffer_length); - //assert message fits in buffer - for (i = 0; i < message_length; i++) + unsigned int c; + for (int i = 0; i < message_length; i++) { - i = i % buffer_length; pc.scanf("%02X",&c); buffer[i] = (char) c; } @@ -92,16 +94,15 @@ void decode_message() { - // Create a stream that reads from the buffer. - + // Create a stream that reads from the buffer. + pb_istream_t istream = pb_istream_from_buffer(buffer, message_length); - //Now we are ready to decode the message. + //Now we are ready to decode the message. status = pb_decode(&istream, memspcr_ExperimentConfiguration_fields, &exp_config); - // Check for errors... - if (!status) - { + // Check for errors... + if (!status) { pc.printf("Decoding failed: %s\n", PB_GET_ERROR(&istream)); } } @@ -111,9 +112,8 @@ vector <memspcr_ThermalStep> * dest = (vector <memspcr_ThermalStep> *)(*arg); memspcr_ThermalStep result = memspcr_ThermalStep_init_zero; status = pb_decode(stream, memspcr_ThermalStep_fields, & result); - - if (!status) - { + + if (!status) { pc.printf("Decode callback failed\n"); } @@ -124,89 +124,87 @@ //Ticking functions_________________________________________________________________ -void temp_trigger() +void temp_trigger() { - //This function triggers a temperature update. - //N.B. update cannot be called directly from a ticker as tickers and + //This function triggers a temperature update. + //N.B. update cannot be called directly from a ticker as tickers and //reading the ADC both rely on interrupts. - heater_flag = true; + flags.set(0x1); + led_0 = !led_0; + } void log_trigger() { - log_flag = true; + flags.set(0x2); } -void pressure_control() +void pressure_control() { //Input pressure control function here //i.e. //read_pressure(); //if (pressure < lower_bound) { - //pump_turn_on(); - //} + //pump_turn_on(); + //} //else if (pressure > upper_bound) { - //pump_turn_off(); - //} + //pump_turn_off(); + //} led_1 = !led_1; } -//Other functions__________________________________________________________________ +//Other functions__________________________________________________________________ void temp_control() { while(1){ - while(!heater_flag); + flags.wait_any(0x1); + led_1 = !led_1; + + flags.clear(0x1); + heater->read(); heater->update(); - heater_flag = false; } } - + void log_state() { while(1){ - while(!log_flag); + flags.wait_any(0x2); + flags.clear(0x2); heater->log(); - log_flag = false; } } - -void set_point_routine() { - memspcr_ThermalStep step; - step.resistance = 0.0; - step.elapsed_time_ms = 0; - step.camera_offset_ms = 0; - vector <memspcr_ThermalStep>::iterator it = profile.begin(); - vector <memspcr_ThermalStep>::iterator it_prev; - profile.insert(it,step); //not needed - should be checked by PC - //just assert that profile[0] time is 0 + +void set_point_routine(std::vector<memspcr_ThermalStep> profile) { + int curr_time; + vector <memspcr_ThermalStep>::iterator it_prev, it = profile.begin(); + if (it->elapsed_time_ms != 0) + { + pc.printf("\nError: the first point in the profile should be at time 0.\n"); + return; + } it++; for (it_prev = profile.begin(); it < profile.end(); it ++, it_prev++){ triggered_flag = false; - untriggered_flag = false; r_gradient = (it->resistance - it_prev->resistance)/(it->elapsed_time_ms - it_prev->elapsed_time_ms); while ((curr_time = timer.read_ms()) <= it->elapsed_time_ms){ - heater->Set_ref(it_prev->resistance + r_gradient * (curr_time - it_prev->elapsed_time_ms)); + heater->Set_ref(it_prev->resistance + r_gradient * (curr_time - it_prev->elapsed_time_ms)); - if (!untriggered_flag && triggered_flag) - { - //Untrigger on the next cycle - //trigger_out = 0; - untriggered_flag = true; - } - + if (!triggered_flag && curr_time > it_prev->elapsed_time_ms + it->camera_offset_ms) { //Start camera trigger //trigger_out = 1; triggered_flag = true; } - else if(triggered_flag) { - trigger_out = false; + else + { + //trigger_out = 0; } wait_us(200); @@ -216,50 +214,70 @@ } - + + - - -int main() { + +int main() +{ pc.baud(115200); adc.init(); - + buffer_length = sizeof(buffer)/sizeof(uint8_t); - pc.printf("Input configuration file\n"); - + pc.printf("\n\nInput configuration file\n"); + //set up nanopb - exp_config.thermal.profile.arg = &profile; - exp_config.thermal.profile.funcs.decode = decode_callback; - + std::vector<memspcr_ThermalStep> profile; + exp_config.profile.funcs.decode = decode_callback; + exp_config.profile.arg = &profile; + + //read and decode configuration read_message(); - pc.printf("\nMessage read\n"); + pc.printf("\nMessage read\n"); decode_message(); printf("\nMessage decoded\n"); - - - //Heater heater_(exp_config.thermal); - heater = new Heater(exp_config.thermal); - + + + + Heater * heater_main = new Heater(i_port_main, v_port_main, & drive_main, & guard_main, exp_config.thermal); + Heater * heater_lysis = new Heater(i_port_lysis, v_port_lysis, & drive_lysis, & guard_lysis, exp_config.thermal); + + //Select heater. Put control times in us for ticker functions + if (exp_config.selected_heater == memspcr_ExperimentConfiguration_Heater_MAIN) { + heater = heater_main; + } else if (exp_config.selected_heater == memspcr_ExperimentConfiguration_Heater_LYSIS) { + heater = heater_lysis; + } else { + pc.printf("Error - no heater has been selected"); + return 1; + } + pc.printf("\nStarting pressure control\n"); pressure_tick.attach(& pressure_control, 1); pc.printf("\nWaiting for start signal to begin temperature control (type in an s or press button 0)\n"); while (pc.getcNb()!='s' && !user_0); - + pc.printf("Start signal received"); heater_control.start(& temp_control); - heat_tick.attach_us(& temp_trigger,exp_config.thermal.control_loop_interval * 1000); + + heat_tick.attach_us(& temp_trigger,exp_config.thermal.control_loop_interval_ms * 500); logging_thread.start(& log_state); - log_tick.attach_us(& log_trigger,exp_config.logging_interval_ms * 1000); + log_tick.attach_us(& log_trigger,exp_config.logging_interval_ms * 500); - + pc.printf("\nStarting routine\n"); timer.start(); - set_point_routine(); + set_point_routine(profile); + heat_tick.detach(); + log_tick.detach(); + wait(1); heater->turn_off(); + pc.printf("Finished"); - - - } \ No newline at end of file + + + return 0; +} \ No newline at end of file