Skip to content
Snippets Groups Projects
Commit c8bf8fd2 authored by Your Name's avatar Your Name
Browse files

initial attempt at pressure calib

parent 32bb5fb4
No related merge requests found
...@@ -77,29 +77,58 @@ void BreathingLoop::updateReadings() ...@@ -77,29 +77,58 @@ void BreathingLoop::updateReadings()
if (_readings_reset) { if (_readings_reset) {
resetReadingSums(); resetReadingSums();
} else if (tnow - _readings_avgs_time > _readings_avgs_timeout) { } else if (tnow - _readings_avgs_time > _readings_avgs_timeout) {
_readings_avgs.timestamp = static_cast<uint32_t>(_readings_sums.timestamp / _readings_N); _readings_avgs.timestamp = static_cast<uint32_t>(_readings_sums.timestamp);
_readings_avgs.pressure_air_supply = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_air_supply / _readings_N)); _readings_avgs.pressure_air_supply = adcToMillibar((_readings_sums.pressure_air_supply / _readings_N), _calib_avgs.pressure_air_supply );
_readings_avgs.pressure_air_regulated = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_air_regulated / _readings_N)); _readings_avgs.pressure_air_regulated = adcToMillibar((_readings_sums.pressure_air_regulated / _readings_N), _calib_avgs.pressure_air_regulated);
_readings_avgs.pressure_buffer = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_buffer / _readings_N)); _readings_avgs.pressure_buffer = adcToMillibar((_readings_sums.pressure_buffer / _readings_N), _calib_avgs.pressure_buffer );
_readings_avgs.pressure_inhale = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_inhale / _readings_N)); _readings_avgs.pressure_inhale = adcToMillibar((_readings_sums.pressure_inhale / _readings_N), _calib_avgs.pressure_inhale );
_readings_avgs.pressure_patient = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_patient / _readings_N)); _readings_avgs.pressure_patient = adcToMillibar((_readings_sums.pressure_patient / _readings_N), _calib_avgs.pressure_patient );
_readings_avgs.temperature_buffer = adcToMillibar(static_cast<uint16_t>(_readings_sums.temperature_buffer / _readings_N)); _readings_avgs.temperature_buffer = adcToMillibar((_readings_sums.temperature_buffer / _readings_N), _calib_avgs.temperature_buffer );
#ifdef HEV_FULL_SYSTEM #ifdef HEV_FULL_SYSTEM
_readings_avgs.pressure_o2_supply = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_o2_supply / _readings_N)); _readings_avgs.pressure_o2_supply = adcToMillibar((_readings_sums.pressure_o2_supply / _readings_N), _calib_avgs.pressure_o2_supply );
_readings_avgs.pressure_o2_regulated = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_o2_regulated / _readings_N)); _readings_avgs.pressure_o2_regulated = adcToMillibar((_readings_sums.pressure_o2_regulated / _readings_N), _calib_avgs.pressure_o2_regulated );
_readings_avgs.pressure_diff_patient = adcToMillibar(static_cast<uint16_t>(_readings_sums.pressure_diff_patient / _readings_N)); _readings_avgs.pressure_diff_patient = adcToMillibar((_readings_sums.pressure_diff_patient / _readings_N), _calib_avgs.pressure_diff_patient );
#endif #endif
resetReadingSums(); resetReadingSums();
} }
} }
void BreathingLoop::updateRawReadings()
{
// calc pressure every 1ms
// create averages every 10ms
uint32_t tnow = static_cast<uint32_t>(millis());
// to make sure the readings correspond only to the same fsm mode
if (tnow - _readings_avgs_time > _readings_avgs_timeout) {
_readings_raw.timestamp = static_cast<uint32_t>(_readings_sums.timestamp);
_readings_raw.pressure_air_supply =analogRead(pin_pressure_air_supply) ;
_readings_raw.pressure_air_regulated =analogRead(pin_pressure_air_regulated) ;
_readings_raw.pressure_buffer =analogRead(pin_pressure_buffer) ;
_readings_raw.pressure_inhale =analogRead(pin_pressure_inhale) ;
_readings_raw.pressure_patient =analogRead(pin_pressure_patient) ;
_readings_raw.temperature_buffer =analogRead(pin_temperature_buffer) ;
#ifdef HEV_FULL_SYSTEM
_readings_raw.pressure_o2_supply =analogRead(pin_pressure_o2_supply) ;
_readings_raw.pressure_o2_regulated =analogRead(pin_pressure_o2_regulated) ;
_readings_raw.pressure_diff_patient =analogRead(pin_pressure_diff_patient) ;
#endif
}
}
readings<uint16_t> BreathingLoop::getReadingAverages()
readings<int16_t> BreathingLoop::getReadingAverages()
{ {
return _readings_avgs; return _readings_avgs;
} }
readings<int16_t> BreathingLoop::getRawReadings()
{
return _readings_raw;
}
float BreathingLoop::getRespiratoryRate(){ float BreathingLoop::getRespiratoryRate(){
// 60*1000ms / total time for a full cycle // 60*1000ms / total time for a full cycle
float avg = (_total_cycle_duration[0]+_total_cycle_duration[1]+_total_cycle_duration[2])/3.0; float avg = (_total_cycle_duration[0]+_total_cycle_duration[1]+_total_cycle_duration[2])/3.0;
...@@ -184,7 +213,7 @@ void BreathingLoop::FSM_assignment( ) { ...@@ -184,7 +213,7 @@ void BreathingLoop::FSM_assignment( ) {
case BL_STATES::IDLE: case BL_STATES::IDLE:
if (_running == true) { if (_running == true) {
// FSM_time = millis(); // FSM_time = millis();
next_state = BL_STATES::BUFF_PREFILL; next_state = BL_STATES::CALIBRATION;
} else { } else {
next_state = BL_STATES::IDLE; next_state = BL_STATES::IDLE;
} }
...@@ -397,9 +426,9 @@ bool BreathingLoop::getRunning() ...@@ -397,9 +426,9 @@ bool BreathingLoop::getRunning()
void BreathingLoop::calibrate() void BreathingLoop::calibrate()
{ {
// get pressure_air_regulated over 10s calc mean // get pressure_air_regulated over last sec of 10s calc mean
uint32_t tnow = static_cast<uint32_t>(millis()); uint32_t tnow = static_cast<uint32_t>(millis());
if (tnow - _calib_time > _calib_timeout) { if (tnow - _calib_time > _calib_timeout ) {
_calib_N++; _calib_N++;
_calib_sums.pressure_air_regulated += static_cast<uint32_t>(analogRead(pin_pressure_air_regulated)); _calib_sums.pressure_air_regulated += static_cast<uint32_t>(analogRead(pin_pressure_air_regulated));
_calib_avgs.pressure_air_regulated = static_cast<float >(_calib_sums.pressure_air_regulated/ _calib_N); _calib_avgs.pressure_air_regulated = static_cast<float >(_calib_sums.pressure_air_regulated/ _calib_N);
...@@ -411,13 +440,18 @@ void BreathingLoop::calibrate() ...@@ -411,13 +440,18 @@ void BreathingLoop::calibrate()
_calib_avgs.pressure_inhale = static_cast<float >(_calib_sums.pressure_inhale/ _calib_N); _calib_avgs.pressure_inhale = static_cast<float >(_calib_sums.pressure_inhale/ _calib_N);
_calib_sums.pressure_patient += static_cast<uint32_t>(analogRead(pin_pressure_patient)); _calib_sums.pressure_patient += static_cast<uint32_t>(analogRead(pin_pressure_patient));
_calib_avgs.pressure_patient = static_cast<float >(_calib_sums.pressure_patient/ _calib_N); _calib_avgs.pressure_patient = static_cast<float >(_calib_sums.pressure_patient/ _calib_N);
_calib_time = tnow;
_calib_timeout = 10;
} }
} }
void BreathingLoop::initCalib() void BreathingLoop::initCalib()
{ { // do calibration in last sec of calibration step (normally 10s) or default to 10ms
_calib_timeout = 10; _calib_timeout = 10;
if (_states_durations.calibration - 1000 > 10)
_calib_timeout = _states_durations.calibration - 1000;
_calib_time = static_cast<uint32_t>(millis()); _calib_time = static_cast<uint32_t>(millis());
_calib_sums.pressure_air_regulated = 0; _calib_sums.pressure_air_regulated = 0;
_calib_sums.pressure_o2_regulated = 0; _calib_sums.pressure_o2_regulated = 0;
...@@ -464,4 +498,4 @@ void BreathingLoop::updateTotalCycleDuration(uint16_t newtotal) ...@@ -464,4 +498,4 @@ void BreathingLoop::updateTotalCycleDuration(uint16_t newtotal)
_total_cycle_duration[0] = _total_cycle_duration[1]; _total_cycle_duration[0] = _total_cycle_duration[1];
_total_cycle_duration[1] = _total_cycle_duration[2]; _total_cycle_duration[1] = _total_cycle_duration[2];
_total_cycle_duration[2] = newtotal; _total_cycle_duration[2] = newtotal;
} }
\ No newline at end of file
...@@ -25,7 +25,9 @@ public: ...@@ -25,7 +25,9 @@ public:
void doReset(); void doReset();
bool getRunning(); bool getRunning();
void updateReadings(); void updateReadings();
readings<uint16_t> getReadingAverages(); void updateRawReadings();
readings<int16_t> getReadingAverages();
readings<int16_t> getRawReadings();
float getRespiratoryRate(); float getRespiratoryRate();
float getFlow(); float getFlow();
float getIERatio(); float getIERatio();
...@@ -84,8 +86,8 @@ private: ...@@ -84,8 +86,8 @@ private:
uint32_t _calib_N; uint32_t _calib_N;
uint32_t _calib_time; uint32_t _calib_time;
uint32_t _calib_timeout; uint32_t _calib_timeout;
readings<uint32_t> _calib_sums; readings<int32_t> _calib_sums;
readings<uint16_t> _calib_avgs; readings<int16_t> _calib_avgs;
// timeouts // timeouts
uint32_t calculateDurationExhale(); uint32_t calculateDurationExhale();
...@@ -93,8 +95,9 @@ private: ...@@ -93,8 +95,9 @@ private:
// readings // readings
void resetReadingSums(); void resetReadingSums();
readings<uint32_t> _readings_sums; // 32 bit due to possible analog read overflow readings<int32_t> _readings_sums; // 32 bit due to possible analog read overflow
readings<uint16_t> _readings_avgs; readings<int16_t> _readings_avgs;
readings<int16_t> _readings_raw;
bool _readings_reset; bool _readings_reset;
uint32_t _readings_N; uint32_t _readings_N;
uint32_t _readings_time; uint32_t _readings_time;
......
...@@ -43,18 +43,22 @@ void UILoop::reportFastReadings() ...@@ -43,18 +43,22 @@ void UILoop::reportFastReadings()
if (tnow - _fast_report_time > _fast_report_timeout) if (tnow - _fast_report_time > _fast_report_timeout)
{ {
readings<uint16_t> readings_avgs = _breathing_loop->getReadingAverages(); // TO SWITCH BETWEEN RAW AND MILLIBAR DATA UNCOMMENT BELOW
_fast_data.timestamp = static_cast<uint32_t>(readings_avgs.timestamp); readings<int16_t> readings = _breathing_loop->getReadingAverages();
//readings<int16_t> readings = _breathing_loop->getRawReadings();
_fast_data.timestamp = static_cast<uint32_t>(readings.timestamp);
_fast_data.fsm_state = _breathing_loop->getFsmState(); _fast_data.fsm_state = _breathing_loop->getFsmState();
_fast_data.pressure_air_supply = readings_avgs.pressure_air_supply;
_fast_data.pressure_air_regulated = readings_avgs.pressure_air_regulated; _fast_data.pressure_air_supply = readings.pressure_air_supply;
_fast_data.pressure_buffer = readings_avgs.pressure_buffer; _fast_data.pressure_air_regulated = readings.pressure_air_regulated;
_fast_data.pressure_inhale = readings_avgs.pressure_inhale; _fast_data.pressure_buffer = readings.pressure_buffer;
_fast_data.pressure_patient = readings_avgs.pressure_patient; _fast_data.pressure_inhale = readings.pressure_inhale;
_fast_data.temperature_buffer = readings_avgs.temperature_buffer; _fast_data.pressure_patient = readings.pressure_patient;
_fast_data.pressure_o2_supply = readings_avgs.pressure_o2_supply; _fast_data.temperature_buffer = readings.temperature_buffer;
_fast_data.pressure_o2_regulated = readings_avgs.pressure_o2_regulated; _fast_data.pressure_o2_supply = readings.pressure_o2_supply;
_fast_data.pressure_diff_patient = readings_avgs.pressure_diff_patient; _fast_data.pressure_o2_regulated = readings.pressure_o2_regulated;
_fast_data.pressure_diff_patient = readings.pressure_diff_patient;
_plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_fast_data), sizeof(_fast_data)); _plSend.setPayload(PAYLOAD_TYPE::DATA, reinterpret_cast<void *>(&_fast_data), sizeof(_fast_data));
_comms->writePayload(_plSend); _comms->writePayload(_plSend);
......
...@@ -123,25 +123,21 @@ void setDuration(CMD_SET_DURATION cmd, states_durations &durations, uint32_t &va ...@@ -123,25 +123,21 @@ void setDuration(CMD_SET_DURATION cmd, states_durations &durations, uint32_t &va
} }
} }
uint16_t adcToMillibar(uint16_t adc, uint16_t offset = 0) int16_t adcToMillibar(int16_t adc, int16_t offset = 0)
{ {
// TODO - a proper calibration // TODO - a proper calibration
// rough guess - ADP5111 spec sheet -Panasonic ADP5 pressure sensor // rough guess - ADP51A11 spec sheet -Panasonic ADP5 pressure sensor
// range is 0.5 to 4.5V == 40 kPA range == 400 mbar ; but - voltage divide by 2 on PCB // range is 0.5 to 4.5V == 40 kPA range == 400 mbar ; but - voltage divide by 2 on PCB
// 12 bit ADC => range = 0-4095 // 12 bit ADC => range = 0-4095
float bits_per_millivolt = 3300/4096.0; float bits_per_millivolt = 3300/4096.0;
float max_p = 400; //mbar float max_p = 400; //mbar
float min_p = 0; float min_p = 0;
float max_adc = 0.5 * 4500 * bits_per_millivolt; float max_adc = 0.5 * 4500 / bits_per_millivolt;
float min_adc = 0.5 * 500 * bits_per_millivolt; float min_adc = 0; //0.5 * 500 / bits_per_millivolt;
float m = (max_p - min_p) / (max_adc - min_adc ); float m = (max_p - min_p) / (max_adc - min_adc );
float c = max_p - m * max_adc; float c = max_p - m * max_adc;
float mbar = m*(adc-offset) + c; float mbar = m*(adc-offset) + c;
if (mbar < 0 ) mbar = 0; // hack FIXME
//if (mbar < 0) return 0; return static_cast<int16_t>(mbar);
//else if (mbar > 1000 ) return 1000; //return static_cast<int16_t>(adc);
}
return static_cast<uint16_t>(mbar);
//return static_cast<uint16_t>(adc);
}
\ No newline at end of file
...@@ -138,17 +138,17 @@ struct fast_data_format { ...@@ -138,17 +138,17 @@ struct fast_data_format {
uint32_t timestamp = 0; uint32_t timestamp = 0;
uint8_t data_type = DATA_TYPE::FAST; uint8_t data_type = DATA_TYPE::FAST;
uint8_t fsm_state = 0; //UNKNOWN uint8_t fsm_state = 0; //UNKNOWN
uint16_t pressure_air_supply = 0; int16_t pressure_air_supply = 0;
uint16_t pressure_air_regulated = 0; int16_t pressure_air_regulated = 0;
uint16_t pressure_o2_supply = 0; int16_t pressure_o2_supply = 0;
uint16_t pressure_o2_regulated = 0; int16_t pressure_o2_regulated = 0;
uint16_t pressure_buffer = 0; int16_t pressure_buffer = 0;
uint16_t pressure_inhale = 0; int16_t pressure_inhale = 0;
uint16_t pressure_patient = 0; int16_t pressure_patient = 0;
uint16_t temperature_buffer = 0; int16_t temperature_buffer = 0;
uint16_t pressure_diff_patient = 0; int16_t pressure_diff_patient = 0;
uint16_t ambient_pressure = 0; int16_t ambient_pressure = 0;
uint16_t ambient_temperature = 0; int16_t ambient_temperature = 0;
float airway_pressure = 0; float airway_pressure = 0;
float flow = 0; float flow = 0;
float volume = 0; float volume = 0;
...@@ -281,7 +281,7 @@ struct alarm_thresholds { ...@@ -281,7 +281,7 @@ struct alarm_thresholds {
void setThreshold(ALARM_CODES alarm, alarm_thresholds &thresholds, uint32_t &value); void setThreshold(ALARM_CODES alarm, alarm_thresholds &thresholds, uint32_t &value);
void setDuration(CMD_SET_DURATION cmd, states_durations &timeouts, uint32_t &value); void setDuration(CMD_SET_DURATION cmd, states_durations &timeouts, uint32_t &value);
uint16_t adcToMillibar(uint16_t adc, uint16_t offset = 0); int16_t adcToMillibar(int16_t adc, int16_t offset = 0);
// used for calculating averages, template due to different size for sums and averages // used for calculating averages, template due to different size for sums and averages
template <typename T> struct readings{ template <typename T> struct readings{
......
...@@ -37,6 +37,8 @@ void setup() ...@@ -37,6 +37,8 @@ void setup()
btStop(); btStop();
ledcSetup(pwm_chan_inhale, pwm_frequency, pwm_resolution); ledcSetup(pwm_chan_inhale, pwm_frequency, pwm_resolution);
ledcSetup(pwm_chan_exhale, pwm_frequency, pwm_resolution); ledcSetup(pwm_chan_exhale, pwm_frequency, pwm_resolution);
ledcSetup(3, 2000, pwm_resolution);
ledcAttachPin(pin_buzzer, 3);
ledcAttachPin(pin_valve_inhale , pwm_chan_inhale); ledcAttachPin(pin_valve_inhale , pwm_chan_inhale);
ledcAttachPin(pin_valve_exhale , pwm_chan_exhale); ledcAttachPin(pin_valve_exhale , pwm_chan_exhale);
pin_to_chan[pin_valve_inhale] = pwm_chan_inhale; pin_to_chan[pin_valve_inhale] = pwm_chan_inhale;
...@@ -73,41 +75,18 @@ void setup() ...@@ -73,41 +75,18 @@ void setup()
pinMode(pin_buzzer, OUTPUT); pinMode(pin_buzzer, OUTPUT);
pinMode(pin_button_0, INPUT); pinMode(pin_button_0, INPUT);
// while (!Serial) ;
comms.beginSerial(); comms.beginSerial();
} }
void loop() void loop()
{ {
// buzzer
// tone(pin, freq (Hz), duration);
// bool vin_air, vin_o2, vpurge ;
// float vinhale, vexhale;
// ValvesController *valves_controller = breathing_loop.getValvesController();
// valves_controller->getValves(vin_air, vin_o2, vinhale, vexhale, vpurge);
// readings<uint16_t> readings_avgs = breathing_loop.getReadingAverages();
// data.timestamp = static_cast<uint32_t>(readings_avgs.timestamp);
// data.pressure_air_supply = readings_avgs.pressure_air_supply;
// data.pressure_air_regulated = readings_avgs.pressure_air_regulated;
// data.pressure_buffer = readings_avgs.pressure_buffer;
// data.pressure_inhale = readings_avgs.pressure_inhale;
// data.pressure_patient = readings_avgs.pressure_patient;
// data.temperature_buffer = readings_avgs.temperature_buffer;
// data.pressure_o2_supply = readings_avgs.pressure_o2_supply;
// data.pressure_o2_regulated = readings_avgs.pressure_o2_regulated;
// data.pressure_diff_patient = readings_avgs.pressure_diff_patient;
// data.fsm_state = breathing_loop.getFsmState();
// data.ventilation_mode = breathing_loop.getVentilationMode();
breathing_loop.FSM_assignment(); breathing_loop.FSM_assignment();
breathing_loop.FSM_breathCycle(); breathing_loop.FSM_breathCycle();
ui_loop.reportFastReadings(); ui_loop.reportFastReadings();
ui_loop.reportReadbackValues(); // ui_loop.reportReadbackValues();
ui_loop.reportCycleReadings(); // ui_loop.reportCycleReadings();
// per cycle sender // per cycle sender
comms.sender(); comms.sender();
...@@ -118,4 +97,6 @@ void loop() ...@@ -118,4 +97,6 @@ void loop()
ui_loop.receiveCommands(); ui_loop.receiveCommands();
// run value readings // run value readings
breathing_loop.updateReadings(); breathing_loop.updateReadings();
breathing_loop.updateRawReadings();
} }
...@@ -189,7 +189,7 @@ class BaseFormat(): ...@@ -189,7 +189,7 @@ class BaseFormat():
@dataclass @dataclass
class DataFormat(BaseFormat): class DataFormat(BaseFormat):
# subclass dataformat # subclass dataformat
_dataStruct = Struct("<BIBBHHHHHHHHHHHfff") _dataStruct = Struct("<BIBBhhhhhhhhhhhfff")
_type = PAYLOAD_TYPE.DATA _type = PAYLOAD_TYPE.DATA
# subclass member variables # subclass member variables
......
...@@ -3,10 +3,23 @@ from CommsControl import CommsControl ...@@ -3,10 +3,23 @@ from CommsControl import CommsControl
from CommsCommon import * from CommsCommon import *
import logging import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
from serial.tools import list_ports
import sys import sys
import time import time
comms = CommsControl(port = sys.argv[1]) port_device = ""
for port in list_ports.comports():
vidpid = ""
if port.pid != None and port.vid != None:
vidpid = f"{ port.vid:04x}:{port.pid:04x}".upper()
print(vidpid)
if port.manufacturer and "ARDUINO" in port.manufacturer.upper():
port_device = port.device
elif vidpid == "10C4:EA60" :
port_device = port.device
elif len(sys.argv) > 1:
port_device = sys.argv[1]
comms = CommsControl(port = port_device)
class Dependant(object): class Dependant(object):
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment