![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
LEX_Threaded_Programming
Dependencies: Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC
Diff: main.cpp
- Revision:
- 0:54bedd3964e2
- Child:
- 2:b27d8f9a6e49
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Aug 27 07:51:34 2019 +0000 @@ -0,0 +1,242 @@ +#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; + +//Tickers +Ticker heat_tick; +Ticker pressure_tick; +Ticker log_tick; + + +//Flags +bool start_flag = false; +bool config_flag = false; +volatile bool heater_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 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; +} + +void log_state() +{ + heater->log(); +} + + +//Other functions__________________________________________________________________ + + +void temp_control() { + while(1){ + while(!heater_flag); + led_0 = !led_0; + heater->read(); + heater->update(); + heater_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); + + 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\n"); + + while (pc.getc()!='s'); + + pc.printf("Start signal received"); + heater_control.start(& temp_control); + heat_tick.attach_us(& temp_trigger,exp_config.thermal.control_loop_interval); + + log_tick.attach_us(& log_state,exp_config.logging_interval_ms * 1000); + + + pc.printf("\nStarting routine\n"); + set_point_routine(); + pc.printf("Finished"); + + + } \ No newline at end of file