This will generate the message for the programme

Dependencies:   MODSERIAL Nanopb

main.cpp

Committer:
justinbuckland
Date:
2019-09-20
Revision:
4:629ca12c04f4
Parent:
3:3888b5ecad7e

File content as of revision 4:629ca12c04f4:

#include "mbed.h"
#include "pb.h"
#include "pb_decode.h"
#include "pb_encode.h"
#include "memspcr.pb.h"
#include "MODSERIAL.h"
#include <vector>
#include <iterator>

#define BUFFER_SIZE 4096

MODSERIAL pc(PA_9, PA_10, BUFFER_SIZE); //mcu TX, RX, BUFFER_SIZE byte TX and RX buffers

uint8_t buffer[BUFFER_SIZE];
size_t message_length;
bool status;
int i = 0;
unsigned int c;
memspcr_ExperimentConfiguration exp_config = memspcr_ExperimentConfiguration_init_zero;
int buffer_length;
int n_points;
//int logging_interval_ms = 100;  // typical for experimental testing 
//int logging_interval_ms = 1000; // for drive electronics resistance measurement calibration
//int logging_interval_ms = 5000; // for consumable temperature calibration
int logging_interval_ms = 500;  // for melt curve measurement

std::vector<memspcr_ThermalStep> profile;

//Parameters for test ramp
//float resistance[9]     = {  0.45, 0.525, 0.525, 0.535, 0.545, 0.555, 0.555};
//int elapsed_time_ms[9]  = {     0,  1000,  2000,  3000,  4000,  5000,  6000};
//int camera_offset_ms[9] = {     0,   500,   500,   500,   500,   500,   500};

//Parameters for drive electronics resistance measurement calibration
//float resistance[2]       = {     0,     0};
//int elapsed_time_ms[2]    = {     0, 20000};
//int camera_offset_ms[2]   = {     0,     0};

//Parameters for consumable temperature calibration
//float resistance[2]       = {     0,       0};
//int elapsed_time_ms[2]    = {     0, 3600000};
//int camera_offset_ms[2]   = {     0,       0};
  
//Melt curve programmed later  
//float melt_resistance_start = 0.525;
//float melt_resistance_end = 0.550;
//float resistance[103];
//int elapsed_time_ms[103];
//int camera_offset_ms[103];    

//RT-PCR temperature profile programmed later
float resistance[165];
float elapsed_time_ms[165];
float camera_offset_ms[165];

int RT_ramp_time_ms =        1000;
int RT_hold_time_ms =        4000;
float RT_resistance =       0.470;


int hotstart_ramp_time_ms =     0;
int hotstart_hold_time_ms =  5000;
float hotstart_resistance = 0.470;

int low_ramp_time_ms =          0;
int low_hold_time_ms =       2000;
float low_resistance =      0.400;

int high_ramp_time_ms =         0;
int high_hold_time_ms =      2000;
float high_resistance =     0.470;

int n_cycles =                 40;
int camera_time_ms =         1000;

void write_message()
{
    pc.printf("%d ",message_length);
    wait_ms(20);
    for (int i = 0; i < message_length; i++) 
    {
        pc.printf("%02X ",buffer[i]);
    }
}


void encode_message()
{
    pb_ostream_t ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
    status = pb_encode(&ostream, memspcr_ExperimentConfiguration_fields, &exp_config);
    message_length = ostream.bytes_written;
    
    if (!status)
    {
        pc.printf("Encoding failed: %s\n", PB_GET_ERROR(&ostream));
    }
}

bool encode_callback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
    vector <memspcr_ThermalStep> * elements = (vector <memspcr_ThermalStep> *)(*arg);
    vector <memspcr_ThermalStep>::iterator it;

    for (it = elements->begin(); it < elements->end(); it ++)
    {
        if (!pb_encode_tag_for_field(stream, field))
        {
            printf("Encode callback error: %s\n", PB_GET_ERROR(stream));
            return false;
        }
        if(!pb_encode_submessage(stream, memspcr_ThermalStep_fields, &(*it)))
            return false;
    }
    return true;
}


int main()
{
    float melt_resistance_step;
    
    /* This is the buffer where we will store our message. */
    pc.baud(115200);
    n_points = sizeof(resistance)/sizeof(float);
    buffer_length = sizeof(buffer)/sizeof(uint8_t);

//    //Prepare temperature profile for melt curve with 100 images
//    melt_resistance_step = (melt_resistance_end - melt_resistance_start)/100;
//
//    //Initial setpoint
//    resistance[0] = 0.450;
//    elapsed_time_ms[0] = 0;
//    camera_offset_ms[0] = 0;
//    
//    //Ramp to start of melt curve
//    resistance[1] = melt_resistance_start;
//    elapsed_time_ms[1] = 2500;
//    camera_offset_ms[1] = 0;
//   
//    //Hold at start of melt curve
//    resistance[2] = melt_resistance_start;
//    elapsed_time_ms[2] = 5000;
//    camera_offset_ms[2] = 0;
//    
//    //Ramp temperature and obtain 100 images
//    for (i = 0; i < 100; i++)
//    {
//        resistance[i+3] = resistance[i+2] + melt_resistance_step;
//        elapsed_time_ms[i+3] = elapsed_time_ms[i+2] + logging_interval_ms;
//        camera_offset_ms[i+3] = 10;
//    }
//
 
//Prepare temperature profile for RT-PCR with hotstart and 40 cycles

//RT
resistance[0] = 0.440;
elapsed_time_ms[0] = 0;
camera_offset_ms[0] = 0;

resistance[1] = RT_resistance;
elapsed_time_ms[1] = RT_ramp_time_ms;
camera_offset_ms[1] = 0;

resistance[2] = RT_resistance;
elapsed_time_ms[2] = elapsed_time_ms[1] + RT_hold_time_ms;
camera_offset_ms[2] = 0;

//Hotstart
resistance[3] = RT_resistance;
elapsed_time_ms[3] = elapsed_time_ms[2] + hotstart_ramp_time_ms;
camera_offset_ms[3] = 0;

resistance[4] = RT_resistance;
elapsed_time_ms[4] = elapsed_time_ms[3] + hotstart_hold_time_ms;
camera_offset_ms[4] = 0;

//Thermocycle
for (i = 0; i < 4*n_cycles; i=i+4)
{
    // ramp high
    resistance[i+4] = high_resistance;
    elapsed_time_ms[i+4] = elapsed_time_ms[i+3] + high_ramp_time_ms;
    camera_offset_ms[i+4] = 0;
    // hold high
    resistance[i+5] = high_resistance;
    elapsed_time_ms[i+5] = elapsed_time_ms[i+4] + high_hold_time_ms;
    camera_offset_ms[i+5] = 0;
    // ramp low
    resistance[i+6] = low_resistance;
    elapsed_time_ms[i+6] = elapsed_time_ms[i+5] + low_ramp_time_ms;
    camera_offset_ms[i+6] = 0;
    // hold low
    resistance[i+7] = low_resistance;
    elapsed_time_ms[i+7] = elapsed_time_ms[i+6] + low_hold_time_ms;
    camera_offset_ms[i+7] = low_hold_time_ms - camera_time_ms;
}   

    for (i = 0; i < n_points; i++)
    {
        memspcr_ThermalStep step = memspcr_ThermalStep_init_zero;
        step.resistance = resistance[i];
        step.elapsed_time_ms = elapsed_time_ms[i];
        step.camera_offset_ms = camera_offset_ms[i];
        profile.push_back(step);
    }

    //Set set points  
    exp_config.profile.arg = &profile;
    exp_config.profile.funcs.encode = encode_callback;
    //exp_config.thermal.guard_drive_ratio = 0.26;
    exp_config.thermal.adc_settling_time_us = 60;
    exp_config.thermal.pid_kp = 4;
    exp_config.thermal.pid_integral_time = 0.75;
    exp_config.thermal.control_loop_interval_ms = 4;
    exp_config.optics.pre_trigger_ms = 1;
    exp_config.optics.on_time_ms = 1;
    exp_config.optics.led_pwm = 0.5;
    exp_config.fluidics.pressure_setpoint = 0.4;
    exp_config.fluidics.pressure_hysterisis = 0.01;
    exp_config.logging_interval_ms = logging_interval_ms;
    exp_config.selected_heater = memspcr_ExperimentConfiguration_Heater_MAIN;

    encode_message();
    write_message();

    return 0;
}