From 9a8038ccb66cd4292edca7b01bb1870af16be028 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 29 Jun 2021 08:56:53 +0200 Subject: [PATCH] Add user_input module and use it instead of raw buttons Encapsulates buttons and commands coming from the communication --- CMakeLists.txt | 1 + src/logic/feed_to_finda.cpp | 7 +-- src/logic/load_filament.cpp | 23 +++++----- src/logic/unload_filament.cpp | 24 +++++----- src/logic/unload_to_finda.cpp | 1 - src/main.cpp | 3 ++ src/modules/user_input.cpp | 38 ++++++++++++++++ src/modules/user_input.h | 44 +++++++++++++++++++ tests/unit/logic/cut_filament/CMakeLists.txt | 1 + .../unit/logic/eject_filament/CMakeLists.txt | 1 + tests/unit/logic/feed_to_finda/CMakeLists.txt | 1 + tests/unit/logic/load_filament/CMakeLists.txt | 1 + tests/unit/logic/tool_change/CMakeLists.txt | 1 + .../unit/logic/unload_filament/CMakeLists.txt | 1 + 14 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 src/modules/user_input.cpp create mode 100644 src/modules/user_input.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 011322b..d98231d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,6 +204,7 @@ target_sources( src/modules/permanent_storage.cpp src/modules/selector.cpp src/modules/timebase.cpp + src/modules/user_input.cpp src/logic/command_base.cpp src/logic/cut_filament.cpp src/logic/eject_filament.cpp diff --git a/src/logic/feed_to_finda.cpp b/src/logic/feed_to_finda.cpp index 1192791..d7c400f 100644 --- a/src/logic/feed_to_finda.cpp +++ b/src/logic/feed_to_finda.cpp @@ -1,5 +1,4 @@ #include "feed_to_finda.h" -#include "../modules/buttons.h" #include "../modules/finda.h" #include "../modules/globals.h" #include "../modules/idler.h" @@ -7,6 +6,7 @@ #include "../modules/leds.h" #include "../modules/motion.h" #include "../modules/permanent_storage.h" +#include "../modules/user_input.h" namespace logic { @@ -14,9 +14,9 @@ namespace mm = modules::motion; namespace mf = modules::finda; namespace mi = modules::idler; namespace ml = modules::leds; -namespace mb = modules::buttons; namespace mg = modules::globals; namespace ms = modules::selector; +namespace mu = modules::user_input; void FeedToFinda::Reset(bool feedPhaseLimited) { state = EngagingIdler; @@ -33,10 +33,11 @@ bool FeedToFinda::Step() { state = PushingFilament; ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::blink0); mm::motion.PlanMove(feedPhaseLimited ? 1500 : 32767, 0, 0, 4000, 0, 0); //@@TODO constants + mu::userInput.Clear(); // remove all buffered events if any just before we wait for some input } return false; case PushingFilament: { - if (mf::finda.Pressed() || (feedPhaseLimited && mb::buttons.AnyButtonPressed())) { // @@TODO probably also a command from the printer + if (mf::finda.Pressed() || (feedPhaseLimited && mu::userInput.AnyEvent())) { // @@TODO probably also a command from the printer mm::motion.AbortPlannedMoves(); // stop pushing filament // FINDA triggered - that means it works and detected the filament tip state = UnloadBackToPTFE; diff --git a/src/logic/load_filament.cpp b/src/logic/load_filament.cpp index 3a29900..c5b3331 100644 --- a/src/logic/load_filament.cpp +++ b/src/logic/load_filament.cpp @@ -1,5 +1,4 @@ #include "load_filament.h" -#include "../modules/buttons.h" #include "../modules/finda.h" #include "../modules/globals.h" #include "../modules/idler.h" @@ -7,6 +6,7 @@ #include "../modules/motion.h" #include "../modules/permanent_storage.h" #include "../modules/selector.h" +#include "../modules/user_input.h" namespace logic { @@ -18,6 +18,7 @@ namespace ms = modules::selector; namespace mf = modules::finda; namespace ml = modules::leds; namespace mg = modules::globals; +namespace mu = modules::user_input; void LoadFilament::Reset(uint8_t param) { state = ProgressCode::EngagingIdler; @@ -76,26 +77,28 @@ bool LoadFilament::Step() { case ProgressCode::ERR1DisengagingIdler: // couldn't unload to FINDA if (!mi::idler.Engaged()) { state = ProgressCode::ERR1WaitingForUser; + mu::userInput.Clear(); // remove all buffered events if any just before we wait for some input } return false; case ProgressCode::ERR1WaitingForUser: { // waiting for user buttons and/or a command from the printer - bool help = modules::buttons::buttons.ButtonPressed(modules::buttons::Left) /*|| command_help()*/; - bool tryAgain = modules::buttons::buttons.ButtonPressed(modules::buttons::Middle) /*|| command_tryAgain()*/; - bool userResolved = modules::buttons::buttons.ButtonPressed(modules::buttons::Right) /*|| command_userResolved()*/; - if (help) { - // try to manually load just a tiny bit - help the filament with the pulley + mu::Event ev = mu::userInput.ConsumeEvent(); + switch (ev) { + case mu::Event::Left: // try to manually load just a tiny bit - help the filament with the pulley state = ProgressCode::ERR1EngagingIdler; mi::idler.Engage(mg::globals.ActiveSlot()); - } else if (tryAgain) { - // try again the whole sequence + break; + case mu::Event::Middle: // try again the whole sequence Reset(mg::globals.ActiveSlot()); - } else if (userResolved) { - // problem resolved - the user pushed the fillament by hand? + break; + case mu::Event::Right: // problem resolved - the user pushed the fillament by hand? modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::red, modules::leds::off); modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::green, modules::leds::on); // mm::motion.PlanMove(mm::Pulley, 450, 5000); // @@TODO constants state = ProgressCode::AvoidingGrind; + break; + default: // no event, continue waiting for user input + break; } return false; } diff --git a/src/logic/unload_filament.cpp b/src/logic/unload_filament.cpp index b3e4cab..7be6110 100644 --- a/src/logic/unload_filament.cpp +++ b/src/logic/unload_filament.cpp @@ -1,22 +1,22 @@ #include "unload_filament.h" -#include "../modules/buttons.h" #include "../modules/finda.h" #include "../modules/globals.h" #include "../modules/idler.h" #include "../modules/leds.h" #include "../modules/motion.h" #include "../modules/permanent_storage.h" +#include "../modules/user_input.h" namespace logic { UnloadFilament unloadFilament; -namespace mb = modules::buttons; namespace mm = modules::motion; namespace mf = modules::finda; namespace mi = modules::idler; namespace ml = modules::leds; namespace mg = modules::globals; +namespace mu = modules::user_input; void UnloadFilament::Reset(uint8_t /*param*/) { // unloads filament from extruder - filament is above Bondtech gears @@ -71,26 +71,28 @@ bool UnloadFilament::Step() { case ProgressCode::ERR1DisengagingIdler: // couldn't unload to FINDA if (!mi::idler.Engaged()) { state = ProgressCode::ERR1WaitingForUser; + mu::userInput.Clear(); // remove all buffered events if any just before we wait for some input } return false; case ProgressCode::ERR1WaitingForUser: { // waiting for user buttons and/or a command from the printer - bool help = mb::buttons.ButtonPressed(mb::Left) /*|| command_help()*/; - bool tryAgain = mb::buttons.ButtonPressed(mb::Middle) /*|| command_tryAgain()*/; - bool userResolved = mb::buttons.ButtonPressed(mb::Right) /*|| command_userResolved()*/; - if (help) { - // try to manually unload just a tiny bit - help the filament with the pulley + mu::Event ev = mu::userInput.ConsumeEvent(); + switch (ev) { + case mu::Event::Left: // try to manually unload just a tiny bit - help the filament with the pulley state = ProgressCode::ERR1EngagingIdler; mi::idler.Engage(mg::globals.ActiveSlot()); - } else if (tryAgain) { - // try again the whole sequence + break; + case mu::Event::Middle: // try again the whole sequence Reset(0); //@@TODO validate the reset parameter - } else if (userResolved) { - // problem resolved - the user pulled the fillament by hand + break; + case mu::Event::Right: // problem resolved - the user pulled the fillament by hand ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::off); ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::on); // mm::motion.PlanMove(mm::Pulley, 450, 5000); // @@TODO constants state = ProgressCode::AvoidingGrind; + break; + default: + break; } return false; } diff --git a/src/logic/unload_to_finda.cpp b/src/logic/unload_to_finda.cpp index 2e78435..1dffc90 100644 --- a/src/logic/unload_to_finda.cpp +++ b/src/logic/unload_to_finda.cpp @@ -1,5 +1,4 @@ #include "unload_to_finda.h" -#include "../modules/buttons.h" #include "../modules/finda.h" #include "../modules/globals.h" #include "../modules/idler.h" diff --git a/src/main.cpp b/src/main.cpp index 35bddc2..369fa78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include "modules/leds.h" #include "modules/protocol.h" #include "modules/selector.h" +#include "modules/user_input.h" #include "logic/command_base.h" #include "logic/cut_filament.h" @@ -34,6 +35,7 @@ namespace mi = modules::idler; namespace ml = modules::leds; namespace ms = modules::selector; namespace mg = modules::globals; +namespace mu = modules::user_input; namespace hu = hal::usart; @@ -193,6 +195,7 @@ void ProcessRequestMsg(const mp::RequestMsg &rq) { switch (rq.code) { case mp::RequestMsgCodes::Button: // behave just like if the user pressed a button + mu::userInput.ProcessMessage(rq.value); break; case mp::RequestMsgCodes::Finda: // immediately report FINDA status diff --git a/src/modules/user_input.cpp b/src/modules/user_input.cpp new file mode 100644 index 0000000..5ee65e6 --- /dev/null +++ b/src/modules/user_input.cpp @@ -0,0 +1,38 @@ +#include "user_input.h" +#include "buttons.h" + +namespace modules { +namespace user_input { + +UserInput userInput; + +void UserInput::Step() { + if (buttons::buttons.ButtonPressed(0)) + eventQueue.push_back(Event::Left); + if (buttons::buttons.ButtonPressed(1)) + eventQueue.push_back(Event::Middle); + if (buttons::buttons.ButtonPressed(2)) + eventQueue.push_back(Event::Right); +} + +void UserInput::ProcessMessage(uint8_t ev) { + eventQueue.push_back((Event)ev); +} + +Event UserInput::ConsumeEvent() { + if (eventQueue.IsEmpty()) + return Event::NoEvent; + Event rv; + eventQueue.ConsumeFirst(rv); + return rv; +} + +void UserInput::Clear() { + while (eventQueue.IsEmpty()) { + Event x; + eventQueue.ConsumeFirst(x); + } +} + +} // namespace user_input +} // namespace modules diff --git a/src/modules/user_input.h b/src/modules/user_input.h new file mode 100644 index 0000000..99c29b0 --- /dev/null +++ b/src/modules/user_input.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include "../hal/circle_buffer.hpp" + +namespace modules { + +/// User input module collects input from buttons and from communication for the logic layer +namespace user_input { + +enum class Event : int8_t { + NoEvent = -1, + Left = 0, + Middle = 1, + Right = 2 +}; + +class UserInput { + +public: + UserInput() = default; + + /// collects the buttons' state and enqueues the corresponding event + void Step(); + + /// enqueues a user event coming from a communication + void ProcessMessage(uint8_t ev); + + /// dequeues the most recent event from the queue for processing + Event ConsumeEvent(); + + /// @returns true if there is at least one event in the event queue + bool AnyEvent() const { return !eventQueue.IsEmpty(); } + + /// Remove all buffered events from the event queue + void Clear(); + +private: + CircleBuffer eventQueue; +}; + +extern UserInput userInput; + +} // namespace user_input +} // namespace modules diff --git a/tests/unit/logic/cut_filament/CMakeLists.txt b/tests/unit/logic/cut_filament/CMakeLists.txt index 039a797..1b80ffb 100644 --- a/tests/unit/logic/cut_filament/CMakeLists.txt +++ b/tests/unit/logic/cut_filament/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp diff --git a/tests/unit/logic/eject_filament/CMakeLists.txt b/tests/unit/logic/eject_filament/CMakeLists.txt index bdd2ef6..860135c 100644 --- a/tests/unit/logic/eject_filament/CMakeLists.txt +++ b/tests/unit/logic/eject_filament/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp diff --git a/tests/unit/logic/feed_to_finda/CMakeLists.txt b/tests/unit/logic/feed_to_finda/CMakeLists.txt index 3567d6e..aaae9d1 100644 --- a/tests/unit/logic/feed_to_finda/CMakeLists.txt +++ b/tests/unit/logic/feed_to_finda/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp diff --git a/tests/unit/logic/load_filament/CMakeLists.txt b/tests/unit/logic/load_filament/CMakeLists.txt index a402c2f..1231a9a 100644 --- a/tests/unit/logic/load_filament/CMakeLists.txt +++ b/tests/unit/logic/load_filament/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp diff --git a/tests/unit/logic/tool_change/CMakeLists.txt b/tests/unit/logic/tool_change/CMakeLists.txt index d207344..8dbca03 100644 --- a/tests/unit/logic/tool_change/CMakeLists.txt +++ b/tests/unit/logic/tool_change/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp diff --git a/tests/unit/logic/unload_filament/CMakeLists.txt b/tests/unit/logic/unload_filament/CMakeLists.txt index 7c86c37..0487cc2 100644 --- a/tests/unit/logic/unload_filament/CMakeLists.txt +++ b/tests/unit/logic/unload_filament/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable( ../../../../src/modules/leds.cpp ../../../../src/modules/permanent_storage.cpp ../../../../src/modules/selector.cpp + ../../../../src/modules/user_input.cpp ../../modules/stubs/stub_adc.cpp ../../modules/stubs/stub_eeprom.cpp ../../modules/stubs/stub_shr16.cpp