Skip to content

Commit

Permalink
Merge pull request #222 from makers-for-life/supportFaulhabber
Browse files Browse the repository at this point in the history
Support faulhaber
  • Loading branch information
dsferruzza committed May 1, 2020
2 parents 548e8cf + 64f2003 commit 85334a8
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 11 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/firmware-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,45 @@ jobs:
run: |
sed -Ei "s/#define VERSION \".+\"/#define VERSION \"${{ steps.version.outputs.version }}\"/" src/software/firmware/includes/parameters.h
- name: Build production HW2-FAULHABER
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_PROD/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_FAULHABER/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_FAULHABER/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/respirator.cpp --output src/software/firmware/output/respirator-production
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
cp src/software/firmware/output/respirator-production.bin "dist/respirator-production-HW2-FAULHABER-$VERSION-$GITHUB_SHA.bin"
- name: Build qualification HW2-FAULHABER
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_QUALIFICATION/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_FAULHABER/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_FAULHABER/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-qualification
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
cp src/software/firmware/output/respirator-qualification.bin "dist/respirator-qualification-HW2-FAULHABER-$VERSION-$GITHUB_SHA.bin"
- name: Build integration test HW2-FAULHABER
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_INTEGRATION_TEST/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_FAULHABER/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_FAULHABER/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-integration-test
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
cp src/software/firmware/output/respirator-integration-test.bin "dist/respirator-integration-test-HW2-FAULHABER-$VERSION-$GITHUB_SHA.bin"
- name: Build production HW2
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_PROD/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/respirator.cpp --output src/software/firmware/output/respirator-production
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand All @@ -56,6 +91,8 @@ jobs:
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_QUALIFICATION/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-qualification
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand All @@ -65,6 +102,8 @@ jobs:
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 2/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_INTEGRATION_TEST/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-integration-test
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand All @@ -74,6 +113,8 @@ jobs:
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 1/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_PROD/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/respirator.cpp --output src/software/firmware/output/respirator-production
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand All @@ -83,6 +124,8 @@ jobs:
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 1/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_QUALIFICATION/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-qualification
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand All @@ -92,6 +135,8 @@ jobs:
run: |
sed -Ei 's/#define HARDWARE_VERSION [0-9]+/#define HARDWARE_VERSION 1/' src/software/firmware/includes/config.h
sed -Ei 's/#define MODE .+/#define MODE MODE_INTEGRATION_TEST/' src/software/firmware/includes/config.h
sed -Ei 's/#define PNEUMATIC_HARDWARE_VERSION .+/#define PNEUMATIC_HARDWARE_VERSION PHW_CHU/' src/software/firmware/includes/config.h
sed -Ei 's/#define VALVE_TYPE .+/#define VALVE_TYPE VT_SERVO_V1/' src/software/firmware/includes/config.h
arduino-cli compile --fqbn STM32:stm32:Nucleo_64:opt=o3std,pnum=NUCLEO_F411RE --verbose src/software/firmware/srcs/qualification.cpp --output src/software/firmware/output/respirator-integration-test
mkdir -p dist/
VERSION=$(sed -En 's/#define VERSION[ ]+["](.+)["]/\1/p' src/software/firmware/includes/parameters.h)
Expand Down
2 changes: 2 additions & 0 deletions src/software/firmware/includes/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@
// Available pneumatic versions
#define PHW_PIGGY 0
#define PHW_CHU 1
#define PHW_FAULHABER 2

/// Defines which preset to use for controlling pressure
#define PNEUMATIC_HARDWARE_VERSION PHW_CHU

// Available valves
#define VT_SERVO_V1 0
#define VT_EMERSON_ASCO 1
#define VT_FAULHABER 2

// Defines which valves are fitted
#define VALVE_TYPE VT_SERVO_V1
Expand Down
33 changes: 31 additions & 2 deletions src/software/firmware/includes/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ static const int32_t PID_PATIENT_INTEGRAL_MIN = -630;
/// Increase target pressure by an offset (in mmH2O) for safety, to avoid going below the target
/// pressure
static const int32_t PID_PATIENT_SAFETY_PEEP_OFFSET = 0;

