diff --git a/flight-computer.ino b/flight-computer.ino index 48af264..370c6c3 100644 --- a/flight-computer.ino +++ b/flight-computer.ino @@ -4,15 +4,17 @@ #include "mosfet_igniter.h" #include "adafruit_gps_api.h" #include "definitions.h" +#include "BuzzerService.h" LSM9DS1_API imu_sensor = LSM9DS1_API::getInstance(); BMP3XX_API altimeter = BMP3XX_API::getInstance(); Telemetry telemetry = Telemetry::getInstance(); MosfetIgniter igniter = MosfetIgniter::getInstance(); Adafruit_GPS_API gps = Adafruit_GPS_API::getInstance(); +BuzzerService& buzzerService = BuzzerService::GetInstance(); FSM *fsm; + // TODO: improve buzzer code -const int buzzer = 17; bool sound = false; uint8_t loop_frequency = 10; // Hz @@ -21,16 +23,7 @@ void setup() { Serial.begin(115200); #endif -#if BUZZER - pinMode(buzzer, OUTPUT); - tone(buzzer, 500); -#endif - - fsm = new FSM(&telemetry, &imu_sensor, &altimeter, &gps, &igniter, &loop_frequency); - -#if BUZZER - noTone(buzzer); -#endif + fsm = new FSM(&telemetry, &imu_sensor, &altimeter, &gps, &igniter, &loop_frequency, &buzzerService); } void loop() { @@ -38,6 +31,15 @@ void loop() { if (telemetry.messageAvailable()) { String message = telemetry.receiveMessage(); + if (message.substring(0, 5).equals("BUZZR")) { + if (message.equals("BUZZR:ON-")) { + buzzerService.TurnOn(); + } + else if (message.equals("BUZZR:OFF")) + { + buzzerService.TurnOff(); + } + } if (message.substring(0, 5).equals("SPCMD")) { int event; if (sscanf(message.c_str(), "SPCMD:%i--", &event) == 1) { @@ -53,16 +55,6 @@ void loop() { } #endif -#if BUZZER - if (sound) { - sound = false; - noTone(buzzer); - } else { - sound = true; - tone(buzzer, 500); - } -#endif - fsm->runCurrentState(); int delayTime = (1000/loop_frequency) - (millis() - timerStart); diff --git a/libraries/BuzzerService.cpp b/libraries/BuzzerService.cpp new file mode 100644 index 0000000..f3ec3a8 --- /dev/null +++ b/libraries/BuzzerService.cpp @@ -0,0 +1,68 @@ +#include "BuzzerService.h" + +#include + +#include + +static BuzzerService* buzzerService = (BuzzerService*)NULL; + +BuzzerService::BuzzerService() +{ + pinMode(this->_buzzerPin, OUTPUT); +} + +BuzzerService& BuzzerService::GetInstance() +{ + bool buzzerServiceNotInitialized = (buzzerService == (BuzzerService*)NULL); + + if (buzzerServiceNotInitialized) + { + buzzerService = new BuzzerService(); + } + + return *buzzerService; +} + +void BuzzerService::Lock() +{ + this->_locked = true; +} + +void BuzzerService::Unlock() +{ + this->_locked = false; +} + +void BuzzerService::TurnOn() +{ + if (!this->_canTurnOn || this->_locked) + { + return; + } + + tone(this->_buzzerPin, 500); +} + +void BuzzerService::TurnOff() +{ + if (this->_locked) + { + return; + } + + noTone(this->_buzzerPin); +} + +void BuzzerService::CanTurnOn() +{ + this->_canTurnOn = true; +} + +void BuzzerService::CannotTurnOn() +{ + this->_canTurnOn = false; + + noTone(this->_buzzerPin); +} + +BuzzerService::~BuzzerService() { } \ No newline at end of file diff --git a/libraries/BuzzerService.h b/libraries/BuzzerService.h new file mode 100644 index 0000000..905f6a9 --- /dev/null +++ b/libraries/BuzzerService.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +class BuzzerService +{ + private: + uint8_t _buzzerPin = 17; + bool _canTurnOn = true; + bool _locked = false; + + BuzzerService(); + public: + BuzzerService(const BuzzerService& obj) = delete; + BuzzerService& operator=(const BuzzerService& obj) = delete; + + BuzzerService(BuzzerService&& deadObj) = default; + BuzzerService& operator=(BuzzerService&& deadObj) = default; + + static BuzzerService& GetInstance(); + + void Lock(); + void Unlock(); + + void TurnOn(); + void TurnOff(); + + void CanTurnOn(); + void CannotTurnOn(); + + ~BuzzerService(); +}; \ No newline at end of file diff --git a/libraries/definitions.h b/libraries/definitions.h index 183dc2a..e8a5044 100644 --- a/libraries/definitions.h +++ b/libraries/definitions.h @@ -1,5 +1,4 @@ #define SERIAL_DEBUG false #define SD_LOGS true #define IGN_DEBUG true -#define IGNITER 1 // 1 or 2 -#define BUZZER true +#define IGNITER 1 // 1 or 2 \ No newline at end of file diff --git a/libraries/fsm.cpp b/libraries/fsm.cpp index 1d7dc67..33a2269 100644 --- a/libraries/fsm.cpp +++ b/libraries/fsm.cpp @@ -15,13 +15,14 @@ #define VBATPIN A7 #define EJECTION_TIMEOUT 4000 // ms -FSM::FSM(Telemetry* telemetry, IMU* imu_sensor, Altimeter* altimeter, GPSReceiver* gps, Igniter* igniter, uint8_t* loop_frequency) +FSM::FSM(Telemetry* telemetry, IMU* imu_sensor, Altimeter* altimeter, GPSReceiver* gps, Igniter* igniter, uint8_t* loop_frequency, BuzzerService* buzzerService) : telemetry(telemetry) , imu_sensor(imu_sensor) , altimeter(altimeter) , gps(gps) , igniter(igniter) , loop_frequency(loop_frequency) + , buzzerService(buzzerService) { Transition flight_state_transitions[] = { // Ground @@ -88,6 +89,9 @@ void FSM::process_event(EVENT event) { } void FSM::onLaunched() { + buzzerService->CanTurnOn(); + buzzerService->Unlock(); + // TODO: not the best place to do that launch_time = millis(); @@ -96,6 +100,9 @@ void FSM::onLaunched() { } void FSM::onSetup() { + buzzerService->CanTurnOn(); + buzzerService->Unlock(); + telemetry->setup(); telemetry->send("Hello!"); @@ -121,9 +128,16 @@ void FSM::onSetup() { process_event(EVENT::SETUP_COMPLETE); } -void FSM::onIDLE() {} +void FSM::onIDLE() +{ + buzzerService->CanTurnOn(); + buzzerService->Unlock(); +} void FSM::onCalibration() { + buzzerService->CanTurnOn(); + buzzerService->Unlock(); + telemetry->send("Altimeter: calibrating.."); altimeter->calibrate(); telemetry->send("Altimeter: ground level set to " + String((float)altimeter->getGroundLevelCM() / 100) + "m"); @@ -136,26 +150,41 @@ void FSM::onCalibration() { } void FSM::onReady() { + buzzerService->CanTurnOn(); + buzzerService->Unlock(); + if (altimeter->agl() > LAUNCH_AGL_THRESHOLD or (imu_sensor->accelerationX() / GRAVITY) * -1 > LAUNCH_ACCELERATION_THRESHOLD) { process_event(EVENT::LAUNCHED); } } -void FSM::onEjectionTestReady() {} +void FSM::onEjectionTestReady() +{ + buzzerService->CanTurnOn(); + buzzerService->Unlock(); +} void FSM::onEjectionTestEject() { + buzzerService->CanTurnOn(); + buzzerService->Unlock(); + telemetry->setRadioThrottle(1000); *loop_frequency = 100; onDeployingChute(); } void FSM::onEjectionTestComplete() { + buzzerService->CannotTurnOn(); + buzzerService->Lock(); + telemetry->setRadioThrottle(0); *loop_frequency = 10; } void FSM::onAscending() { + buzzerService->CannotTurnOn(); + float agl = altimeter->agl(); if (agl > max_agl) { max_agl = agl; @@ -175,6 +204,9 @@ void FSM::onApogeeTimeout() { } void FSM::onDeployingChute() { + buzzerService->CanTurnOn(); + buzzerService->TurnOn(); + igniter->enable(); if (millis() - ejection_start > EJECTION_TIMEOUT) { igniter->disable(); @@ -185,6 +217,10 @@ void FSM::onDeployingChute() { } void FSM::onRecovering() { + buzzerService->CanTurnOn(); + buzzerService->TurnOn(); + buzzerService->Lock(); + // TODO: celebrate } diff --git a/libraries/fsm.h b/libraries/fsm.h index 7c23b5d..8c27c7e 100644 --- a/libraries/fsm.h +++ b/libraries/fsm.h @@ -4,6 +4,7 @@ #include "altimeter.h" #include "gps_receiver.h" #include "igniter.h" +#include "BuzzerService.h" class Transition { public: @@ -26,7 +27,7 @@ class FSM { void process_event(EVENT event); void runCurrentState(); - FSM(Telemetry* telemetry, IMU* imu_sensor, Altimeter* altimeter, GPSReceiver* gps, Igniter* igniter, uint8_t* loop_frequency); + FSM(Telemetry* telemetry, IMU* imu_sensor, Altimeter* altimeter, GPSReceiver* gps, Igniter* igniter, uint8_t* loop_frequency, BuzzerService* buzzerService); private: STATE state = STATE::SETUP; @@ -37,6 +38,7 @@ class FSM { Altimeter* altimeter; GPSReceiver* gps; Igniter* igniter; + BuzzerService* buzzerService; uint8_t* loop_frequency; unsigned long launch_time;