Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
66aee68
use the assit control flag with display, reverse map the trigger sens…
abukhalaf Apr 3, 2020
7c922fb
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 4, 2020
6445c58
trigger sensitivty knob [2<5<off]
abukhalaf Apr 4, 2020
8f02eb1
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 7, 2020
253d924
remove inhale type in favor to patienttriggered flag
abukhalaf Apr 7, 2020
6fadcbe
Create LICENSE
abukhalaf Apr 7, 2020
71bb064
Update LICENSE
abukhalaf Apr 7, 2020
75a1156
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 7, 2020
6d13a1e
add patient and time icons
abukhalaf Apr 8, 2020
7866ee0
update flag
abukhalaf Apr 8, 2020
bc37ea5
adjust the patient icon
abukhalaf Apr 8, 2020
45bb7c0
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 8, 2020
414b9f3
revert to [OFF, 2, 5] trigger sensitivty scale
abukhalaf Apr 8, 2020
9337c35
revert to [OFF, 2, 5] trigger sensitivty scale
abukhalaf Apr 8, 2020
fcf83d7
adjust message length to avoid flickering; add hide icon called at st…
abukhalaf Apr 8, 2020
6a8fe20
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 13, 2020
a360e51
rename flag
abukhalaf Apr 13, 2020
54176cf
defined icon constants in header file
abukhalaf Apr 13, 2020
6908c13
Merge branch 'develop' into AssistControl_cleanup
abukhalaf Apr 14, 2020
a329931
fix constant name
abukhalaf Apr 14, 2020
053227a
move indicators to row 3 column 11
abukhalaf Apr 15, 2020
31b0471
Merge branch 'develop' into AssistControl_cleanup
abukhalaf May 8, 2020
deb5439
bug fix: ensure 2.0 AC knob setting is ON
abukhalaf May 8, 2020
419383f
bug fix: ensure 2.0 AC knob setting is ON
abukhalaf May 9, 2020
d0729ca
Merge branch 'develop' into AssistControl_cleanup
abukhalaf May 28, 2020
b299a07
Adding Indicators, and Rearranging Knob Displaying
abukhalaf Jun 2, 2020
5ff896e
Display Snooze Timer, Created Footer for Confirm
abukhalaf Jun 4, 2020
1215201
Ensure snooze timer disappears when no alarms
abukhalaf Jun 4, 2020
b956a7f
Eliminate a space overlap
abukhalaf Jun 5, 2020
168de9f
Hide snooze timer for edge cases; unsnooze for no alarms
abukhalaf Jun 5, 2020
ea44e8c
Assign each knob a confim alarm, and cycle through
abukhalaf Jun 5, 2020
47c7caf
Display 1st PEEP measurement; Fix typo in logger
abukhalaf Jun 13, 2020
152e899
Simplify #29 and #50 refactoring
abukhalaf Jul 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 75 additions & 10 deletions Alarms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,24 @@ void Beeper::update(const AlarmLevel& alarm_level) {
if (snoozeButtonPressed()) {
toggleSnooze();
}

// check if snooze time is up
if (snoozed_ && millis() - snooze_time_ > kSnoozeTime) {
snoozed_ = false;
}

if (snoozed_) {
stop();
timeRemaining_ = (kSnoozeTime - (millis() - snooze_time_)) / 1000UL;
} else {
play(alarm_level);
}

// Reset snooze timer when alarms are gone
if (alarm_level == NO_ALARM) {
timeRemaining_ = 0; // Hides timer when snoozed with no alarms
snoozed_ = false; // Ensures beeping as soon a new alarm emerges
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the expected behavior. Per expert guidance, the alarms should stay silent for the snooze time even when a new alarm emerges.

See https://emergency-vent.mit.edu/controls/list-of-alarms/

}
}

bool Beeper::snoozeButtonPressed() const {
Expand All @@ -89,9 +98,10 @@ bool Beeper::snoozeButtonPressed() const {
void Beeper::toggleSnooze() {
if (snoozed_) {
snoozed_ = false;
timeRemaining_ = 0; // Hides timer count when beeping
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getRemainingSnoozeTime function should have the logic of what to return when not snoozed, rather than cluttering up toggleSnooze

} else {
snoozed_ = true;
snooze_time_ = millis();
snooze_time_ = millis();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary whitespace

}
}

Expand All @@ -110,12 +120,15 @@ void Beeper::stop() {
}
}

unsigned long Beeper::getRemainingSnoozeTime() {
return timeRemaining_;
}

/// Alarm ///

Alarm::Alarm(const String& default_text, const int& min_bad_to_trigger,
const int& min_good_to_clear, const AlarmLevel& alarm_level):
text_(default_text),
text_(default_text.substring(0, display::kHeaderLength-1)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kHeaderLength is already 1 shorter than the display width. Why subtract another?

min_bad_to_trigger_(min_bad_to_trigger),
min_good_to_clear_(min_good_to_clear),
alarm_level_(alarm_level) {}
Expand Down Expand Up @@ -143,15 +156,15 @@ void Alarm::setCondition(const bool& bad, const unsigned long& seq) {
}

void Alarm::setText(const String& text) {
if (text.length() == display::kWidth) {
if (text.length() == display::kFooterLength) {
text_ = text;
}
else if (text.length() > display::kWidth) {
text_ = text.substring(0, display::kWidth);
else if (text.length() > display::kFooterLength) {
text_ = text.substring(0, display::kFooterLength);
}
else {
text_ = text;
while (text_.length() < display::kWidth) {
while (text_.length() < display::kFooterLength) {
text_ += " ";
}
}
Expand All @@ -166,7 +179,9 @@ void AlarmManager::begin() {
}

void AlarmManager::update() {
displ_->setAlarmText(getText());
displ_->setAlarmText(getGeneralAlarmText());
displ_->setUnconfirmedKnobAlarmText(getUnconfirmedKnobText());
displ_->setSnoozeText(beeper_.getRemainingSnoozeTime());
AlarmLevel highest_level = getHighestLevel();
beeper_.update(highest_level);
if (highest_level > NO_ALARM) {
Expand All @@ -191,16 +206,66 @@ int AlarmManager::numON() const {
return num;
}

String AlarmManager::getText() const {
const int num_on = numON();
int AlarmManager::numON_Confirm() const {
int num = 0;
bool aConfirmAlarm;
for (int i = 0; i < NUM_ALARMS; i++) {
aConfirmAlarm = (i==NOT_CONFIRM_TV || i==NOT_CONFIRM_RR ||
i==NOT_CONFIRM_IE || i==NOT_CONFIRM_AC);
if(aConfirmAlarm) {
num += (int)alarms_[i].isON();
}
}
return num;
}

int AlarmManager::numON_NonConfirm() const {
int num = 0;
bool aConfirmAlarm;
for (int i = 0; i < NUM_ALARMS; i++) {
aConfirmAlarm = (i==NOT_CONFIRM_TV || i==NOT_CONFIRM_RR ||
i==NOT_CONFIRM_IE || i==NOT_CONFIRM_AC);
if(!aConfirmAlarm) {
num += (int)alarms_[i].isON();
}
}
return num;
}

String AlarmManager::getGeneralAlarmText() const {
const int num_on = numON_NonConfirm();
String text = "";
if (num_on > 0) {
// determine which of the on alarms to display
const int index = millis() % (num_on * kDisplayTime) / kDisplayTime;
int count_on = 0;
int i;
bool aConfirmAlarm;
for (i = 0; i < NUM_ALARMS; i++) {
aConfirmAlarm = (i==NOT_CONFIRM_TV || i==NOT_CONFIRM_RR ||
i==NOT_CONFIRM_IE || i==NOT_CONFIRM_AC);
if (!aConfirmAlarm && alarms_[i].isON()) {
if (count_on++ == index) break;
}
}
text = alarms_[i].text();
}
return text;
}

String AlarmManager::getUnconfirmedKnobText() const {
const int num_on = numON_Confirm();
String text = "";
if (num_on > 0) {
// determine which of the on alarms to display
const int index = millis() % (num_on * kDisplayTime) / kDisplayTime;
int count_on = 0;
int i;
bool aConfirmAlarm;
for (i = 0; i < NUM_ALARMS; i++) {
if (alarms_[i].isON()) {
aConfirmAlarm = (i==NOT_CONFIRM_TV || i==NOT_CONFIRM_RR ||
i==NOT_CONFIRM_IE || i==NOT_CONFIRM_AC);
if (aConfirmAlarm && alarms_[i].isON()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is confusing and brittle. Now that the confirm knobs and alarms are being written to different places, they should be treated differently. But hardcoding the list of which alarms are confirm alarms, and writing these almost duplicate functions is bad practice. We should abstract the logic of which alarms are in which cycle, so we don't need to hardcode checks and write code multiple times

if (count_on++ == index) break;
}
}
Expand Down
60 changes: 45 additions & 15 deletions Alarms.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,16 @@ class Beeper {
// Update during arduino loop()
void update(const AlarmLevel& alarm_level);

// Get snooze time remaining
unsigned long getRemainingSnoozeTime();

private:
const int beeper_pin_;
buttons::DebouncedButton snooze_button_;
Tone tones_[NUM_LEVELS];

unsigned long snooze_time_ = 0;
unsigned long timeRemaining_ = 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alarms class still uses milliseconds to represent time (from before the convention was set). However, it's confusing to now set timeRemaining to be seconds. We should either switch everything to floats in seconds (ideal) or leave it in milliseconds consistently until a future update.

bool snoozed_ = false;

bool snoozeButtonPressed() const;
Expand All @@ -155,6 +159,7 @@ class Beeper {
void play(const AlarmLevel& alarm_level);

void stop();

};


Expand All @@ -177,7 +182,7 @@ class Alarm {
// for at least `min_good_to_clear_` consecutive calls with different `seq`.
void setCondition(const bool& bad, const unsigned long& seq);

// Set the alarm text (trim or pad to display width)
// Set the alarm text (trim or pad to footer width)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to footer width when some alarms are in the header?

void setText(const String& text);

// Check if this alarm is on
Expand Down Expand Up @@ -222,11 +227,17 @@ class AlarmManager {
NO_TIDAL_PR,
OVER_CURREN,
MECH_FAILUR,
NOT_CONFIRM,
NOT_CONFIRM_TV,
NOT_CONFIRM_RR,
NOT_CONFIRM_IE,
NOT_CONFIRM_AC,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need separate alarms for each not_confirm? The old way was better since it's really the same alarm

TURNING_OFF,
NUM_ALARMS
};

// Number of NOT_CONFIRM_XX alarms
static const int numConfirmKnob = 4;

public:
AlarmManager(const int& beeper_pin, const int& snooze_pin, const int& led_pin,
Display* displ, unsigned long const* cycle_count):
Expand All @@ -235,15 +246,18 @@ class AlarmManager {
led_pin_(led_pin),
led_pulse_(500, 0.5),
cycle_count_(cycle_count) {
alarms_[HIGH_PRESSU] = Alarm(" HIGH PRESSURE ", 1, 2, EMERGENCY);
alarms_[HIGH_PRESSU] = Alarm("HIGH PRESSURE ", 1, 2, EMERGENCY);
alarms_[LOW_PRESSUR] = Alarm("LOW PRES DISCONNECT?", 1, 1, EMERGENCY);
alarms_[BAD_PLATEAU] = Alarm(" HIGH RESIST PRES ", 1, 1, NOTIFY);
alarms_[UNMET_VOLUM] = Alarm(" UNMET TIDAL VOLUME ", 1, 1, EMERGENCY);
alarms_[NO_TIDAL_PR] = Alarm(" NO TIDAL PRESSURE ", 2, 1, EMERGENCY);
alarms_[OVER_CURREN] = Alarm(" OVER CURRENT FAULT ", 1, 2, EMERGENCY);
alarms_[MECH_FAILUR] = Alarm(" MECHANICAL FAILURE ", 1, 1, EMERGENCY);
alarms_[NOT_CONFIRM] = Alarm(" CONFIRM? ", 1, 1, NOTIFY);
alarms_[TURNING_OFF] = Alarm(" TURNING OFF ", 1, 1, OFF_LEVEL);
alarms_[BAD_PLATEAU] = Alarm("HIGH RESIST PRES ", 1, 1, NOTIFY);
alarms_[UNMET_VOLUM] = Alarm("UNMET TIDAL VOLUME ", 1, 1, EMERGENCY);
alarms_[NO_TIDAL_PR] = Alarm("NO TIDAL PRESSURE ", 2, 1, EMERGENCY);
alarms_[OVER_CURREN] = Alarm("OVER CURRENT FAULT ", 1, 2, EMERGENCY);
alarms_[MECH_FAILUR] = Alarm("MECHANICAL FAILURE ", 1, 1, EMERGENCY);
alarms_[NOT_CONFIRM_TV] = Alarm("CONFIRM? ", 1, 1, NOTIFY);
alarms_[NOT_CONFIRM_RR] = Alarm("CONFIRM? ", 1, 1, NOTIFY);
alarms_[NOT_CONFIRM_IE] = Alarm("CONFIRM? ", 1, 1, NOTIFY);
alarms_[NOT_CONFIRM_AC] = Alarm("CONFIRM? ", 1, 1, NOTIFY);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is all this duplicating of NOT_CONFIRM really needed?

alarms_[TURNING_OFF] = Alarm("TURNING OFF ", 1, 1, OFF_LEVEL);
}

// Setup during arduino setup()
Expand Down Expand Up @@ -291,8 +305,13 @@ class AlarmManager {
}

// Setting not confirmed
inline void unconfirmedChange(const bool& value, const String& message = "") {
if (value) {
inline void unconfirmedChange(const bool& value, const String& message = "", const display::DisplayKey& key = 0) {
Indices NOT_CONFIRM;
if (key == display::DisplayKey::VOLUME) { NOT_CONFIRM = NOT_CONFIRM_TV;}
if (key == display::DisplayKey::BPM) { NOT_CONFIRM = NOT_CONFIRM_RR;}
if (key == display::DisplayKey::IE_RATIO) { NOT_CONFIRM = NOT_CONFIRM_IE;}
if (key == display::DisplayKey::AC_TRIGGER) { NOT_CONFIRM = NOT_CONFIRM_AC;}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here again... this will be very hard to maintain

if (value) {
alarms_[NOT_CONFIRM].setText(message);
}
alarms_[NOT_CONFIRM].setCondition(value, *cycle_count_);
Expand All @@ -310,7 +329,7 @@ class AlarmManager {
inline const bool& getNoTidalPres() { return alarms_[NO_TIDAL_PR].isON(); }
inline const bool& getOverCurrent() { return alarms_[OVER_CURREN].isON(); }
inline const bool& getMechanicalFailure() { return alarms_[MECH_FAILUR].isON(); }
inline const bool& getUnconfirmedChange() { return alarms_[NOT_CONFIRM].isON(); }
//inline const bool& getUnconfirmedChange() { return alarms_[NOT_CONFIRM].isON(); }
inline const bool& getTurningOFF() { return alarms_[TURNING_OFF].isON(); }

private:
Expand All @@ -319,13 +338,24 @@ class AlarmManager {
int led_pin_;
utils::Pulse led_pulse_;
Alarm alarms_[NUM_ALARMS];
Alarm alarmsHeader_[NUM_ALARMS-numConfirmKnob];
Alarm alarmsFooter_[numConfirmKnob];
unsigned long const* cycle_count_;

// Get number of alarms that are ON
int numON() const;

// Get text to display
String getText() const;
// Get number of knob confirm alarms that are ON
int numON_Confirm() const;

// Get number of nonconfirm alarms that are ON
int numON_NonConfirm() const;

// Get general alarm text to display
String getGeneralAlarmText() const;

// Get unconfirmed knob alarm text to display
String getUnconfirmedKnobText() const;

// Get highest priority level of the alarms that are ON
AlarmLevel getHighestLevel() const;
Expand Down
Loading