Add user_input module and use it instead of raw buttons
Encapsulates buttons and commands coming from the communicationpull/37/head
parent
af8c866f1a
commit
9a8038ccb6
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#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<Event, 4> eventQueue;
|
||||
};
|
||||
|
||||
extern UserInput userInput;
|
||||
|
||||
} // namespace user_input
|
||||
} // namespace modules
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue