Skip to content
Snippets Groups Projects
syringefilled.cpp 8.35 KiB
Newer Older
Malaurie Bernard's avatar
Malaurie Bernard committed
//CONSTRUCTORS
SyringeFilled :: SyringeFilled() : Motor (&ISRStepper) //pb with my motor constructor
{
    set_exchange_throughput_uL_per_sec(1);
    set_exchange_volume_mL(1);
    set_remaining_volume_mL(1);
    set_push(true);
    set_screw_thread_mm(4);
    set_clockwise_equals_push(true);
    set_emergency(false);

}

Malaurie Bernard's avatar
Malaurie Bernard committed
//SET METHODS
void SyringeFilled :: set_exchange_throughput_uL_per_sec(float exchange_throughput_uL_per_sec)
{
Malaurie Bernard's avatar
Malaurie Bernard committed
    SyringeFilledJSON["exchange_throughput_uL_per_sec"] = exchange_throughput_uL_per_sec;
}

void SyringeFilled :: set_exchange_volume_mL(float exchange_volume_mL)
{
    SyringeFilledJSON["exchange_volume_mL"] = exchange_volume_mL;
}

void SyringeFilled :: set_remaining_volume_mL(float remaining_volume_mL)
{
    SyringeFilledJSON["remaining_volume_mL"] = remaining_volume_mL;
}

void SyringeFilled :: set_push(bool push)
{
    SyringeFilledJSON["push"] = push;
}

void SyringeFilled :: set_id_syringe(Syringe* id_syringe){
    SyringeFilledJSON["id_syringe"] = id_syringe;
void SyringeFilled :: set_screw_thread_mm(float screw_thread_mm)
{
    SyringeFilledJSON["screw_thread_mm"] = screw_thread_mm;
}

void SyringeFilled :: set_clockwise_equals_push(bool clockwise_equals_push)
    SyringeFilledJSON["clockwise_equals_push"] = clockwise_equals_push;
}

