EXTENSIBLE_UI Joystick support (#15303)
This commit is contained in:
parent
12e0581f24
commit
7f117bfc60
10 changed files with 112 additions and 68 deletions
|
@ -36,6 +36,10 @@
|
|||
|
||||
Joystick joystick;
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../lcd/extensible_ui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#if HAS_JOY_ADC_X
|
||||
temp_info_t Joystick::x; // = { 0 }
|
||||
#endif
|
||||
|
@ -65,35 +69,39 @@ Joystick joystick;
|
|||
}
|
||||
#endif
|
||||
|
||||
void Joystick::calculate(float norm_jog[XYZ]) {
|
||||
// Do nothing if enable pin (active-low) is not LOW
|
||||
#if HAS_JOY_ADC_EN
|
||||
if (READ(JOY_EN_PIN)) return;
|
||||
#endif
|
||||
#if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z
|
||||
|
||||
auto _normalize_joy = [](float &adc, const int16_t raw, const int16_t (&joy_limits)[4]) {
|
||||
if (WITHIN(raw, joy_limits[0], joy_limits[3])) {
|
||||
// within limits, check deadzone
|
||||
if (raw > joy_limits[2])
|
||||
adc = (raw - joy_limits[2]) / float(joy_limits[3] - joy_limits[2]);
|
||||
else if (raw < joy_limits[1])
|
||||
adc = (raw - joy_limits[1]) / float(joy_limits[1] - joy_limits[0]); // negative value
|
||||
}
|
||||
};
|
||||
void Joystick::calculate(float (&norm_jog)[XYZ]) {
|
||||
// Do nothing if enable pin (active-low) is not LOW
|
||||
#if HAS_JOY_ADC_EN
|
||||
if (READ(JOY_EN_PIN)) return;
|
||||
#endif
|
||||
|
||||
#if HAS_JOY_ADC_X
|
||||
static constexpr int16_t joy_x_limits[4] = JOY_X_LIMITS;
|
||||
_normalize_joy(norm_jog[X_AXIS], x.raw, joy_x_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Y
|
||||
static constexpr int16_t joy_y_limits[4] = JOY_Y_LIMITS;
|
||||
_normalize_joy(norm_jog[Y_AXIS], y.raw, joy_y_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Z
|
||||
static constexpr int16_t joy_z_limits[4] = JOY_Z_LIMITS;
|
||||
_normalize_joy(norm_jog[Z_AXIS], z.raw, joy_z_limits);
|
||||
#endif
|
||||
}
|
||||
auto _normalize_joy = [](float &adc, const int16_t raw, const int16_t (&joy_limits)[4]) {
|
||||
if (WITHIN(raw, joy_limits[0], joy_limits[3])) {
|
||||
// within limits, check deadzone
|
||||
if (raw > joy_limits[2])
|
||||
adc = (raw - joy_limits[2]) / float(joy_limits[3] - joy_limits[2]);
|
||||
else if (raw < joy_limits[1])
|
||||
adc = (raw - joy_limits[1]) / float(joy_limits[1] - joy_limits[0]); // negative value
|
||||
}
|
||||
};
|
||||
|
||||
#if HAS_JOY_ADC_X
|
||||
static constexpr int16_t joy_x_limits[4] = JOY_X_LIMITS;
|
||||
_normalize_joy(norm_jog[X_AXIS], x.raw, joy_x_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Y
|
||||
static constexpr int16_t joy_y_limits[4] = JOY_Y_LIMITS;
|
||||
_normalize_joy(norm_jog[Y_AXIS], y.raw, joy_y_limits);
|
||||
#endif
|
||||
#if HAS_JOY_ADC_Z
|
||||
static constexpr int16_t joy_z_limits[4] = JOY_Z_LIMITS;
|
||||
_normalize_joy(norm_jog[Z_AXIS], z.raw, joy_z_limits);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(POLL_JOG)
|
||||
|
||||
|
@ -122,11 +130,19 @@ void Joystick::calculate(float norm_jog[XYZ]) {
|
|||
float norm_jog[XYZ] = { 0 };
|
||||
|
||||
// Use ADC values and defined limits. The active zone is normalized: -1..0 (dead) 0..1
|
||||
joystick.calculate(norm_jog);
|
||||
#if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z
|
||||
joystick.calculate(norm_jog);
|
||||
#endif
|
||||
|
||||
// Other non-joystick poll-based jogging could be implemented here
|
||||
// with "jogging" encapsulated as a more general class.
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
norm_jog[X_AXIS] = ExtUI::norm_jog[X_AXIS];
|
||||
norm_jog[Y_AXIS] = ExtUI::norm_jog[Y_AXIS];
|
||||
norm_jog[Z_AXIS] = ExtUI::norm_jog[Z_AXIS];
|
||||
#endif
|
||||
|
||||
// Jogging value maps continuously (quadratic relationship) to feedrate
|
||||
float move_dist[XYZ] = { 0 }, hypot2 = 0;
|
||||
LOOP_XYZ(i) if (norm_jog[i]) {
|
||||
|
|
|
@ -46,7 +46,7 @@ class Joystick {
|
|||
#if ENABLED(JOYSTICK_DEBUG)
|
||||
static void report();
|
||||
#endif
|
||||
static void calculate(float norm_jog[XYZ]);
|
||||
static void calculate(float (&norm_jog)[XYZ]);
|
||||
static void inject_jog_moves();
|
||||
};
|
||||
|
||||
|
|
|
@ -156,9 +156,11 @@ namespace FTDI {
|
|||
if (!UIData::flags.bits.touch_debouncing) {
|
||||
if (tag == pressed_tag) {
|
||||
// The user is holding down a button.
|
||||
if (touch_timer.elapsed(1000 / TOUCH_REPEATS_PER_SECOND) && current_screen.onTouchHeld(tag)) {
|
||||
current_screen.onRefresh();
|
||||
if (UIData::flags.bits.touch_repeat_sound) sound.play(repeat_sound);
|
||||
if (touch_timer.elapsed(1000 / TOUCH_REPEATS_PER_SECOND)) {
|
||||
if (current_screen.onTouchHeld(tag)) {
|
||||
current_screen.onRefresh();
|
||||
if (UIData::flags.bits.touch_repeat_sound) sound.play(repeat_sound);
|
||||
}
|
||||
touch_timer.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,13 +36,7 @@ void BioConfirmHomeE::onRedraw(draw_mode_t) {
|
|||
bool BioConfirmHomeE::onTouchEnd(uint8_t tag) {
|
||||
switch (tag) {
|
||||
case 1:
|
||||
SpinnerDialogBox::enqueueAndWait_P(F(
|
||||
"G112\n" /* Home extruder */
|
||||
LULZBOT_AXIS_LEVELING_COMMANDS /* Level X axis */
|
||||
"G0 X115 Z50 F6000\n" /* Goto loading position */
|
||||
"M400\n" /* Wait for moves to finish */
|
||||
"M18 X Y" /* Unlock motors */
|
||||
));
|
||||
SpinnerDialogBox::enqueueAndWait_P(F(LULZBOT_HOME_E_COMMANDS));
|
||||
current_screen.forget();
|
||||
break;
|
||||
case 2:
|
||||
|
|
|
@ -36,10 +36,7 @@ void BioConfirmHomeXYZ::onRedraw(draw_mode_t) {
|
|||
bool BioConfirmHomeXYZ::onTouchEnd(uint8_t tag) {
|
||||
switch (tag) {
|
||||
case 1:
|
||||
SpinnerDialogBox::enqueueAndWait_P(F(
|
||||
"G28 X Y Z\n" /* Home all axis */
|
||||
"G0 X115 Z50 F6000" /* Move to park position */
|
||||
));
|
||||
SpinnerDialogBox::enqueueAndWait_P(F(LULZBOT_HOME_XYZ_COMMANDS));
|
||||
current_screen.forget();
|
||||
break;
|
||||
case 2:
|
||||
|
|
|
@ -141,6 +141,7 @@ void BioPrintingDialogBox::setStatusMessage(const char* message) {
|
|||
}
|
||||
|
||||
void BioPrintingDialogBox::onIdle() {
|
||||
reset_menu_timeout();
|
||||
if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
|
||||
onRefresh();
|
||||
refresh_timer.start();
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0]))
|
||||
|
||||
const uint8_t shadow_depth = 5;
|
||||
const float max_speed = 0.30;
|
||||
const float min_speed = 0.05;
|
||||
const uint8_t num_speeds = 10;
|
||||
|
||||
using namespace FTDI;
|
||||
using namespace Theme;
|
||||
|
@ -248,7 +251,7 @@ void StatusScreen::onRedraw(draw_mode_t what) {
|
|||
}
|
||||
|
||||
bool StatusScreen::onTouchStart(uint8_t) {
|
||||
increment = fine_motion ? 0.25 : 1;
|
||||
increment = min_speed;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -263,6 +266,11 @@ bool StatusScreen::onTouchEnd(uint8_t tag) {
|
|||
jog_xy = true;
|
||||
injectCommands_P(PSTR("M17"));
|
||||
}
|
||||
jog(0, 0, 0);
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
jog(0, 0, 0);
|
||||
break;
|
||||
case 9: GOTO_SCREEN(FilesScreen); break;
|
||||
case 10: GOTO_SCREEN(MainMenu); break;
|
||||
|
@ -280,25 +288,31 @@ bool StatusScreen::onTouchEnd(uint8_t tag) {
|
|||
|
||||
bool StatusScreen::onTouchHeld(uint8_t tag) {
|
||||
if (tag >= 1 && tag <= 4 && !jog_xy) return false;
|
||||
if (ExtUI::isMoving()) return false; // Don't allow moves to accumulate
|
||||
#define UI_INCREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_INCREMENT(AxisPosition_mm, axis);
|
||||
#define UI_DECREMENT_AXIS(axis) MoveAxisScreen::setManualFeedrate(axis, increment); UI_DECREMENT(AxisPosition_mm, axis);
|
||||
const float s = fine_motion ? min_speed : increment;
|
||||
switch (tag) {
|
||||
case 1: UI_DECREMENT_AXIS(X); break;
|
||||
case 2: UI_INCREMENT_AXIS(X); break;
|
||||
case 4: UI_DECREMENT_AXIS(Y); break; // NOTE: Y directions inverted because bed rather than needle moves
|
||||
case 3: UI_INCREMENT_AXIS(Y); break;
|
||||
case 5: UI_DECREMENT_AXIS(Z); break;
|
||||
case 6: UI_INCREMENT_AXIS(Z); break;
|
||||
case 7: UI_DECREMENT_AXIS(E0); break;
|
||||
case 8: UI_INCREMENT_AXIS(E0); break;
|
||||
default: return false;
|
||||
case 1: jog(-s, 0, 0); break;
|
||||
case 2: jog( s, 0, 0); break;
|
||||
case 4: jog( 0, -s, 0); break; // NOTE: Y directions inverted because bed rather than needle moves
|
||||
case 3: jog( 0, s, 0); break;
|
||||
case 5: jog( 0, 0, -s); break;
|
||||
case 6: jog( 0, 0, s); break;
|
||||
case 7:
|
||||
if (ExtUI::isMoving()) return false;
|
||||
MoveAxisScreen::setManualFeedrate(E0, 1);
|
||||
UI_INCREMENT(AxisPosition_mm, E0);
|
||||
current_screen.onRefresh();
|
||||
break;
|
||||
case 8:
|
||||
if (ExtUI::isMoving()) return false;
|
||||
MoveAxisScreen::setManualFeedrate(E0, 1);
|
||||
UI_DECREMENT(AxisPosition_mm, E0);
|
||||
current_screen.onRefresh();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#undef UI_DECREMENT_AXIS
|
||||
#undef UI_INCREMENT_AXIS
|
||||
if (increment < 10 && !fine_motion)
|
||||
increment += 0.5;
|
||||
current_screen.onRefresh();
|
||||
if (increment < max_speed)
|
||||
increment += (max_speed - min_speed) / num_speeds;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ void MainMenu::onRedraw(draw_mode_t what) {
|
|||
#else
|
||||
#define GRID_ROWS 5
|
||||
#define GRID_COLS 2
|
||||
.tag(2).button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT(AUTO_HOME))
|
||||
.tag(2).button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXTF(AUTO_HOME))
|
||||
#if ENABLED(NOZZLE_CLEAN_FEATURE)
|
||||
.enabled(1)
|
||||
#else
|
||||
|
|
|
@ -102,12 +102,16 @@
|
|||
#include "../../feature/host_actions.h"
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
uint8_t printer_killed : 1;
|
||||
uint8_t manual_motion : 1;
|
||||
} flags;
|
||||
|
||||
namespace ExtUI {
|
||||
static struct {
|
||||
uint8_t printer_killed : 1;
|
||||
uint8_t manual_motion : 1;
|
||||
} flags;
|
||||
|
||||
#if ENABLED(JOYSTICK)
|
||||
float norm_jog[XYZ];
|
||||
#endif
|
||||
|
||||
#ifdef __SAM3X8E__
|
||||
/**
|
||||
* Implement a special millis() to allow time measurement
|
||||
|
@ -193,6 +197,14 @@ namespace ExtUI {
|
|||
#endif
|
||||
}
|
||||
|
||||
void jog(float dx, float dy, float dz) {
|
||||
#if ENABLED(JOYSTICK)
|
||||
norm_jog[X] = dx;
|
||||
norm_jog[Y] = dy;
|
||||
norm_jog[Z] = dz;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isHeaterIdle(const extruder_t extruder) {
|
||||
return false
|
||||
#if HOTENDS && HEATER_IDLE_HANDLER
|
||||
|
@ -1037,9 +1049,10 @@ void MarlinUI::update() {
|
|||
}
|
||||
|
||||
void MarlinUI::kill_screen(PGM_P const msg) {
|
||||
using namespace ExtUI;
|
||||
if (!flags.printer_killed) {
|
||||
flags.printer_killed = true;
|
||||
ExtUI::onPrinterKilled(msg);
|
||||
onPrinterKilled(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
namespace ExtUI {
|
||||
|
||||
#if ENABLED(JOYSTICK)
|
||||
extern float norm_jog[];
|
||||
#endif
|
||||
|
||||
// The ExtUI implementation can store up to this many bytes
|
||||
// in the EEPROM when the methods onStoreSettings and
|
||||
// onLoadSettings are called.
|
||||
|
@ -79,6 +84,8 @@ namespace ExtUI {
|
|||
void enableHeater(const heater_t);
|
||||
void enableHeater(const extruder_t);
|
||||
|
||||
void jog(float dx, float dy, float dz);
|
||||
|
||||
/**
|
||||
* Getters and setters
|
||||
* Should be used by the EXTENSIBLE_UI to query or change Marlin's state.
|
||||
|
|
Reference in a new issue