This will generate the message for the programme

Dependencies:   MODSERIAL Nanopb

Committer:
justinbuckland
Date:
Fri Sep 20 12:55:49 2019 +0000
Revision:
4:629ca12c04f4
Parent:
3:3888b5ecad7e
Generates example low T test sequence for use with thermochromic tape

Who changed what in which revision?

UserRevisionLine numberNew contents of line
omatthews 0:388a2a9f5247 1 #include "mbed.h"
omatthews 0:388a2a9f5247 2 #include "pb.h"
omatthews 0:388a2a9f5247 3 #include "pb_decode.h"
omatthews 0:388a2a9f5247 4 #include "pb_encode.h"
omatthews 0:388a2a9f5247 5 #include "memspcr.pb.h"
omatthews 0:388a2a9f5247 6 #include "MODSERIAL.h"
omatthews 0:388a2a9f5247 7 #include <vector>
omatthews 0:388a2a9f5247 8 #include <iterator>
omatthews 0:388a2a9f5247 9
justinbuckland 3:3888b5ecad7e 10 #define BUFFER_SIZE 4096
omatthews 0:388a2a9f5247 11
justinbuckland 3:3888b5ecad7e 12 MODSERIAL pc(PA_9, PA_10, BUFFER_SIZE); //mcu TX, RX, BUFFER_SIZE byte TX and RX buffers
justinbuckland 3:3888b5ecad7e 13
justinbuckland 3:3888b5ecad7e 14 uint8_t buffer[BUFFER_SIZE];
omatthews 0:388a2a9f5247 15 size_t message_length;
omatthews 0:388a2a9f5247 16 bool status;
omatthews 0:388a2a9f5247 17 int i = 0;
omatthews 0:388a2a9f5247 18 unsigned int c;
omatthews 0:388a2a9f5247 19 memspcr_ExperimentConfiguration exp_config = memspcr_ExperimentConfiguration_init_zero;
omatthews 0:388a2a9f5247 20 int buffer_length;
omatthews 0:388a2a9f5247 21 int n_points;
justinbuckland 3:3888b5ecad7e 22 //int logging_interval_ms = 100; // typical for experimental testing
justinbuckland 3:3888b5ecad7e 23 //int logging_interval_ms = 1000; // for drive electronics resistance measurement calibration
justinbuckland 3:3888b5ecad7e 24 //int logging_interval_ms = 5000; // for consumable temperature calibration
justinbuckland 3:3888b5ecad7e 25 int logging_interval_ms = 500; // for melt curve measurement
omatthews 0:388a2a9f5247 26
omatthews 0:388a2a9f5247 27 std::vector<memspcr_ThermalStep> profile;
omatthews 0:388a2a9f5247 28
justinbuckland 3:3888b5ecad7e 29 //Parameters for test ramp
justinbuckland 3:3888b5ecad7e 30 //float resistance[9] = { 0.45, 0.525, 0.525, 0.535, 0.545, 0.555, 0.555};
justinbuckland 3:3888b5ecad7e 31 //int elapsed_time_ms[9] = { 0, 1000, 2000, 3000, 4000, 5000, 6000};
justinbuckland 3:3888b5ecad7e 32 //int camera_offset_ms[9] = { 0, 500, 500, 500, 500, 500, 500};
omatthews 0:388a2a9f5247 33
justinbuckland 3:3888b5ecad7e 34 //Parameters for drive electronics resistance measurement calibration
justinbuckland 3:3888b5ecad7e 35 //float resistance[2] = { 0, 0};
justinbuckland 3:3888b5ecad7e 36 //int elapsed_time_ms[2] = { 0, 20000};
justinbuckland 3:3888b5ecad7e 37 //int camera_offset_ms[2] = { 0, 0};
justinbuckland 3:3888b5ecad7e 38
justinbuckland 3:3888b5ecad7e 39 //Parameters for consumable temperature calibration
justinbuckland 3:3888b5ecad7e 40 //float resistance[2] = { 0, 0};
justinbuckland 3:3888b5ecad7e 41 //int elapsed_time_ms[2] = { 0, 3600000};
justinbuckland 3:3888b5ecad7e 42 //int camera_offset_ms[2] = { 0, 0};
justinbuckland 3:3888b5ecad7e 43
justinbuckland 3:3888b5ecad7e 44 //Melt curve programmed later
justinbuckland 3:3888b5ecad7e 45 //float melt_resistance_start = 0.525;
justinbuckland 3:3888b5ecad7e 46 //float melt_resistance_end = 0.550;
justinbuckland 3:3888b5ecad7e 47 //float resistance[103];
justinbuckland 3:3888b5ecad7e 48 //int elapsed_time_ms[103];
justinbuckland 3:3888b5ecad7e 49 //int camera_offset_ms[103];
justinbuckland 3:3888b5ecad7e 50
justinbuckland 3:3888b5ecad7e 51 //RT-PCR temperature profile programmed later
justinbuckland 3:3888b5ecad7e 52 float resistance[165];
justinbuckland 3:3888b5ecad7e 53 float elapsed_time_ms[165];
justinbuckland 3:3888b5ecad7e 54 float camera_offset_ms[165];
justinbuckland 3:3888b5ecad7e 55
justinbuckland 3:3888b5ecad7e 56 int RT_ramp_time_ms = 1000;
justinbuckland 3:3888b5ecad7e 57 int RT_hold_time_ms = 4000;
justinbuckland 4:629ca12c04f4 58 float RT_resistance = 0.470;
justinbuckland 3:3888b5ecad7e 59
justinbuckland 3:3888b5ecad7e 60
justinbuckland 4:629ca12c04f4 61 int hotstart_ramp_time_ms = 0;
justinbuckland 4:629ca12c04f4 62 int hotstart_hold_time_ms = 5000;
justinbuckland 4:629ca12c04f4 63 float hotstart_resistance = 0.470;
justinbuckland 3:3888b5ecad7e 64
justinbuckland 4:629ca12c04f4 65 int low_ramp_time_ms = 0;
justinbuckland 4:629ca12c04f4 66 int low_hold_time_ms = 2000;
justinbuckland 4:629ca12c04f4 67 float low_resistance = 0.400;
justinbuckland 3:3888b5ecad7e 68
justinbuckland 4:629ca12c04f4 69 int high_ramp_time_ms = 0;
justinbuckland 4:629ca12c04f4 70 int high_hold_time_ms = 2000;
justinbuckland 4:629ca12c04f4 71 float high_resistance = 0.470;
justinbuckland 3:3888b5ecad7e 72
justinbuckland 3:3888b5ecad7e 73 int n_cycles = 40;
justinbuckland 3:3888b5ecad7e 74 int camera_time_ms = 1000;
omatthews 0:388a2a9f5247 75
omatthews 0:388a2a9f5247 76 void write_message()
omatthews 0:388a2a9f5247 77 {
omatthews 0:388a2a9f5247 78 pc.printf("%d ",message_length);
omatthews 0:388a2a9f5247 79 wait_ms(20);
omatthews 0:388a2a9f5247 80 for (int i = 0; i < message_length; i++)
omatthews 0:388a2a9f5247 81 {
omatthews 0:388a2a9f5247 82 pc.printf("%02X ",buffer[i]);
omatthews 0:388a2a9f5247 83 }
omatthews 0:388a2a9f5247 84 }
omatthews 0:388a2a9f5247 85
omatthews 0:388a2a9f5247 86
omatthews 0:388a2a9f5247 87 void encode_message()
omatthews 0:388a2a9f5247 88 {
omatthews 0:388a2a9f5247 89 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
omatthews 0:388a2a9f5247 90 status = pb_encode(&ostream, memspcr_ExperimentConfiguration_fields, &exp_config);
omatthews 0:388a2a9f5247 91 message_length = ostream.bytes_written;
omatthews 0:388a2a9f5247 92
omatthews 0:388a2a9f5247 93 if (!status)
omatthews 0:388a2a9f5247 94 {
omatthews 0:388a2a9f5247 95 pc.printf("Encoding failed: %s\n", PB_GET_ERROR(&ostream));
omatthews 0:388a2a9f5247 96 }
omatthews 0:388a2a9f5247 97 }
omatthews 0:388a2a9f5247 98
omatthews 0:388a2a9f5247 99 bool encode_callback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
omatthews 0:388a2a9f5247 100 {
omatthews 0:388a2a9f5247 101 vector <memspcr_ThermalStep> * elements = (vector <memspcr_ThermalStep> *)(*arg);
omatthews 0:388a2a9f5247 102 vector <memspcr_ThermalStep>::iterator it;
omatthews 0:388a2a9f5247 103
omatthews 0:388a2a9f5247 104 for (it = elements->begin(); it < elements->end(); it ++)
omatthews 0:388a2a9f5247 105 {
omatthews 0:388a2a9f5247 106 if (!pb_encode_tag_for_field(stream, field))
omatthews 0:388a2a9f5247 107 {
omatthews 0:388a2a9f5247 108 printf("Encode callback error: %s\n", PB_GET_ERROR(stream));
omatthews 0:388a2a9f5247 109 return false;
omatthews 0:388a2a9f5247 110 }
omatthews 0:388a2a9f5247 111 if(!pb_encode_submessage(stream, memspcr_ThermalStep_fields, &(*it)))
omatthews 0:388a2a9f5247 112 return false;
omatthews 0:388a2a9f5247 113 }
omatthews 0:388a2a9f5247 114 return true;
omatthews 0:388a2a9f5247 115 }
omatthews 0:388a2a9f5247 116
omatthews 0:388a2a9f5247 117
omatthews 0:388a2a9f5247 118 int main()
omatthews 0:388a2a9f5247 119 {
justinbuckland 3:3888b5ecad7e 120 float melt_resistance_step;
justinbuckland 3:3888b5ecad7e 121
omatthews 0:388a2a9f5247 122 /* This is the buffer where we will store our message. */
omatthews 0:388a2a9f5247 123 pc.baud(115200);
omatthews 0:388a2a9f5247 124 n_points = sizeof(resistance)/sizeof(float);
omatthews 0:388a2a9f5247 125 buffer_length = sizeof(buffer)/sizeof(uint8_t);
omatthews 0:388a2a9f5247 126
justinbuckland 3:3888b5ecad7e 127 // //Prepare temperature profile for melt curve with 100 images
justinbuckland 3:3888b5ecad7e 128 // melt_resistance_step = (melt_resistance_end - melt_resistance_start)/100;
justinbuckland 3:3888b5ecad7e 129 //
justinbuckland 3:3888b5ecad7e 130 // //Initial setpoint
justinbuckland 3:3888b5ecad7e 131 // resistance[0] = 0.450;
justinbuckland 3:3888b5ecad7e 132 // elapsed_time_ms[0] = 0;
justinbuckland 3:3888b5ecad7e 133 // camera_offset_ms[0] = 0;
justinbuckland 3:3888b5ecad7e 134 //
justinbuckland 3:3888b5ecad7e 135 // //Ramp to start of melt curve
justinbuckland 3:3888b5ecad7e 136 // resistance[1] = melt_resistance_start;
justinbuckland 3:3888b5ecad7e 137 // elapsed_time_ms[1] = 2500;
justinbuckland 3:3888b5ecad7e 138 // camera_offset_ms[1] = 0;
justinbuckland 3:3888b5ecad7e 139 //
justinbuckland 3:3888b5ecad7e 140 // //Hold at start of melt curve
justinbuckland 3:3888b5ecad7e 141 // resistance[2] = melt_resistance_start;
justinbuckland 3:3888b5ecad7e 142 // elapsed_time_ms[2] = 5000;
justinbuckland 3:3888b5ecad7e 143 // camera_offset_ms[2] = 0;
justinbuckland 3:3888b5ecad7e 144 //
justinbuckland 3:3888b5ecad7e 145 // //Ramp temperature and obtain 100 images
justinbuckland 3:3888b5ecad7e 146 // for (i = 0; i < 100; i++)
justinbuckland 3:3888b5ecad7e 147 // {
justinbuckland 3:3888b5ecad7e 148 // resistance[i+3] = resistance[i+2] + melt_resistance_step;
justinbuckland 3:3888b5ecad7e 149 // elapsed_time_ms[i+3] = elapsed_time_ms[i+2] + logging_interval_ms;
justinbuckland 3:3888b5ecad7e 150 // camera_offset_ms[i+3] = 10;
justinbuckland 3:3888b5ecad7e 151 // }
justinbuckland 3:3888b5ecad7e 152 //
justinbuckland 3:3888b5ecad7e 153
justinbuckland 3:3888b5ecad7e 154 //Prepare temperature profile for RT-PCR with hotstart and 40 cycles
justinbuckland 3:3888b5ecad7e 155
justinbuckland 3:3888b5ecad7e 156 //RT
justinbuckland 4:629ca12c04f4 157 resistance[0] = 0.440;
justinbuckland 3:3888b5ecad7e 158 elapsed_time_ms[0] = 0;
justinbuckland 3:3888b5ecad7e 159 camera_offset_ms[0] = 0;
justinbuckland 3:3888b5ecad7e 160
justinbuckland 3:3888b5ecad7e 161 resistance[1] = RT_resistance;
justinbuckland 3:3888b5ecad7e 162 elapsed_time_ms[1] = RT_ramp_time_ms;
justinbuckland 3:3888b5ecad7e 163 camera_offset_ms[1] = 0;
justinbuckland 3:3888b5ecad7e 164
justinbuckland 3:3888b5ecad7e 165 resistance[2] = RT_resistance;
justinbuckland 3:3888b5ecad7e 166 elapsed_time_ms[2] = elapsed_time_ms[1] + RT_hold_time_ms;
justinbuckland 3:3888b5ecad7e 167 camera_offset_ms[2] = 0;
justinbuckland 3:3888b5ecad7e 168
justinbuckland 3:3888b5ecad7e 169 //Hotstart
justinbuckland 3:3888b5ecad7e 170 resistance[3] = RT_resistance;
justinbuckland 3:3888b5ecad7e 171 elapsed_time_ms[3] = elapsed_time_ms[2] + hotstart_ramp_time_ms;
justinbuckland 3:3888b5ecad7e 172 camera_offset_ms[3] = 0;
justinbuckland 3:3888b5ecad7e 173
justinbuckland 3:3888b5ecad7e 174 resistance[4] = RT_resistance;
justinbuckland 3:3888b5ecad7e 175 elapsed_time_ms[4] = elapsed_time_ms[3] + hotstart_hold_time_ms;
justinbuckland 3:3888b5ecad7e 176 camera_offset_ms[4] = 0;
justinbuckland 3:3888b5ecad7e 177
justinbuckland 3:3888b5ecad7e 178 //Thermocycle
justinbuckland 3:3888b5ecad7e 179 for (i = 0; i < 4*n_cycles; i=i+4)
justinbuckland 3:3888b5ecad7e 180 {
justinbuckland 3:3888b5ecad7e 181 // ramp high
justinbuckland 3:3888b5ecad7e 182 resistance[i+4] = high_resistance;
justinbuckland 3:3888b5ecad7e 183 elapsed_time_ms[i+4] = elapsed_time_ms[i+3] + high_ramp_time_ms;
justinbuckland 3:3888b5ecad7e 184 camera_offset_ms[i+4] = 0;
justinbuckland 3:3888b5ecad7e 185 // hold high
justinbuckland 3:3888b5ecad7e 186 resistance[i+5] = high_resistance;
justinbuckland 3:3888b5ecad7e 187 elapsed_time_ms[i+5] = elapsed_time_ms[i+4] + high_hold_time_ms;
justinbuckland 3:3888b5ecad7e 188 camera_offset_ms[i+5] = 0;
justinbuckland 3:3888b5ecad7e 189 // ramp low
justinbuckland 3:3888b5ecad7e 190 resistance[i+6] = low_resistance;
justinbuckland 3:3888b5ecad7e 191 elapsed_time_ms[i+6] = elapsed_time_ms[i+5] + low_ramp_time_ms;
justinbuckland 3:3888b5ecad7e 192 camera_offset_ms[i+6] = 0;
justinbuckland 3:3888b5ecad7e 193 // hold low
justinbuckland 3:3888b5ecad7e 194 resistance[i+7] = low_resistance;
justinbuckland 3:3888b5ecad7e 195 elapsed_time_ms[i+7] = elapsed_time_ms[i+6] + low_hold_time_ms;
justinbuckland 3:3888b5ecad7e 196 camera_offset_ms[i+7] = low_hold_time_ms - camera_time_ms;
justinbuckland 3:3888b5ecad7e 197 }
justinbuckland 3:3888b5ecad7e 198
justinbuckland 4:629ca12c04f4 199 for (i = 0; i < n_points; i++)
justinbuckland 4:629ca12c04f4 200 {
justinbuckland 4:629ca12c04f4 201 memspcr_ThermalStep step = memspcr_ThermalStep_init_zero;
justinbuckland 4:629ca12c04f4 202 step.resistance = resistance[i];
justinbuckland 4:629ca12c04f4 203 step.elapsed_time_ms = elapsed_time_ms[i];
justinbuckland 4:629ca12c04f4 204 step.camera_offset_ms = camera_offset_ms[i];
justinbuckland 4:629ca12c04f4 205 profile.push_back(step);
justinbuckland 4:629ca12c04f4 206 }
justinbuckland 4:629ca12c04f4 207
omatthews 0:388a2a9f5247 208 //Set set points
omatthews 2:b46d53a5f931 209 exp_config.profile.arg = &profile;
omatthews 2:b46d53a5f931 210 exp_config.profile.funcs.encode = encode_callback;
justinbuckland 4:629ca12c04f4 211 //exp_config.thermal.guard_drive_ratio = 0.26;
omatthews 0:388a2a9f5247 212 exp_config.thermal.adc_settling_time_us = 60;
omatthews 2:b46d53a5f931 213 exp_config.thermal.pid_kp = 4;
omatthews 2:b46d53a5f931 214 exp_config.thermal.pid_integral_time = 0.75;
omatthews 2:b46d53a5f931 215 exp_config.thermal.control_loop_interval_ms = 4;
omatthews 0:388a2a9f5247 216 exp_config.optics.pre_trigger_ms = 1;
omatthews 0:388a2a9f5247 217 exp_config.optics.on_time_ms = 1;
omatthews 0:388a2a9f5247 218 exp_config.optics.led_pwm = 0.5;
omatthews 0:388a2a9f5247 219 exp_config.fluidics.pressure_setpoint = 0.4;
omatthews 0:388a2a9f5247 220 exp_config.fluidics.pressure_hysterisis = 0.01;
justinbuckland 3:3888b5ecad7e 221 exp_config.logging_interval_ms = logging_interval_ms;
omatthews 2:b46d53a5f931 222 exp_config.selected_heater = memspcr_ExperimentConfiguration_Heater_MAIN;
omatthews 2:b46d53a5f931 223
omatthews 0:388a2a9f5247 224 encode_message();
omatthews 0:388a2a9f5247 225 write_message();
omatthews 0:388a2a9f5247 226
omatthews 0:388a2a9f5247 227 return 0;
omatthews 0:388a2a9f5247 228 }