Skip to content
Snippets Groups Projects
syringefilled.cpp 12.1 KiB
Newer Older
ISRStepper stepper(AccelStepper::DRIVER, STEP, DIR);

SyringeFilled syringe_filled(stepper);


Malaurie Bernard's avatar
Malaurie Bernard committed
//CONSTRUCTORS
SyringeFilled :: SyringeFilled (MotorHardware_t& stepper): Motor(stepper)
Malaurie Bernard's avatar
Malaurie Bernard committed
    set_exchange_throughput_uL_per_min(1);
    set_exchange_volume_mL(1);
    set_remaining_volume_mL(1);
    set_push(true);
Malaurie Bernard's avatar
Malaurie Bernard committed
    set_throughput(true);
    set_update_remaining_volume(false);
    set_name_syringe("BD_5mL");
    set_syringe_pump_length_mm(50);
    set_microstep_configuration(16);
    set_motor_steps(200);
    set_motor_release(false);
Malaurie Bernard's avatar
Malaurie Bernard committed
//SET METHODS
Malaurie Bernard's avatar
Malaurie Bernard committed
void SyringeFilled :: set_exchange_throughput_uL_per_min(float exchange_throughput_uL_per_min)
Malaurie Bernard's avatar
Malaurie Bernard committed
    syringe_filled_json["exchange_throughput_uL_per_min"] = exchange_throughput_uL_per_min;
}

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

