Skip to content
Snippets Groups Projects
Commit 71299291 authored by Malaurie Bernard's avatar Malaurie Bernard
Browse files

Complete modification of the syringe class with basic functions (setters and...

Complete modification of the syringe class with basic functions (setters and getters) throough a Json document
parent d9cc5a8e
No related branches found
No related tags found
1 merge request!17Malaurie's work on UI + CLI interface + AccelStepper interface
#include <math.h>
#include "syringe.h"
void Syringe::showConfiguration (const Syringe_configuration_t& conf)
/***
-Argument : Address of configuration to show
-Return : /
-Action : Displays syringe attributes
***/
{
Motor::showConfiguration();
auto step = whereStep();
Serial.printf("# push clockwise: %s"
"# diameter: %g mm\n"
"# capacity: %g uL\n"
"# rate: %g uL/s = %g mm/s\n"
"# volume: %g uL (target)\n"
"# direction: %s\n"
"# zeroing: %d\n"
"# emergency: %d\n"
"# current position: %g mm %g ul %d steps\n",
getPushClockwise()? "yes": "no",
conf.diameter_mm,
conf.capacity_ul,
conf.rate_ul_per_s,
mm3ToMm(conf.rate_ul_per_s),
conf.volume_value * conf.volume_unit_ul,
conf.direction > 0? "infuse": "withdraw",
emergency(),
stepToMm(step), mmToMm3(stepToMm(step)), step); //Current position of syringe pump in terms of displacement, volume and motor pitch
}
float Syringe::confToMm3 () const
/***
-Argument : /
-Return : Total syringe volume in mm3
-Action : /
***/
//SET METHODES
void Syringe :: set_total_volume_mL(float total_volume_mL)
{
return current_configuration.direction * current_configuration.volume_value * current_configuration.volume_unit_ul;
SyringeJSON["total_volume_mL"] = total_volume_mL;
}
float Syringe::sectionMm2 () const
/***
-Argument : /
-Return : The cross-sectional area of the syringe plunger in mm2.
-Action : /
***/
void Syringe :: set_internal_diameter_mm(float internal_diameter_mm)
{
return pow(current_configuration.diameter_mm / 2, 2) * M_PI;
SyringeJSON["internal_diameter_mm"] = internal_diameter_mm;
}
float Syringe::mm3ToMm (float mm3) const
/***
-Argument : Volume to be delivered in mm3.
-Return : Distance to be covered (=volume divided by piston cross-section) in mm
-Action : /
***/
{
return mm3 / sectionMm2();
void Syringe :: set_id(int id){
SyringeJSON["id"] = id;
}
float Syringe::mmToMm3 (float mm) const
{
/***
-Argument : Distance in mm
-Return : Syringe volume given distance covered
-Action : /
***/
return mm * sectionMm2();
}
float Syringe::confToMm () const
/***
-Argument : /
-Return : Total syringe length in mm
-Action : /
***/
{
return mm3ToMm(confToMm3());
}
void Syringe::fill ()
/***
-Argument : /
-Return : /
-Action : Move the syringe forward
***/
//GET METHODES
float Syringe :: get_total_volume_mL()
{
Serial.printf("# set speed to %g mm/s\n", mm3ToMm(current_configuration.rate_ul_per_s));
setSpeedMmPerSec(mm3ToMm(current_configuration.rate_ul_per_s));
moveToMm(confToMm());
return SyringeJSON["total_volume_mL"].as<float>();
}
bool Syringe::configureSyringe(const Syringe_configuration_t& config)
/***
-Argument : Address to syringe configuration
-Return : A Boolean indicating whether the syringe configuration is correct
-Action : /
***/
float Syringe :: get_internal_diameter_mm()
{
if (config.diameter_mm <= 0)
return false;
if (config.volume_value < 0)
return false;
if (config.volume_unit_ul <= 0)
return false;
if (config.rate_ul_per_s <= 0)
return false;
if (config.direction != 1 && config.direction != -1)
return false;
this->current_configuration = config;
this->piston_surface = M_PI * pow(config.diameter_mm,2) / 4.;
this->is_configured = true;
return true;
return SyringeJSON["internal_diameter_mm"].as<float>();
}
void Syringe::findZero (float mmPerSec, float maxCourseMm)
/***
-Argument : Optional, otherwise two numbers for setting travel speed and maximum syringe pump length
-Return : /
-Action : Set syringe pump to position 0
***/
int Syringe :: get_id()
{
if (emergency())
return;
if (mmPerSec > 0)
setSpeedMmPerSec(mmPerSec);
else
setSpeedMmPerSec(mm3ToMm(current_configuration.rate_ul_per_s));
resetPosition();
moveToMm(-maxCourseMm);
return SyringeJSON["id"].as<float>();
}
void Syringe::runFromEmergency (float mmPerSec, float maxCourseMm)
/***
-Argument : Optional, otherwise two numbers for setting travel speed and maximum syringe pump length
-Return : /
-Action : move the pump sloowly until the limit switch is released
***/
{
if (emergency())
{
Serial.printf("EMERGENCY: running away slowly\n");
setSpeedMmPerSec(mmPerSec);
resetPosition();
moveToMm(maxCourseMm);
}
}
void Syringe::resetPosition ()
/***
-Argument : /
-Return : /
-Action : Changes the zero position as the current one
***/
{
Motor::resetPosition();
}
void Syringe::manageEmergency (bool pressed, bool stepperMoving)
/***
-Argument : two boolean to know the position of the limit switch and if the stepper is moving
-Return : /
-Action : Manage different emergency cases (move the pump if necessary)
***/
void Syringe :: setupJsonSyringe( float total_volume_mL, float internal_diameter_mm, int id)
{
if (pressed) //if the limit switch is pressed
{
setEmergency(); //we're entering a state of emergency
if (stepperMoving)
{
Serial.printf("EMERGENCY\n");
runFromEmergency();
}
else
{
Serial.printf("EMERGENCY: Pressed by someone\n");
}
}
else
{
Serial.printf("EMERGENCY: released\n");
setEmergency(false);
stayHere();
resetPosition(); //zero is here again
Serial.printf("ZERO: reset\n");
}
}
//ADD INITIALISATION VALUES TO THE DOC
SyringeJSON["total_volume_mL"] = total_volume_mL;
SyringeJSON["internal_diameter_mm"] = internal_diameter_mm;
SyringeJSON["id"] = id;
//GENERATE THE MINIFIED JSON AND SEND IT TO THE SERIAL PORT
serializeJson(SyringeJSON, Serial);
#if 0
float Syringe::volumeToDistance(float volume)
/***
-Argument : Volume in mL
-Return : The distance to cover associated
-Action : /
***/
{
// Volume is in mL => convert to mm³
float volume_in_mm3 = 1000*volume;
// Distance to travel is in mm => use syringe piston surface in mm²
float distance = volume_in_mm3/this->piston_surface;
return distance;
}
#endif
#if 0
void Syringe::setInitialContent(float initial_volume)
/***
-Argument : Initial volume in the syringe
-Return : /
-Action : Initializes the initial volume contained in the syringe to the given volume
***/
{
this->remaining_volume = initial_volume;
}
/**********************fonction qui rassemble les fonctions push et pull de la fin non ?*********************/
void Syringe::moveMotor(bool direction, float duration, float speed)
/***
-Argument : The direction, duration and speed of the desired movement
-Return : /
-Action : /
***/
{
float quantity = speed*this->piston_surface*duration; //Volume delivered in mm3
if (direction == true) //If you deliver a quantity
{
if (quantity <= this->remaining_volume) //Check that there's enough cash left for the request
{
this->remaining_volume -= quantity; //Update the remaining volume
}
else
{
quantity = this->remaining_volume; // Otherwise, we deliver all the remaining liquid
this->remaining_volume = 0;
}
}
else // If we are retrieving liquid
{
if (this->remaining_volume + quantity <= this->current_configuration.capacity_ul) // We check if there is enough space in the syringe
{
this->remaining_volume += quantity; // We update the remaining volume (adding what we retrieved)
}
else
{
quantity = this->current_configuration.capacity_ul - this->remaining_volume; // Otherwise, we retrieve all the liquid we can store
this->remaining_volume = this->current_configuration.capacity_ul;
}
}
// TODO: recompute duration to match quantity before sending the command to the motor
motor.turn(direction, duration, speed);
}
void Syringe::reset()
/***
-Argument : /
-Return : /
-Action : Resets syringe pump to initial position (not zero, but the position before starting to deliver/retrieve liquid)
***/
{
float speed = 100; // Default to 10 cm/min
this->pull(this->current_configuration.capacity_ul, speed);
}
/***PUSH***/
void Syringe::push(float volume, float throughput)
/***
-Argument : Volume in mL, throughput in µL/min
-Return : /
-Action : Push the volume requested with the throughput imposed (duration is deduced)
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
this->pushFor(volume/throughput, throughput);
}
void Syringe::pushAll(float throughput)
/***
-Argument : Throughput in µL/min
-Return : /
-Action : Push all the liquid the syringe contains with the throughput imposed
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
this->push(this->current_configuration.capacity_ul, throughput);
}
void Syringe::pushFor(float duration, float throughput)
/***
-Argument : Duration in min, throughput in µL/min
-Return : /
-Action : Push for the duration requested with the throughput imposed (volume is deduced)
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
float volume = throughput*duration;
float distance = this->volumeToDistance(volume);
float speed = distance/duration;
this->moveMotor(true, duration, speed);
}
void Syringe::pushVol(float volume, float duration)
/***
-Argument : Volume in mL, duration in min
-Return : /
-Action : Push the volume requested in the duration imposed (throughput is deduced)
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
float throughput = volume/duration;
this->push(volume, throughput);
}
/***PULL***/
void Syringe::pull(float volume, float throughput)
/***
-Argument : Volume in mL, throughput in µL/min
-Return : /
-Action : Pull the amount of volume with the thoughput requested (duration is deduced)
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
// Volume in mL, throughput in µL/min, duration in min
this->pullFor(volume/throughput, throughput);
}
void Syringe::pullAll(float throughput)
/***
-Argument : Throughput in µL/min
-Return : /
-Action : Pull all the liquid it can contains in
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
float volume = throughput*duration; //***********************************************************************************Where is duration specified ?
float distance = this->volumeToDistance(volume);
float speed = distance/duration;
this->moveMotor(false, duration, speed);
}
void Syringe::pullVol(float volume, float duration)
/***
-Argument : Volume in mL, duration in min
-Return : /
-Action : Pull the volume requested in the duration imposed (throughput is deduced)
***/
{
// Ensure syringe is configured before using it
if (this->is_configured == false)
return;
float throughput = volume/duration;
this->pull(volume, throughput);
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment