LEX_Threaded_Programming

Dependencies:   Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC

Revision:
0:54bedd3964e2
Child:
2:b27d8f9a6e49
diff -r 000000000000 -r 54bedd3964e2 main.cpp
--- /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