LEX_Threaded_Programming

Dependencies:   Heater_V2 MODSERIAL Nanopb FastPWM ADS8568_ADC

Revision:
5:702b32ead94e
Parent:
4:63d7f2a0dec6
Child:
6:ef2bcc5fe3af
diff -r 63d7f2a0dec6 -r 702b32ead94e main.cpp
--- 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