Skip to content

Commit

Permalink
Merge pull request #61 from mit-drl/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
amadoantonini authored Apr 27, 2020
2 parents 8861e3b + 10b78da commit 4f2c212
Show file tree
Hide file tree
Showing 35 changed files with 4,281 additions and 582 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# based on https://blog.arduino.cc/2019/11/14/arduino-on-github-actions/

name: build

on: [push, pull_request]

jobs:

build-matrix:

strategy:

matrix:
os: [windows-latest, ubuntu-latest]

arduino-platform: ["arduino:avr"]

include:
- arduino-platform: "arduino:avr"
fqbn: "arduino:avr:mega:cpu=atmega2560"

runs-on: ${{ matrix.os }}

steps:
- name: Checkout
uses: actions/checkout@master

- name: Setup Arduino CLI
uses: arduino/[email protected]

- name: Install platform
run: |
arduino-cli core update-index
arduino-cli core install ${{ matrix.arduino-platform }}
arduino-cli lib install SD LiquidCrystal
- name: Compile Sketch
run: arduino-cli compile --fqbn ${{ matrix.fqbn }} ./e-vent.ino

158 changes: 114 additions & 44 deletions Alarms.cpp
Original file line number Diff line number Diff line change
@@ -1,56 +1,82 @@
/**
* MIT License
*
* Copyright (c) 2020 MIT E-Vent
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/**
* Alarms.cpp
*/

#include "Alarms.h"


namespace alarms {


/// DebouncedButton ///

DebouncedButton::DebouncedButton(const int& pin): pin_(pin) {}
/// Tone ///

void DebouncedButton::begin() {
pinMode(pin_, INPUT_PULLUP);
}
Tone::Tone(const Note notes[], const int& notes_length, const int* pin):
notes_(notes),
pin_(pin),
length_(notes_length),
tone_step_(length_) {}

bool DebouncedButton::is_LOW() {
int reading = digitalRead(pin_);

bool low_value = false;
const unsigned long time_now = millis();
if (reading == LOW) {
if ((time_now - last_low_time_) > kDebounceDelay) {
low_value = true;
}
last_low_time_ = time_now;
void Tone::play() {
if (length_ == 0) {
return;
}
if (!playing_) { // Do once when tone starts
tone_timer_ = millis();
tone_step_ = 0;
playing_ = true;
}
tone_step_ %= length_; // Start again if tone finished
if (millis() > tone_timer_) {
tone(*pin_, notes_[tone_step_].note, notes_[tone_step_].duration);
tone_timer_ += notes_[tone_step_].duration + notes_[tone_step_].pause;
tone_step_ ++;
}
return low_value;
}


/// Beeper ///

Beeper::Beeper(const int& beeper_pin, const int& snooze_pin):
beeper_pin_(beeper_pin),
snooze_button_(snooze_pin) {}

void Beeper::begin() {
snooze_button_.begin();
pinMode(beeper_pin_, OUTPUT);
}

void Beeper::update() {
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 (alarms_on_ && !snoozed_) {
if(tone_step_ == kNotesLen) tone_step_ = 0; // Start again if tone finished
play();
if (snoozed_) {
stop();
} else {
tone_step_ = kNotesLen;
play(alarm_level);
}
}

Expand All @@ -67,23 +93,34 @@ void Beeper::toggleSnooze() {
}
}

void Beeper::play(){
unsigned long current = millis();
if (tone_step_ == kNotesLen) return; // The tone has completed
if(current > tone_timer_){
tone(beeper_pin_, kNotes[tone_step_], kNoteDurations[tone_step_]);
tone_timer_ = current + kNoteDurations[tone_step_] + kNotePauses[tone_step_];
tone_step_ ++;
void Beeper::play(const AlarmLevel& alarm_level) {
for (int i = 0; i < NUM_LEVELS; i++) {
if (i != alarm_level) {
tones_[i].stop();
}
}
tones_[alarm_level].play();
}

void Beeper::stop() {
for (int i = 0; i < NUM_LEVELS; i++) {
tones_[i].stop();
}
}


/// Alarm ///

Alarm::Alarm(const String& text, const int& min_bad_to_trigger, const int& min_good_to_clear):
text_(text),
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),
min_bad_to_trigger_(min_bad_to_trigger),
min_good_to_clear_(min_good_to_clear) {}
min_good_to_clear_(min_good_to_clear),
alarm_level_(alarm_level) {}

void Alarm::reset() {
*this = Alarm::Alarm(text_, min_bad_to_trigger_, min_good_to_clear_, alarm_level_);
}

void Alarm::setCondition(const bool& bad, const unsigned long& seq) {
if (bad) {
Expand All @@ -103,22 +140,45 @@ void Alarm::setCondition(const bool& bad, const unsigned long& seq) {
}
}

void Alarm::setText(const String& text) {
if (text.length() == display::kWidth) {
text_ = text;
}
else if (text.length() > display::kWidth) {
text_ = text.substring(0, display::kWidth);
}
else {
text_ = text;
while (text_.length() < display::kWidth) {
text_ += " ";
}
}
}


/// AlarmManager ///

void AlarmManager::begin() {
beeper_.begin();
pinMode(led_pin_, OUTPUT);
}

void AlarmManager::update() {
const String text = getText();
displ_->writeAlarmText(text);
if (text.length() > 0) {
beeper_.alarmsON();
} else {
beeper_.alarmsOFF();
displ_->setAlarmText(getText());
AlarmLevel highest_level = getHighestLevel();
beeper_.update(highest_level);
if (highest_level > NO_ALARM) {
digitalWrite(led_pin_, led_pulse_.read() ? HIGH : LOW);
}
else {
digitalWrite(led_pin_, LOW);
}
}

void AlarmManager::allOff() {
for (int i = 0; i < NUM_ALARMS; i++) {
alarms_[i].reset();
}
beeper_.update();
}

int AlarmManager::numON() const {
Expand All @@ -129,7 +189,7 @@ int AlarmManager::numON() const {
return num;
}

const String AlarmManager::getText() const {
String AlarmManager::getText() const {
const int num_on = numON();
String text = "";
if (num_on > 0) {
Expand All @@ -147,5 +207,15 @@ const String AlarmManager::getText() const {
return text;
}

AlarmLevel AlarmManager::getHighestLevel() const {
AlarmLevel alarm_level = NO_ALARM;
for (int i = 0; i < NUM_ALARMS; i++) {
if (alarms_[i].isON()) {
alarm_level = max(alarm_level, alarms_[i].alarmLevel());
}
}
return alarm_level;
}


} // namespace alarms
Loading

0 comments on commit 4f2c212

Please sign in to comment.