software:firmware
MakAir Firmware
serial_control.h File Reference

Handle control protocol on the serial input. More...

Go to the source code of this file.

Macros

#define DISABLE_RPI_WATCHDOG   43690u
 Special value that can be used in a heartbeat control message to disable RPi watchdog. More...
 

Enumerations

enum  ControlSetting {
  Heartbeat = 0 , VentilationMode = 1 , PlateauPressure = 2 , PEEP = 3 ,
  CyclesPerMinute = 4 , ExpiratoryTerm = 5 , TriggerEnabled = 6 , TriggerOffset = 7 ,
  RespirationEnabled = 8 , AlarmSnooze = 9 , InspiratoryTriggerFlow = 10 , ExpiratoryTriggerFlow = 11 ,
  TiMin = 12 , TiMax = 13 , LowInspiratoryMinuteVolumeAlarmThreshold = 14 , HighInspiratoryMinuteVolumeAlarmThreshold = 15 ,
  LowExpiratoryMinuteVolumeAlarmThreshold = 16 , HighExpiratoryMinuteVolumeAlarmThreshold = 17 , LowRespiratoryRateAlarmThreshold = 18 , HighRespiratoryRateAlarmThreshold = 19 ,
  TargetTidalVolume = 20 , LowTidalVolumeAlarmThreshold = 21 , HighTidalVolumeAlarmThreshold = 22 , PlateauDuration = 23 ,
  LeakAlarmThreshold = 24 , TargetInspiratoryFlow = 25 , InspiratoryDuration = 26 , Locale = 27 ,
  PatientHeight = 28 , PatientGender = 29 , PeakPressureAlarmThreshold = 30 , EolConfirm = 31
}
 Available settings in the control protocol. More...
 

Functions

void serialControlLoop ()
 Parse input and handle changes of settings. More...
 

Detailed Description

Handle control protocol on the serial input.

Author
Makers For Life

Definition in file serial_control.h.

Macro Definition Documentation

◆ DISABLE_RPI_WATCHDOG

#define DISABLE_RPI_WATCHDOG   43690u

Special value that can be used in a heartbeat control message to disable RPi watchdog.

Definition at line 11 of file serial_control.h.

Enumeration Type Documentation

◆ ControlSetting

Available settings in the control protocol.

Enumerator
Heartbeat 

Heartbeat used for the RPi watchdog feature (value is ignored except for the special value DISABLE_RPI_WATCHDOG which disables watchdog)

VentilationMode 

Ventilation mode, must be one of the following:

  • 1 → PC-CMV
  • 2 → PC-AC (default)
  • 3 → VC-CMV
  • 4 → PC-VSAI
  • 5 → VC-AC
PlateauPressure 

Plateau pressure in mmH2O (value bounds must be between 100 and 400)

PEEP 

PEEP in mmH2O (value bounds must be between 0 and 300)

CyclesPerMinute 

Number of cycles per minute (value bounds must be between 5 and 35)

ExpiratoryTerm 

Expiration term in the "Inspiration/Expiration" ratio given that Inspiration = 10 (value bounds must be between 10 and 60)

TriggerEnabled 

State of the trigger (value must be 1 if enabled and 0 if disabled)

TriggerOffset 

Trigger offset in mmH2O (value bounds must be between 0 and 100)

RespirationEnabled 

State of the respiration (value must be 1 if enabled and 0 if disabled)

AlarmSnooze 

Alarm snooze (value must be 1 to snooze and 0 to unsnooze)

InspiratoryTriggerFlow 

Inspiratory trigger flow in percent.

ExpiratoryTriggerFlow 

Expiratory trigger flow in percent.

TiMin 

Minimum duration of inhalation in ms (value bounds must be between 100 and 3000)

TiMax 

Maximum duration of inhalation in ms (value bounds must be between 200 and 5000)

LowInspiratoryMinuteVolumeAlarmThreshold 

Threshold for low inspiratory minute volume alarm in L/min (value bounds must be between 0 and 20)

HighInspiratoryMinuteVolumeAlarmThreshold 

Threshold for high inspiratory minute volume alarm in L/min (value bounds must be between 10 and 40)

LowExpiratoryMinuteVolumeAlarmThreshold 

Threshold for low expiratory minute volume alarm in L/min (value bounds must be between 0 and 20)

HighExpiratoryMinuteVolumeAlarmThreshold 

Threshold for high expiratory minute volume alarm in L/min (value bounds must be between 10 and 40)

LowRespiratoryRateAlarmThreshold 

Threshold for low respiratory rate alarm in cycle per minute (value bounds must be between 5 and 25)

HighRespiratoryRateAlarmThreshold 

Threshold for high respiratory rate alarm in cycle per minute (value bounds must be between 15 and 35)

TargetTidalVolume 