void SyringeFilled :: set_remaining_volume_mL(float remaining_volume_mL)
{
    syringe_filled_json["remaining_volume_mL"] = remaining_volume_mL;
Malaurie Bernard's avatar
Malaurie Bernard committed
void SyringeFilled :: set_throughput(bool throughput)
{
    syringe_filled_json["throughput"] = throughput;
}

void SyringeFilled :: set_update_remaining_volume(bool update_remaining_volume)
{
    syringe_filled_json["update_remaining_volume"] = update_remaining_volume;
}

void SyringeFilled :: set_name_syringe(String name_syringe)
    syringe_filled_json["name_syringe"] = name_syringe;
void SyringeFilled :: set_clockwise_equals_push(bool clockwise_equals_push)
    syringe_filled_json["clockwise_equals_push"] = clockwise_equals_push;
void SyringeFilled :: set_syringe_pump_length_mm(float syringe_pump_length_mm)
{
    syringe_filled_json["syringe_pump_length_mm"] = syringe_pump_length_mm;
}

void SyringeFilled :: set_lead_screw_pitch_mm(float lead_screw_pitch_mm)
{
    syringe_filled_json["lead_screw_pitch_mm"] = lead_screw_pitch_mm;
}

void SyringeFilled :: set_microstep_configuration(int microstep_configuration)
{
    syringe_filled_json["microstep_configuration"] = microstep_configuration;
}

void SyringeFilled :: set_motor_steps(int motor_steps)
{
    syringe_filled_json["motor_steps"] = motor_steps;
}

void SyringeFilled :: set_motor_release(int motor_release)
{
    syringe_filled_json["motor_release"] = motor_release;
}

void SyringeFilled :: set_emergency(bool emergency)
{
Malaurie Bernard's avatar
Malaurie Bernard committed
//GET METHODS
float SyringeFilled :: get_exchange_throughput_uL_per_min()
    return syringe_filled_json["exchange_throughput_uL_per_min"].as<float>();
    return syringe_filled_json["exchange_volume_mL"].as<float>();
    return syringe_filled_json["remaining_volume_mL"].as<float>();
Malaurie Bernard's avatar
Malaurie Bernard committed
bool SyringeFilled :: get_throughput()
{
    return syringe_filled_json["throughput"].as<bool>();
}

bool SyringeFilled :: get_update_remaining_volume()
{
    return syringe_filled_json["update_remaining_volume"].as<bool>();
}

String SyringeFilled :: get_syringe_name()
    return syringe_filled_json["name_syringe"].as<String>();
bool SyringeFilled :: get_clockwise_equals_push()
    return syringe_filled_json["clockwise_equals_push"].as<bool>();
}

float SyringeFilled :: get_syringe_pump_length_mm()
{
    return syringe_filled_json["syringe_pump_length_mm"].as<float>();
float SyringeFilled :: get_lead_screw_pitch_mm()
{
    return syringe_filled_json["lead_screw_pitch_mm"].as<float>();
}

int SyringeFilled :: get_microstep_configuration()
{
    return syringe_filled_json["microstep_configuration"].as<int>();
}

int SyringeFilled :: get_motor_steps()
{
    return syringe_filled_json["motor_steps"].as<int>();
}

bool SyringeFilled :: get_motor_release()
{
    return syringe_filled_json["motor_release"].as<bool>();
}

bool SyringeFilled :: get_emergency()
{
const StaticJsonDocument<200>& SyringeFilled :: get_syringe_filled_data()
{
StaticJsonDocument<200> syringe_filled_json;  //200 = RAM allocated to this document

float SyringeFilled::volume_mL_to_distance_mm(float volume_mL)
/***
-Argument : Volume in mL.
-Return   : The distance to cover associated in mm.
-Action   : /
***/
{
    float volume_mm3 = 1000 * volume_mL; //mL->mm3

Malaurie Bernard's avatar
Malaurie Bernard committed
    float piston_radius_mm = (syringe.get_syringe_database()[syringe_filled.get_syringe_name().c_str()]["internal_diameter_mm"]).as<float>()/2;
    float piston_surface_mm2 = M_PI * piston_radius_mm * piston_radius_mm;
    float distance_mm = volume_mm3 / piston_surface_mm2;
float SyringeFilled::distance_mm_to_volume_mL(float distance_mm)
/***
-Argument : distance in mm.
-Return   : The volume associated in mL.
-Action   : /
***/
{
Malaurie Bernard's avatar
Malaurie Bernard committed
    float piston_radius_mm = (syringe.get_syringe_database()[syringe_filled.get_syringe_name().c_str()]["internal_diameter_mm"]).as<float>()/2;

    float piston_surface_mm2 = M_PI * piston_radius_mm * piston_radius_mm;

    float volume_mm3 = distance_mm * piston_surface_mm2;
    float volume_mL = volume_mm3 / 1000;
    return volume_mL;
bool SyringeFilled :: is_running ()  //return true if the motor is currently running
/***
-Argument : /
-Return   : A boolean to indicates if the motor is running.
-Action   : /
***/
{
    return motor_is_running();
}

/***
-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 exchange_volume_mm3 = get_exchange_volume_mL()*1000;

    //Find the section
Malaurie Bernard's avatar
Malaurie Bernard committed
    float piston_radius_mm = (syringe.get_syringe_database()[syringe_filled.get_syringe_name().c_str()]["internal_diameter_mm"]).as<float>()/2;
Malaurie Bernard's avatar
Malaurie Bernard committed
    float piston_surface_mm2 = M_PI * piston_radius_mm * piston_radius_mm;

    digitalWrite(SLEEP, LOW); //on met en route le moteur
Malaurie Bernard's avatar
Malaurie Bernard committed
    set_speed_mm_per_sec(get_exchange_throughput_uL_per_min()/piston_surface_mm2);
    
    if (get_push()) //If we want to deliver some liquid
Malaurie Bernard's avatar
Malaurie Bernard committed
        reset_position();
        move_to_mm_limit_switch(_clockwise_equals_push? volume_mL_to_distance_mm(get_exchange_volume_mL()): -volume_mL_to_distance_mm(get_exchange_volume_mL()));
Malaurie Bernard's avatar
Malaurie Bernard committed
        reset_position();
        move_to_mm_limit_switch(_clockwise_equals_push? -volume_mL_to_distance_mm(get_exchange_volume_mL()): volume_mL_to_distance_mm(get_exchange_volume_mL()));
void SyringeFilled :: go_to_limit_switch()
/***
-Argument : / (We're using informations stored in the class itself)
-Return   : /
-Action   : Move the syringe filled to deliver or recover the volume expected
***/
{
    digitalWrite(SLEEP, LOW);
    set_speed_mm_per_sec(-1);
    move_to_mm_limit_switch(_clockwise_equals_push? -200: 200);
//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
    {
Malaurie Bernard's avatar
Malaurie Bernard committed
        save_json();
        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");
Malaurie Bernard's avatar
Malaurie Bernard committed
        save_json();
        Serial.printf("EMERGENCY: released\n");
        reset_position();  //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");
        set_speed_mm_per_sec(-1);
        reset_position();
        move_to_mm_limit_switch(_clockwise_equals_push? 200: -200);

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_exchange_throughput_uL_per_min() <= 0)
    if (get_exchange_volume_mL() < 0)
    if (get_remaining_volume_mL() < 0)
    if (!((get_push()==true) || (get_push()==false)))
    if (!((get_clockwise_equals_push()==true) || (get_clockwise_equals_push()==false)))
        return false;

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

    if (get_lead_screw_pitch_mm() <= 0)
    if (get_microstep_configuration() <= 0)
        return false;

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

    if (!((get_motor_release()==true) || (get_motor_release()==false)))
    if (!((get_emergency()==true) || (get_emergency()==false)))
void SyringeFilled :: show_configuration()
/***
-Argument : /
-Return   : /
-Action   : Displays syringe filled attributes
***/
{
    //Motor::show_configuration();
Serial.println(String("Exchange_throughput :") + String(get_exchange_throughput_uL_per_min()) + String(" in uL/min"));
Serial.println(String("Exchange_volume : ")  + String(get_exchange_volume_mL())+ String(" in mL"));
Serial.println(String("Remaining_volume : ")  + String(get_remaining_volume_mL())+ String(" in mL"));
Serial.println(String("Push : ") +  String(get_push()));
Serial.println(String("Syringe_name : ") + String(get_syringe_name()));
Serial.println(String("Clockwise_equals_push : ") + String(get_clockwise_equals_push()));
Serial.println(String("Syringe_pump_length : ") + String(get_syringe_pump_length_mm()) + String(" in mm") );
Serial.println(String("Lead_screw_pitch : ") + String(get_lead_screw_pitch_mm()) + String(" in mm"));
Serial.println(String("Microstep_configuration : ") + String(get_microstep_configuration()) + String(" in step"));
Serial.println(String("Motor_steps : ") + String(get_motor_steps()) + String(" in step"));
Serial.println(String("Motor_release : ") + String(get_motor_release()));
Serial.println(String("Emergency : ") + String(get_emergency()));
Serial.println(String("Total_volume : ") + String(syringe.get_syringe_database()[syringe_filled.get_syringe_name().c_str()]["total_volume_mL"]));
Serial.println(String("Internal_diameter : ") + String(syringe.get_syringe_database()[syringe_filled.get_syringe_name().c_str()]["internal_diameter_mm"]));
//Example : File f = ({ InterruptLock lock; filesystem->open(filename, "w"); }); and the f becomes the argument input_stream
Malaurie Bernard's avatar
Malaurie Bernard committed
void SyringeFilled :: save_json ()
-Argument : input_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)
File f = filesystem->open("syringe_filled_json", "w"); //Creation du fichier
Malaurie Bernard's avatar
Malaurie Bernard committed
size_t a = serializeJsonPretty(syringe_filled_json, f);
Serial.println("Taille de syringe_filled_json");
Serial.println(a);
f.close();
}

//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
Malaurie Bernard's avatar
Malaurie Bernard committed
void SyringeFilled :: load_json ()
-Argument : output_stream (= serial or a file)
-Action   : Check if a Json Document alredy exist or not, if it does it is load
InterruptLock lock; //useful thanks to its constructor (so a is not visible in the code)
File f = filesystem->open("syringe_filled_json", "r"); //Creation du fichier
deserializeJson(syringe_filled_json, f);