Newer
Older
Malaurie Bernard
committed
#include "syringefilled.h"
Malaurie Bernard
committed
SyringeFilled :: SyringeFilled (MotorHardware_t& stepper): Motor(stepper)
Malaurie Bernard
committed
{
set_exchange_throughput_uL_per_sec(1);
set_exchange_volume_mL(1);
set_remaining_volume_mL(1);
set_push(true);
Malaurie Bernard
committed
set_name_syringe("300912");
Malaurie Bernard
committed
set_screw_thread_mm(4);
set_clockwise_equals_push(true);
set_emergency(false);
}
Malaurie Bernard
committed
Malaurie Bernard
committed
void SyringeFilled :: set_exchange_throughput_uL_per_sec(float exchange_throughput_uL_per_sec)
{
SyringeFilledJSON["exchange_throughput_uL_per_sec"] = exchange_throughput_uL_per_sec;
Malaurie Bernard
committed
}
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;
}
Malaurie Bernard
committed
void SyringeFilled :: set_name_syringe(Syringe* name_syringe){
SyringeFilledJSON["name_syringe"] = name_syringe;
Malaurie Bernard
committed
}
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
committed
Malaurie Bernard
committed
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>();
}
Malaurie Bernard
committed
String SyringeFilled :: get_name_syringe()
Malaurie Bernard
committed
{
Malaurie Bernard
committed
return SyringeFilledJSON["name_syringe"].as<String>();
Malaurie Bernard
committed
}
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>();
}
Malaurie Bernard
committed
//CONVERSIONS
StaticJsonDocument<200> SyringeFilledJSON; //200 = RAM allocated to this document
Malaurie Bernard
committed
float SyringeFilled::volume_to_distance(float volume_mL)
/***
-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 = Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["internal_diameter"];
float distance_mm = volume_mm3/piston_surface_mm2;
return distance_mm;
}
Malaurie Bernard
committed
float SyringeFilled::distance_to_volume(float distance_mm)
Malaurie Bernard
committed
/***
-Argument : distance in mm.
-Return : The volume associated in mL.
-Action : /
***/
{
float piston_surface_mm2 = Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["internal_diameter"];
Malaurie Bernard
committed
float volume_mm3 = distance_mm*piston_surface_mm2;
return volume_mm3;
}
Malaurie Bernard
committed
//MOVEMENTS
Malaurie Bernard
committed
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 = Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["internal_diameter_mm"];
float section_mm2 = M_PI*radius*radius;
set_speed_mm_per_sec(get_exchange_throughput_uL_per_sec()/section_mm2);
if (where_step() == 0) //If we are putting the syringe for the first time
{
move_to_mm(syringe_pump_length_mm - remaining_volume_mm3/section_mm2);
}
else
{
float initial_position_mm = syringe_pump_length_mm - remaining_volume_mm3/section_mm2;
if (get_push()) //If we want to deliver some liquid
{
move_to_mm(initial_position_mm + exchange_volume_mm3/section_mm2);
}
else //If we want to recover some liquid
{
move_to_mm(initial_position_mm - exchange_volume_mm3/section_mm2);
}
}
}
Malaurie Bernard
committed
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
{
reset_position();
move_to_mm(-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
{
set_emergency(true);
if (at_zero) //if we are at te initialisation place
{
Serial.printf("EMERGENCY: Pressed by someone\n");
}
}
else
{
set_emergency(false);
Serial.printf("EMERGENCY: released\n");
stay_here();
reset_position(); //zero is here again
Serial.printf("ZERO: reset\n");
}
}
Malaurie Bernard
committed
void SyringeFilled::run_from_emergency()
/***
-Argument : /
-Return : /
-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(syringe_pump_length_mm);
Malaurie Bernard
committed
}
//CONFIGURATION
Malaurie Bernard
committed
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 (Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["internal_diameter"] <= 0)
Malaurie Bernard
committed
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;
}
Malaurie Bernard
committed
void SyringeFilled :: show_configuration()
/***
-Argument : /
-Return : /
-Action : Displays syringe filled attributes
***/
{
Motor::show_configuration();
Malaurie Bernard
committed
auto step = where_step();
Malaurie Bernard
committed
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",
Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["internal_diameter"],
Syringe :: get_syringe_database()[SyringeFilledJSON["name_syringe"]]["total_volume_mL"],
Malaurie Bernard
committed
get_exchange_throughput_uL_per_sec(),
Malaurie Bernard
committed
volume_to_distance(get_exchange_throughput_uL_per_sec()),
Malaurie Bernard
committed
get_remaining_volume_mL(),
get_push()? "infuse": "withdraw",
get_emergency(),
step_to_mm(step));
Malaurie Bernard
committed
}
Malaurie Bernard
committed
Malaurie Bernard
committed
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
//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);
}