#elif PNEUMATIC_HARDWARE_VERSION == PHW_FAULHABER

static const int32_t PID_BLOWER_KP = 1;
static const int32_t PID_BLOWER_KI = 25;
static const int32_t PID_BLOWER_KD = 0;
static const int32_t PID_BLOWER_INTEGRAL_MAX = 1000;
static const int32_t PID_BLOWER_INTEGRAL_MIN = -1000;

static const int32_t PID_PATIENT_KP = 4;
static const int32_t PID_PATIENT_KI = 20;
static const int32_t PID_PATIENT_KD = 10;
static const int32_t PID_PATIENT_INTEGRAL_MAX = 400;
static const int32_t PID_PATIENT_INTEGRAL_MIN = -400;

/// Increase target pressure by an offset (in mmH2O) for safety, to avoid going below the target
/// pressure
static const int32_t PID_PATIENT_SAFETY_PEEP_OFFSET = 10;

#endif

///@}
Expand All @@ -104,13 +123,18 @@ static const int32_t PID_PATIENT_SAFETY_PEEP_OFFSET = 0;

/// Angle when closed
#define VALVE_CLOSED_STATE 125u

#if VALVE_TYPE == VT_SERVO_V1
#define SERVO_VALVE_PERIOD \
10000 // 100 Hz : on hardware 1, esc timer is shared between servo and esc. Servo can handle
// 100hz too
// 100 Hz too
#elif VALVE_TYPE == VT_EMERSON_ASCO
#define SERVO_VALVE_PERIOD 3278 // 305 Hz
#define EMERSON_MIN_PWM 600 // 18 % PWM is the minimum to start opening (3278 * 0.18)
#elif VALVE_TYPE == VT_FAULHABER
#define SERVO_VALVE_PERIOD 1000 // 1 kHz Faulhaber motors are controlled with a 1 kHz PWM
#define FAULHABER_OPENED 640 // PWM duty cycle 64% -> open
#define FAULHABER_CLOSED 900 // PWM duty cycle 90% -> closed
#endif

#if HARDWARE_VERSION == 1
Expand Down Expand Up @@ -282,8 +306,13 @@ static const int32_t PID_PATIENT_SAFETY_PEEP_OFFSET = 0;
///@{

#define ALARM_THRESHOLD_MIN_PRESSURE 20u // RCM-SW-2 + RCM-SW-19
#define ALARM_THRESHOLD_MAX_PRESSURE 800u // RCM-SW-18
#define ALARM_THRESHOLD_MAX_PRESSURE 800u // RCM-SW-18
#define ALARM_THRESHOLD_DIFFERENCE_PERCENT 20u // RCM-SW-1 + RCM-SW-14
#define ALARM_THRESHOLD_DIFFERENCE_PRESSURE 20u // RCM-SW-3 + RCM-SW-15

///@}

// Preprocessor checks
#if VALVE_TYPE == VT_FAULHABER && HARDWARE_VERSION == 1
#error "Faulhaber can only be driven with hardware v2"
#endif
5 changes: 4 additions & 1 deletion src/software/firmware/includes/pressure_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class PressureController {
void inhale();

/// Perform the pressure control and compute the transistors commands during the plateau phase
void plateau();
void plateau(uint16_t p_centiSec);

/// Perform the pressure control and compute the transistors commands during the exhalation
/// phase
Expand Down Expand Up @@ -274,6 +274,9 @@ class PressureController {
/// Positive End Expiratory Pressure
uint16_t m_peep;

/// Blower valve angle at peak
uint32_t m_peakBlowerValveAngle;

/// Current respiratory cycle phase
CyclePhases m_phase;

Expand Down
28 changes: 21 additions & 7 deletions src/software/firmware/srcs/pressure_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ PressureController::PressureController()
m_lastPressureValuesIndex(0),
m_sumOfPressures(0),
m_numberOfPressures(0),
m_plateauStartTime(0u) {
m_plateauStartTime(0u),
m_peakBlowerValveAngle(VALVE_CLOSED_STATE) {
computeCentiSecParameters();
for (uint8_t i = 0; i < MAX_PRESSURE_SAMPLES; i++) {
m_lastPressureValues[i] = 0;
Expand Down Expand Up @@ -112,7 +113,8 @@ PressureController::PressureController(int16_t p_cyclesPerMinute,
m_lastPressureValuesIndex(0),
m_sumOfPressures(0),
m_numberOfPressures(0),
m_plateauStartTime(0u) {
m_plateauStartTime(0u),
m_peakBlowerValveAngle(VALVE_CLOSED_STATE) {
computeCentiSecParameters();
for (uint8_t i = 0; i < MAX_PRESSURE_SAMPLES; i++) {
m_lastPressureValues[i] = 0;
Expand Down Expand Up @@ -241,7 +243,7 @@ void PressureController::compute(uint16_t p_centiSec) {
break;
}
case CycleSubPhases::HOLD_INSPIRATION: {
plateau();
plateau(p_centiSec);
break;
}
case CycleSubPhases::EXHALE:
Expand Down Expand Up @@ -375,7 +377,7 @@ void PressureController::onPeakPressureDecrease(uint8_t p_decrement) {
m_maxPeakPressureCommand = m_maxPeakPressureCommand - p_decrement;

m_maxPeakPressureCommand =
max(m_maxPeakPressureCommand, static_cast<uint16_t>(CONST_MIN_PEAK_PRESSURE));
max(m_maxPeakPressureCommand, static_cast<uint16_t>(CONST_MIN_PEAK_PRESSURE));
}

void PressureController::onPeakPressureIncrease(uint8_t p_increment) {
Expand Down Expand Up @@ -412,7 +414,8 @@ void PressureController::updatePhase(uint16_t p_centiSec) {

void PressureController::inhale() {
// Open the air stream towards the patient's lungs
m_blower_valve.open(pidBlower(m_pressureCommand, m_pressure, m_dt));
m_peakBlowerValveAngle = pidBlower(m_pressureCommand, m_pressure, m_dt);
m_blower_valve.open(m_peakBlowerValveAngle);

// Open the air stream towards the patient's lungs
m_patient_valve.close();
Expand All @@ -421,12 +424,23 @@ void PressureController::inhale() {
m_peakPressure = max(m_pressure, m_peakPressure);
}

void PressureController::plateau() {
void PressureController::plateau(uint16_t p_centiSec) {
// Deviate the air stream outside
m_blower_valve.close();

// Close the air stream towards the patient's lungs
#if VALVE_TYPE == VT_FAULHABER
// With Faulhaber valves, gently close the air stream towards the patient's lungs
if (p_centiSec < (m_plateauStartTime + 10u)) {
m_blower_valve.open(((p_centiSec - m_plateauStartTime)
* (VALVE_CLOSED_STATE - m_peakBlowerValveAngle) / 10u)
+ m_peakBlowerValveAngle);
} else {
m_patient_valve.close();
}
#else
(void)p_centiSec;
m_patient_valve.close();
#endif

// Update the peak pressure
m_peakPressure = max(m_pressure, m_peakPressure);
Expand Down
5 changes: 4 additions & 1 deletion src/software/firmware/srcs/pressure_valve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ uint16_t valveAngle2MicroSeconds(uint16_t value) {
// TODO: avoid 500ns spikes
uint16_t result = 1;

// map 0 - 125 ° to 100% pwm - EMERSON_MIN_PWM (0% when fully closed)
// map 0 - 125 ° to 100% PWM - EMERSON_MIN_PWM (0% when fully closed)
if (VALVE_CLOSED_STATE != value) {
result = map(value, 0, 125, SERVO_VALVE_PERIOD, EMERSON_MIN_PWM);
}

return result;
#elif VALVE_TYPE == VT_FAULHABER
// Faulhaber motors works with PWM
return map(value, 0, 125, FAULHABER_OPENED, FAULHABER_CLOSED);
#endif
}

0 comments on commit 85334a8

Please sign in to comment.