void SyringeFilled :: set_emergency(bool emergency)
{
    SyringeFilledJSON["emergency"] = emergency;
Malaurie Bernard's avatar
Malaurie Bernard committed
//GET METHODS
float SyringeFilled :: get_exchange_throughput_uL_per_sec()
{
    return SyringeFilledJSON["exchange_throughput_uL_per_sec"].as<float>();
}

float SyringeFilled :: get_exchange_volume_mL()
{
    return SyringeFilledJSON["exchange_volume_mL"].as<float>();
}

float SyringeFilled :: get_remaining_volume_mL()
{
    return SyringeFilledJSON["remaining_volume_mL"].as<float>();
}

bool SyringeFilled :: get_push()
{
    return SyringeFilledJSON["push"].as<bool>();
}

Syringe* SyringeFilled :: get_id_syringe()
    return SyringeFilledJSON["id_syringe"].as<Syringe*>();
float SyringeFilled :: get_screw_thread_mm()
{
    return SyringeFilledJSON["screw_thread_mm"].as<float>();
}

bool SyringeFilled :: get_clockwise_equals_push()
    return SyringeFilledJSON["clockwise_equals_push"].as<float>();
bool SyringeFilled :: get_emergency()
{
    return SyringeFilledJSON["emergency"].as<bool>();
}
//CONVERSIONS
    
float SyringeFilled::volume_to_distance(float volume_mL, Syringe* id_syringe)
/***
-Argument : Volume in mL.
-Return   : The distance to cover associated in mm.
-Action   : /
***/
{
    float volume_mm3 = 1000*volume_mL; //mL->mm3

    float piston_surface_mm2 = id_syringe->get_internal_diameter_mm();

    float distance_mm = volume_mm3/piston_surface_mm2;

    return distance_mm;
}

float SyringeFilled::distance_to_volume(float distance_mm, Syringe* id_syringe)
/***
-Argument : distance in mm.
-Return   : The volume associated in mL.
-Action   : /
***/
{
    float piston_surface_mm2 = id_syringe->get_internal_diameter_mm();

    float volume_mm3 = distance_mm*piston_surface_mm2;

    return volume_mm3;
}
float SyringeFilled :: move()
/***
-Argument : / (We're using informations stored in the class itself)
-Return   : /
-Action   : Move the syringe filled to deliver or recover the volume expected
***/
{
    //Conversions of volumes
    float remaining_volume_mm3 = get_remaining_volume_mL()*1000;
    float exchange_volume_mm3 = get_exchange_volume_mL()*1000;

    //Find the section
    float radius = get_id_syringe()->get_internal_diameter_mm();
    float section_mm2 = M_PI*radius*radius;


    setSpeedMmPerSec(get_exchange_throughput_uL_per_sec()/section_mm2);


    if (whereStep() == 0) //If we are putting the syringe for the first time
    {
        moveToMm(syringe_pump_length_mm - remaining_volume_mm3/section_mm2);
        float initial_position_mm = syringe_pump_length_mm - remaining_volume_mm3/section_mm2;
        
        if (get_push()) //If we want to deliver some liquid
        {
            moveToMm(initial_position_mm + exchange_volume_mm3/section_mm2);
        }
        else //If we want to recover some liquid
        {
            moveToMm(initial_position_mm - exchange_volume_mm3/section_mm2);
        }
        }

}
void SyringeFilled :: go_to_zero()
/***
-Argument : / (We're using informations stored in the class itself)
-Return   : /
-Action   : Move the syringe filled to deliver or recover the volume expected
***/
{
    if (get_emergency())
        return;
    else
    {
    resetPosition();
    moveToMm(-syringe_pump_length_mm);
    }

}


//LIMIT SWITCH

void SyringeFilled::manage_emergency (bool pressed, bool at_zero)
/***
-Argument : two boolean to know the position of the limit switch and if we are a the zero
-Return   : /
-Action   : Manage different emergency cases (move the pump if necessary)
***/
{
    if (pressed)  //if the limit switch is pressed
    {
        if (at_zero) //if we are at te initialisation place
        {
Malaurie Bernard's avatar
Malaurie Bernard committed
            run_from_emergency();
            Serial.printf("EMERGENCY: Pressed by someone\n");
        Serial.printf("EMERGENCY: released\n");
        stayHere();
        resetPosition();  //zero is here again
        Serial.printf("ZERO: reset\n");
    }
}
void SyringeFilled::run_from_emergency()
/***
-Argument : /
-Return   : /
Malaurie Bernard's avatar
Malaurie Bernard committed
-Action   : Move the pump slowly until the limit switch is released
***/
{
if (get_emergency())
    {
        Serial.printf("EMERGENCY: running away slowly\n");
        setSpeedMmPerSec(-1);
        resetPosition();
        moveToMm(syringe_pump_length_mm);
    }


bool SyringeFilled :: check_configuration()
/***
-Argument : /
-Return   : A boolean true(everything is fine), false(at least one attribut is'nt correct)
-Action   : Check if the values are correct.
***/
{
    if (get_id_syringe()->get_internal_diameter_mm() <= 0)
        return false;

    if (get_exchange_volume_mL() < 0)
        return false;

    if (get_remaining_volume_mL() <= 0)
        return false;

    if (get_exchange_throughput_uL_per_sec() <= 0)
        return false;


    return true;

}

void SyringeFilled :: show_configuration()
/***
-Argument : /
-Return   : /
-Action   : Displays syringe filled attributes
***/
{
    Motor::showConfiguration();

    auto step = whereStep();

    Serial.printf("#     push clockwise: %s\n"
                  "#     diameter: %g mm\n"
                  "#     capacity: %g uL\n"
                  "#     rate: %g uL/s = %g mm/s\n"
                  "#     volume remaining: %g uL (target)\n"
                  "#     direction: %s\n"
                  "#     emergency: %d\n"
                  "#     current position: %g mm\n",
                  get_clockwise_equals_push()? "yes": "no",
                  get_id_syringe()->get_internal_diameter_mm(),
                  get_id_syringe()->get_total_volume_mL(),
                  get_exchange_throughput_uL_per_sec(),
                  volume_to_distance(get_exchange_throughput_uL_per_sec(), get_id_syringe()),
                  get_remaining_volume_mL(),
                  get_push()? "infuse": "withdraw",
                  get_emergency(),
                  stepToMm(step));
}
//Example : File f = ({ InterruptLock lock; filesystem->open(filename, "w"); }); and the f becomes the argument output_stream
//useful in web.cpp via a button to save data
void SyringeFilled :: write_Json (Stream& output_stream) //file_name sera le nom du fichier Json, doc sera la structure Json qu'on veut transformer en fichier
{ 
/***
-Argument : output_stream (= serial or a file)
-Return   : /
-Action   : Save the Json structure in a file (convert it to text)
***/

InterruptLock lock; //useful thanks to its constructor (so a is not visible in the code)
serializeJson(SyringeFilledJSON, output_stream);
  
}


//useful in setup of pousse-seringue.cpp(to check at the begining what has already been saved) and web.cpp via a button to recover data
void SyringeFilled :: read_Json (Stream& input_stream) //file_name sera le nom du fichier Json, doc sera la structure Json qu'on veut transformer en fichier
{
/***
-Argument : input_stream (= serial or a file)
-Return   : /
-Action   : Check if a Json Document alredy exist or not
***/

InterruptLock lock; //useful thanks to its constructor (so a is not visible in the code)
deserializeJson(SyringeFilledJSON, input_stream);
  

}