![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
LEX_Threaded_Programming
Dependencies: Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC
main.cpp
- Committer:
- omatthews
- Date:
- 2019-08-27
- Revision:
- 2:b27d8f9a6e49
- Parent:
- 0:54bedd3964e2
- Child:
- 4:63d7f2a0dec6
File content as of revision 2:b27d8f9a6e49:
#include "mbed.h" #include "pb.h" #include "pb_decode.h" #include "pb_encode.h" #include "MODSERIAL.h" #include "ADS8568_ADC.h" #include "Heater.h" #include "FastPWM.h" #include "memspcr.pb.h" #include <vector> #include <iterator> #define ALL_CH 15 //value of convst bus to read all chanels simultaneosly Heater * heater; float r_gradient; int curr_time; 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; //Heater Control FastPWM drive_1(PC_9); FastPWM drive_2(PC_8); FastPWM guard_1(PC_7); FastPWM guard_2(PC_6); //indicator LEDs DigitalOut hb_led(PC_13); //Green DigitalOut led_0(PC_4); //Red DigitalOut led_1(PC_5); //Green //User buttons DigitalIn user_0(PB_0); DigitalIn user_1(PB_1); BusOut converts(PC_0, PC_1, PC_2, PC_3); //Threads Thread heater_control; Thread logging_thread; //Tickers Ticker heat_tick; Ticker pressure_tick; Ticker log_tick; //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; 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; size_t message_length; uint8_t buffer[256]; //Functions for reading and decoding the message__________________________________________________ void read_message() { if (pc.scanf("%d",&message_length) < 0){pc.printf("Error reading message length");} pc.printf("Message is %d chars long, buffer length is %d\n",message_length,buffer_length); for (i = 0; i < message_length; i++) { i = i % buffer_length; pc.scanf("%02X",&c); buffer[i] = (char) c; } } void decode_message() { // 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. status = pb_decode(&istream, memspcr_ExperimentConfiguration_fields, &exp_config); // Check for errors... if (!status) { pc.printf("Decoding failed: %s\n", PB_GET_ERROR(&istream)); } } bool decode_callback(pb_istream_t *stream, const pb_field_t *field, void **arg) { 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) { pc.printf("Decode callback failed\n"); } dest->push_back(result); return true; } //Ticking functions_________________________________________________________________ void temp_trigger() { //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; } void log_trigger() { log_flag = true; } void pressure_control() { //Input pressure control function here //i.e. //read_pressure(); //if (pressure < lower_bound) { //pump_turn_on(); //} //else if (pressure > upper_bound) { //pump_turn_off(); //} led_1 = !led_1; } //Other functions__________________________________________________________________ void temp_control() { while(1){ while(!heater_flag); heater->read(); heater->update(); heater_flag = false; } } void log_state() { while(1){ while(!log_flag); 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); 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)); 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; } wait_ms(1); } } } int main() { pc.baud(115200); adc.init(); buffer_length = sizeof(buffer)/sizeof(uint8_t); pc.printf("Input configuration file\n"); read_message(); pc.printf("\nMessage read\n"); exp_config.thermal.profile.arg = &profile; exp_config.thermal.profile.funcs.decode = decode_callback; decode_message(); printf("\nMessage decoded\n"); Heater heater_(exp_config.thermal); heater = &heater_; 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); logging_thread.start(& log_state); log_tick.attach_us(& log_trigger,exp_config.logging_interval_ms * 1000); pc.printf("\nStarting routine\n"); timer.start(); set_point_routine(); heater->turn_off(); pc.printf("Finished"); }