Target tidal volume in mL (value bounds must be between 50 and 2000)

LowTidalVolumeAlarmThreshold 

Threshold for low tidal volume in mL (value bounds must be between 0 and 1000)

HighTidalVolumeAlarmThreshold 

Threshold for high tidal volume in mL (value bounds must be between 50 and 2000)

PlateauDuration 

Duration in ms of closing both valves to effectively measure plateau pressure in volume control modes (value bounds must be between 100 and 2000)

LeakAlarmThreshold 

Threshold for leak alarm in cL/min (value bounds must be between 0 and 10000)

TargetInspiratoryFlow 

Target flow during inspiration in L/min (value bounds must be between 5 and 80)

InspiratoryDuration 

Duration of inspiration in ms (value bounds must be between 200 and 3000)

Locale 

Language of the system; this should be two letters (see ISO 639-1) in ASCII representation as two u8.

PatientHeight 

Patient's height in centimeters.

PatientGender 

Patient's gender (0 = male, 1 = female)

PeakPressureAlarmThreshold 

Threshold for peak pressure alarm in mmH2O (value bounds must be between 50 and 700)

EolConfirm 

Confirm end-of-line test step (value bounds must be between 0 and 0)

Definition at line 14 of file serial_control.h.

14  {
17  Heartbeat = 0,
24  VentilationMode = 1,
26  PlateauPressure = 2,
28  PEEP = 3,
30  CyclesPerMinute = 4,
33  ExpiratoryTerm = 5,
35  TriggerEnabled = 6,
37  TriggerOffset = 7,
41  AlarmSnooze = 9,
47  TiMin = 12,
49  TiMax = 13,
69  TargetTidalVolume = 20,
76  PlateauDuration = 23,
78  LeakAlarmThreshold = 24,
85  Locale = 27,
87  PatientHeight = 28,
89  PatientGender = 29,
93  EolConfirm = 31,
94 };
@ PatientHeight
Patient's height in centimeters.
@ Heartbeat
Heartbeat used for the RPi watchdog feature (value is ignored except for the special value DISABLE_RP...
@ CyclesPerMinute
Number of cycles per minute (value bounds must be between 5 and 35)
@ TiMin
Minimum duration of inhalation in ms (value bounds must be between 100 and 3000)
@ HighInspiratoryMinuteVolumeAlarmThreshold
Threshold for high inspiratory minute volume alarm in L/min (value bounds must be between 10 and 40)
@ RespirationEnabled
State of the respiration (value must be 1 if enabled and 0 if disabled)
@ ExpiratoryTriggerFlow
Expiratory trigger flow in percent.
@ LowTidalVolumeAlarmThreshold
Threshold for low tidal volume in mL (value bounds must be between 0 and 1000)
@ TriggerEnabled
State of the trigger (value must be 1 if enabled and 0 if disabled)
@ PatientGender
Patient's gender (0 = male, 1 = female)
@ EolConfirm
Confirm end-of-line test step (value bounds must be between 0 and 0)
@ HighRespiratoryRateAlarmThreshold
Threshold for high respiratory rate alarm in cycle per minute (value bounds must be between 15 and 35...
@ LowExpiratoryMinuteVolumeAlarmThreshold
Threshold for low expiratory minute volume alarm in L/min (value bounds must be between 0 and 20)
@ LowInspiratoryMinuteVolumeAlarmThreshold
Threshold for low inspiratory minute volume alarm in L/min (value bounds must be between 0 and 20)
@ TargetTidalVolume
Target tidal volume in mL (value bounds must be between 50 and 2000)
@ LeakAlarmThreshold
Threshold for leak alarm in cL/min (value bounds must be between 0 and 10000)
@ InspiratoryDuration
Duration of inspiration in ms (value bounds must be between 200 and 3000)
@ HighTidalVolumeAlarmThreshold
Threshold for high tidal volume in mL (value bounds must be between 50 and 2000)
@ TargetInspiratoryFlow
Target flow during inspiration in L/min (value bounds must be between 5 and 80)
@ HighExpiratoryMinuteVolumeAlarmThreshold
Threshold for high expiratory minute volume alarm in L/min (value bounds must be between 10 and 40)
@ InspiratoryTriggerFlow
Inspiratory trigger flow in percent.
@ LowRespiratoryRateAlarmThreshold
Threshold for low respiratory rate alarm in cycle per minute (value bounds must be between 5 and 25)
@ Locale
Language of the system; this should be two letters (see ISO 639-1) in ASCII representation as two u8.
@ ExpiratoryTerm
Expiration term in the "Inspiration/Expiration" ratio given that Inspiration = 10 (value bounds must ...
@ PlateauPressure
Plateau pressure in mmH2O (value bounds must be between 100 and 400)
@ TiMax
Maximum duration of inhalation in ms (value bounds must be between 200 and 5000)
@ TriggerOffset
Trigger offset in mmH2O (value bounds must be between 0 and 100)
@ PEEP
PEEP in mmH2O (value bounds must be between 0 and 300)
@ AlarmSnooze
Alarm snooze (value must be 1 to snooze and 0 to unsnooze)
@ VentilationMode
Ventilation mode, must be one of the following:
@ PeakPressureAlarmThreshold
Threshold for peak pressure alarm in mmH2O (value bounds must be between 50 and 700)
@ PlateauDuration
Duration in ms of closing both valves to effectively measure plateau pressure in volume control modes...

Function Documentation

◆ serialControlLoop()

void serialControlLoop ( )

Parse input and handle changes of settings.

Warning
This must be used after initTelemetry()

Definition at line 61 of file serial_control.cpp.

61  {
62  // Let's note this current time to avoid blocking too long here
63  int time = millis();
64 
65  // We need to ensure we received the whole message
66  while (((time + 2) >= millis()) && (Serial6.available() >= 11)) {
67  // Let's check the first header byte
68  if (Serial6.peek() == header[0]) {
69  // If it is correct, we discard it and continue
70  (void)Serial6.read();
71 
72  // Let's check the second header byte
73  if (Serial6.peek() == header[1]) {
74  // If it is correct, we discard it and continue
75  (void)Serial6.read();
76 
77  // Let's prepare to compute a CRC
78  CRC32 computedCRC;
79 
80  byte setting = Serial6.read();
81  computedCRC.update(setting);
82 
83  byte rawValue[2];
84  Serial6.readBytes(rawValue, 2);
85  computedCRC.update(rawValue, 2);
86  uint16_t value = toU16(rawValue);
87 
88  byte rawExpectedCRC[4];
89  Serial6.readBytes(rawExpectedCRC, 4);
90  uint32_t expectedCRC = toU32(rawExpectedCRC);
91 
92  // Let's check that the 2 bytes footer is correct
93  if ((Serial6.read() != footer[0]) || (Serial6.read() != footer[1])) {
94  DBG_DO(Serial.println(
95  "Invalid footer for control message; discarding whole message"));
96  continue;
97  }
98 
99  // The computed CRC must be the same as the one included with the message
100  if (expectedCRC != computedCRC.finalize()) {
101  DBG_DO(Serial.println(
102  "Invalid CRC for control message; discarding whole message"));
103  continue;
104  }
105 
106  DBG_DO({
107  Serial.print("Serial control message: setting = ");
108  Serial.print(setting);
109  Serial.print(", value = ");
110  Serial.print(value);
111  Serial.println();
112  });
113 
114  switch (setting) {
115  case Heartbeat:
116  if (value == DISABLE_RPI_WATCHDOG) {
118  } else {
120  }
121  break;
122 
123  case VentilationMode:
125  break;
126 
127  case PlateauPressure:
129  break;
130 
131  case PEEP:
132  mainController.onPeepSet(value);
133  break;
134 
135  case CyclesPerMinute:
136  mainController.onCycleSet(value);
137  break;
138 
139  case ExpiratoryTerm:
141  break;
142 
143  case TriggerEnabled:
145  break;
146 
147  case TriggerOffset:
149  break;
150 
151  case RespirationEnabled:
153  break;
154 
155  case AlarmSnooze:
157  break;
158 
161  break;
162 
165  break;
166 
167  case TiMin:
168  mainController.onTiMinSet(value);
169  break;
170 
171  case TiMax:
172  mainController.onTiMaxSet(value);
173  break;
174 
177  break;
178 
181  break;
182 
185  break;
186 
189  break;
190 
193  break;
194 
197  break;
198 
199  case TargetTidalVolume:
201  break;
202 
205  break;
206 
209  break;
210 
211  case PlateauDuration:
213  break;
214 
215  case LeakAlarmThreshold:
217  break;
218 
221  break;
222 
223  case InspiratoryDuration:
225  break;
226 
227  case Locale:
228  // TODO
229  break;
230 
231  case PatientHeight:
233  break;
234 
235  case PatientGender:
237  break;
238 
241  break;
242 
243  case EolConfirm:
244  eolTest.onConfirm();
245  break;
246 
247  default:
248  DBG_DO({
249  Serial.print("Unknown control setting: ");
250  Serial.print(setting);
251  Serial.println();
252  });
253  break;
254  }
255  } else {
256  // This is not the begining of a message, let's discard it
257  (void)Serial6.read();
258  DBG_DO(Serial.println("Invalid header for control message; discarding a byte"));
259  }
260  } else {
261  // This is not the begining of a message, let's discard it
262  (void)Serial6.read();
263  DBG_DO(Serial.println("Invalid header for control message; discarding a byte"));
264  }
265  }
266 }
ActivationController activationController
Instance of the activation controller.
Definition: activation.cpp:21
AlarmController alarmController
Instance of the alarm controller.
void changeState(uint16_t state)
Change the current state.
Definition: activation.cpp:29
void snooze()
Snooze alarm for 2 minutes.
void onConfirm()
Handle EOL confirm control setting from telemetry.
void onTargetInspiratoryFlow(uint16_t p_targetInspiratoryFlow)
Set the inspiratory flow target.
void onTriggerOffsetSet(uint16_t p_triggerOffset)
Set the desired offset for expiratory trigger.
void onInspiratoryDuration(uint16_t p_inspiratoryDuration)
Set the inspiration duration.
void onCycleSet(uint16_t p_cpm)
Set the desired number of cycles per minute.
void onLowTidalVolumeAlarmThresholdSet(uint16_t p_lowTidalVolumeAlarmThreshold)
Set threshold on tidal volume below which an alarm is raised.
void onlowRespiratoryRateAlarmThresholdSet(uint16_t p_lowRespiratoryRateAlarmThreshold)
Set alarm threshold for low respiratory rate.
void onLeakAlarmThresholdSet(uint16_t p_leakAlarmThreshold)
Set the threshold for leak that raise the alarm.
void onExpiratoryTermSet(uint16_t p_expiratoryTerm)
Set the desired expiratory term.
void onhighRespiratoryRateAlarmThresholdSet(uint16_t p_highRespiratoryRateAlarmThreshold)
Set alarm threshold for high respiratory rate.
void onTiMinSet(uint16_t p_tiMin)
Set min inspiratory time.
void onInspiratoryTriggerFlowSet(uint16_t p_inspiratoryTriggerFlow)
Set inspiratory trigger flow.
void onTiMaxSet(uint16_t p_tiMax)
Set max inspiratory time.
void onPeepSet(int16_t p_peep)
Set the desired PEEP.
void onPeakPressureAlarmThreshold(int16_t p_peakPressureAlarmThreshold)
Set the desired threshold for max peak pressure.
void onLowExpiratoryMinuteVolumeAlarmThresholdSet(uint16_t p_lowExpiratoryMinuteVolumeAlarmThreshold)
Set alarm threshold for low expiratory minute volume.
void onPlateauPressureSet(int16_t p_plateauPressure)
Set the desired plateau pressure.
void onPatientHeight(int16_t p_patientHeight)
Set the desired patient height.
void onPatientGender(int16_t p_patientGender)
Set the desired patient gender.
void onLowInspiratoryMinuteVolumeAlarmThresholdSet(uint16_t p_lowInspiratoryMinuteVolumeAlarmThreshold)
Set alarm threshold for low inspiratory minute volume.
void onHighInspiratoryMinuteVolumeAlarmThresholdSet(uint16_t p_highInspiratoryMinuteVolumeAlarmThreshold)
Set alarm threshold for high inspiratory minute volume.
void onVentilationModeSet(uint16_t p_ventilationControllerMode)
Set ventilation mode.
void onTargetTidalVolumeSet(uint16_t p_targetTidalVolume)
Set target tidal volume (used in VC modes)
void onHighExpiratoryMinuteVolumeAlarmThresholdSet(uint16_t p_highExpiratoryMinuteVolumeAlarmThreshold)
Set alarm threshold for high expiratory minute volume.
void onPlateauDurationSet(uint16_t p_plateauDuration)
Set the duration of Pause at the end of expiration in VC modes.
void onExpiratoryTriggerFlowSet(uint16_t p_expiratoryTriggerFlow)
Set expiratory trigger flow.
void onTriggerModeEnabledSet(uint16_t p_triggerEnabled)
Enable or disable expiratory trigger mode.
void onHighTidalVolumeAlarmThresholdSet(uint16_t p_highTidalVolumeAlarmThreshold)
Set threshold on tidal volume for which an alarm is raised.
void disable()
Disable countdown mode (used for debug)
void resetCountDown()
When the UI software on the Raspberry PI sends a heartbeat, reset countdown.
#define DBG_DO(statement)
Expand arbitrary code only when in debug mode.
Definition: debug.h:24
EolTest eolTest
MainController mainController
HardwareSerial Serial6(PIN_TELEMETRY_SERIAL_RX, PIN_TELEMETRY_SERIAL_TX)
RpiWatchdog rpiWatchdog
static const uint8_t header[CONTROL_HEADER_SIZE]
uint16_t toU16(byte bytes[])
Convert an array of 2 bytes to a u16.
static const uint8_t footer[CONTROL_FOOTER_SIZE]
uint32_t toU32(byte bytes[])
Convert an array of 4 bytes to a u32.
#define DISABLE_RPI_WATCHDOG
Special value that can be used in a heartbeat control message to disable RPi watchdog.