EXTENSIBLE_UI Joystick support (#15303)

This commit is contained in:
Marcio Teixeira 2019-09-18 18:35:03 -06:00 committed by Scott Lahteine
parent 12e0581f24
commit 7f117bfc60
10 changed files with 112 additions and 68 deletions

View file

@ -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]) {

View file

@ -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();
};

View file

@ -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();
}
}

View file

@ -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:

View file

@ -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:

View file

@ -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();

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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.