manual positioning / Jogwheel

edited March 2016 in Feature Requests
Hi all !
as i use repetier fw for milling , i found  that positioning for offsets via encoder is not very efficient.
As REPETIER added the analog keypad support i thought about positioning via jostick.
it needs three analog inputs and works via potentiometer-based joysticks.The encoder and other functions keep as before.

i use 1 Analog channel per axis and define several "buttons" depending on joystick position and UIActions define stepwidths.
feedrate for these steps is defined as"JOGRATE" and of coarse very slow.
I tested the code on DUE and it works fine. THE min/max numbers for the buttons depend on the hardware setup,
i used 4.7 KOhm pullups and jostick as variable resistor 0...10 Kohm similar to thermistor input.
thats what i modified in code (FW 92.8 ):

//############Changes in UICONFIG.H


void uiInitKeys() {
#if UI_HAS_KEYS!=0
UI_KEYS_INIT_CLICKENCODER_LOW(43,45); // click encoder on pins 43 and 45. Phase is connected with gnd for signals.
UI_KEYS_INIT_BUTTON_LOW(47); // push button, connects gnd to pin
#endif
}

void uiCheckKeys(uint16_t &action) {

#if UI_HAS_KEYS!=0

UI_KEYS_CLICKENCODER_LOW_REV(43,45); // click encoder on pins 43 and 45. Phase is connected with gnd for signals.
UI_KEYS_BUTTON_LOW(47,UI_ACTION_OK); // push button, connects gnd to pin
#endif

// Here starts Joystick assignment
// button assignment x-axis
struct {
uint16_t min;
uint16_t max;
uint16_t action;
} keys_x[] = {
{ 0, 800, UI_ACTION_X_DOWN10 }, // down 10 mm steps
{ 810, 1200, UI_ACTION_X_DOWN1 }, // down 1 mm steps
{ 1210, 1800, UI_ACTION_X_DOWN01 }, // down 0.1 mm steps
{ 1810, 2000, UI_ACTION_X_DOWN001 }, // down 0.01 mm steps

{ 2200, 2350, UI_ACTION_X_UP001 }, // up 0.01mm steps
{ 2370, 2500, UI_ACTION_X_UP01 }, // up 0.1 mm steps
{ 2510, 2650, UI_ACTION_X_UP1 }, // up 1mm steps
{ 2660, 3000, UI_ACTION_X_UP10 }, // up 10 mm steps
};
const uint8_t numOfKeys_x = sizeof(keys_x) / sizeof(keys_x[0]);

extern volatile uint16_t osAnalogInputValues[ANALOG_INPUTS];
uint16_t adc_x = osAnalogInputValues[KEYPAD_ANALOG_INDEX] >> (ANALOG_REDUCE_BITS);
if (adc_x < 4000) {
for (int8_t ix = 0; ix < numOfKeys_x; ++ix) {
if ((adc_x > keys_x[ix].min) && (adc_x< keys_x[ix].max)) {
action = keys_x[ix].action;
return;
}
}
}

//button assignment y-axis


struct {
uint16_t min;
uint16_t max;
uint16_t action;
}

keys_y[] = {

{ 0, 800, UI_ACTION_Y_UP10 }, // Up 10 mm Steps
{ 810, 1200, UI_ACTION_Y_UP1 }, // Up 1mm Steps
{ 1210,1800, UI_ACTION_Y_UP01 }, // Up 0.1 mm Steps
{ 1810,2000, UI_ACTION_Y_UP001 }, // Up 0.01 mm steps

{ 2200, 2350, UI_ACTION_Y_DOWN001 }, // Down 0.01mm Steps
{ 2370, 2500, UI_ACTION_Y_DOWN01 }, // Down 0.1mm Steps
{ 2510, 2650, UI_ACTION_Y_DOWN1 }, // Down 1mm Steps
{ 2660, 3000, UI_ACTION_Y_DOWN10 }, // Down 10 mm Steps
};


const uint8_t numOfKeys2 = sizeof(keys_y) / sizeof(keys_y[0]);

uint16_t adc_y = osAnalogInputValues[KEYPAD2_ANALOG_INDEX] >> (ANALOG_REDUCE_BITS);
if ( adc_y < 4000) {
for (int8_t iy = 0; iy < numOfKeys2; ++iy) {
if ((adc_y > keys_y[iy].min) && (adc_y < keys_y[iy].max)) {
action = keys_y[iy].action;
return;
}
}
}

// Button assignment Z-Axis
struct {
uint16_t min;
uint16_t max;
uint16_t action;
}

keys_z[] = {


{ 810, 1200, UI_ACTION_Z_UP1 }, // Up 1mm steps
{ 1210,1800, UI_ACTION_Z_UP01 }, // Up 0.1 mm steps
{ 1810,2000, UI_ACTION_Z_UP001 }, // Up 0.01 mm steps

{ 2200, 2350, UI_ACTION_Z_DOWN001 }, //Down 0.01 mm steps
{ 2370, 2500, UI_ACTION_Z_DOWN01 }, //Down 0.1 mm steps
{ 2510, 2650, UI_ACTION_Z_DOWN1 }, // Down 1mm steps

};


const uint8_t numOfKeysz = sizeof(keys_z) / sizeof(keys_z[0]);

uint16_t adc_z = osAnalogInputValues[KEYPAD3_ANALOG_INDEX] >> (ANALOG_REDUCE_BITS);
if ( adc_z < 4000) {
for (int8_t iz = 0; iz < numOfKeysz; ++iz) {
if ((adc_z > keys_z[iz].min) && (adc_z < keys_z[iz].max)) {
action = keys_z[iz].action;
return;
}
}
}


}


//############## Changes in UI.cpp

case UI_ACTION_X_UP:
case UI_ACTION_X_DOWN:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP) ? 1.0 : -1.0) * (Printer::axisStepsPerMM[X_AXIS]), 0, 0, 0, Printer::homingFeedrate[X_AXIS], false,false);
break;

case UI_ACTION_X_UP001:
case UI_ACTION_X_DOWN001:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP001) ? 1.0 : -1.0) * (Printer::axisStepsPerMM[X_AXIS]/100), 0, 0, 0, JOGRATE, false,false);
break;

case UI_ACTION_X_UP01:
case UI_ACTION_X_DOWN01:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP01) ? 1.0 : -1.0) * (Printer::axisStepsPerMM[X_AXIS]/10), 0, 0, 0, JOGRATE, false,false);
break;


case UI_ACTION_X_UP1:
case UI_ACTION_X_DOWN1:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP1) ? 1.0 : -1.0) * Printer::axisStepsPerMM[X_AXIS], 0, 0, 0, JOGRATE, false,false);
break;

case UI_ACTION_X_UP10:
case UI_ACTION_X_DOWN10:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(((action == UI_ACTION_X_UP10) ? 1.0 : -1.0) * (Printer::axisStepsPerMM[X_AXIS]*10), 0, 0, 0, JOGRATE, false,false);
break;


case UI_ACTION_Y_UP:
case UI_ACTION_Y_DOWN:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS]/100, 0, 0,Printer::homingFeedrate[Y_AXIS], false,false);
break;

case UI_ACTION_Y_UP001:
case UI_ACTION_Y_DOWN001:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP001) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS]/100, 0, 0, JOGRATE, false,false);
break;
case UI_ACTION_Y_UP01:
case UI_ACTION_Y_DOWN01:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP01) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS]/10, 0, 0, JOGRATE, false,false);
break;
case UI_ACTION_Y_UP1:
case UI_ACTION_Y_DOWN1:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP1) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS], 0, 0, JOGRATE, false,false);
break;
case UI_ACTION_Y_UP10:
case UI_ACTION_Y_DOWN10:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, ((action == UI_ACTION_Y_UP10) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Y_AXIS]*10, 0, 0, JOGRATE, false,false);
break;






case UI_ACTION_Z_UP:
case UI_ACTION_Z_DOWN:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((action == UI_ACTION_Z_UP) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Z_AXIS], 0, Printer::homingFeedrate[Z_AXIS], false,false);
break;

case UI_ACTION_Z_UP001:
case UI_ACTION_Z_DOWN001:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((action == UI_ACTION_Z_UP001) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Z_AXIS]/100, 0, JOGRATE, false,false);
break;

case UI_ACTION_Z_UP01:
case UI_ACTION_Z_DOWN01:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((action == UI_ACTION_Z_UP01) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Z_AXIS]/10, 0, JOGRATE, false,false);
break;

case UI_ACTION_Z_UP1:
case UI_ACTION_Z_DOWN1:
if(!allowMoves) return action;
PrintLine::moveRelativeDistanceInStepsReal(0, 0, ((action == UI_ACTION_Z_UP1) ? 1.0 : -1.0) * Printer::axisStepsPerMM[Z_AXIS], 0, JOGRATE, false,false);
break;



//########### Changes in ui. H ( additional uiactions)
#define UI_ACTION_X_UP1 114
#define UI_ACTION_X_DOWN1 115
#define UI_ACTION_X_UP01 116
#define UI_ACTION_X_DOWN01 117
#define UI_ACTION_X_UP001 118
#define UI_ACTION_X_DOWN001 119
#define UI_ACTION_X_UP10 120
#define UI_ACTION_X_DOWN10 121

#define UI_ACTION_Y_UP1 122
#define UI_ACTION_Y_DOWN1 123
#define UI_ACTION_Y_UP01 124
#define UI_ACTION_Y_DOWN01 125
#define UI_ACTION_Y_UP001 126
#define UI_ACTION_Y_DOWN001 127
#define UI_ACTION_Y_UP10 128
#define UI_ACTION_Y_DOWN10 129


#define UI_ACTION_Z_UP1 130
#define UI_ACTION_Z_DOWN1 131
#define UI_ACTION_Z_UP01 132
#define UI_ACTION_Z_DOWN01 133
#define UI_ACTION_Z_UP001 134
#define UI_ACTION_Z_DOWN001 135


//############Changes in Repetier.h
// add:


#if defined(ADC_KEYPAD2_PIN) && (ADC_KEYPAD2_PIN > -1)
#define KEYPAD2_ANALOG_INPUTS 1
#define KEYPAD2_ANALOG_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS+THERMO_ANALOG_INPUTS+KEYPAD_ANALOG_INPUTS
#define KEYPAD2_ANALOG_CHANNEL THERMO_COMMA ADC_KEYPAD2_PIN
#else
#define KEYPAD2_ANALOG_INPUTS 0
#define KEYPAD2_ANALOG_CHANNEL
#endif


#if defined(ADC_KEYPAD3_PIN) && (ADC_KEYPAD3_PIN > -1)
#define KEYPAD3_ANALOG_INPUTS 1
#define KEYPAD3_ANALOG_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS+THERMO_ANALOG_INPUTS+KEYPAD_ANALOG_INPUTS+KEYPAD2_ANALOG_INPUTS
#define KEYPAD3_ANALOG_CHANNEL THERMO_COMMA ADC_KEYPAD3_PIN
#else
#define KEYPAD3_ANALOG_INPUTS 0
#define KEYPAD3_ANALOG_CHANNEL
#endif

// change:
/** \brief number of analog input signals. Normally 1 for each temperature sensor */
#define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS+THERMO_ANALOG_INPUTS+KEYPAD_ANALOG_INPUTS+KEYPAD2_ANALOG_INPUTS+KEYPAD3_ANALOG_INPUTS)
#if ANALOG_INPUTS > 0
/** Channels are the MUX-part of ADMUX register */
#define ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL EXT2_ANALOG_CHANNEL EXT3_ANALOG_CHANNEL EXT4_ANALOG_CHANNEL EXT5_ANALOG_CHANNEL BED_ANALOG_CHANNEL THERMO_ANALOG_CHANNEL KEYPAD_ANALOG_CHANNEL KEYPAD2_ANALOG_CHANNEL KEYPAD3_ANALOG_CHANNEL}
#endif


//#######Changes in configuration.h ( add keypad2 and3)

/* You can have one keypad connected via single analog pin as seen on
some printers with Melzi V2.0 board, 20x4 LCD and 5 buttons keypad. This must be
the analog pin number! */
#define ADC_KEYPAD_PIN ORIG_ADC_KEYPAD_PIN
#define ADC_KEYPAD2_PIN ORIG_ADC_KEYPAD2_PIN
#define ADC_KEYPAD3_PIN ORIG_ADC_KEYPAD3_PIN
#define JOGRATE 3 // fixed feedrate for slow moves during joystick moves
// define pins directly or via pins.h respectively userpins.h
// for a better overview i use reference names and define the pin numbers in userpins.h


Comments

  • edited February 2017
    Hi RAyWB... i have been wanting to do this for a while now. Im only a beginner with code so can you provide more detail and/or pics/schematics to help me understand where to wire the joystick and the keypad? Im using a ramps 1.4 board with a mega 2560... and ive got two arduino joysticks and a 4x4 keypad but need a little help to understand your code. Thanks for your help.
  • hi, so what hardware do you use?
  • edited February 2017
    Hi RAyWB... Im using a ramps 1.4 board with a mega 2560... and ive got two arduino joysticks and a 4x4 keypad... all of the stuff ive got are chinese knock offs.
    Keypad: 4 x 4 AVR 16 Key Matrix Array membrane
    Joystick: biaxial XY Joystick Module KY-023
    The machine i built is a 3 axis cartesian style printer made with 3 screw type linear slides. Im not using any bed heater or extruder heater since the machine is for lazer welding.... so those analogue inputs are free.
  • edited February 2017
    ok, so what do you want to do exactly?

    the mod i wrote is thought for manual movement to find workpiece zero.

    welding sounds interesting, what type of laser?

  • I think I want to do exactly what you are doing. I'd like to be able to use the printer manually or automatically. in manual mode, I'd use the joystick to manoeuvre the print platform to specific locations or laser weld a part manually. I read that you are using yours for milling... It's very similar to what I am using it for except its for welding small parts...
  • ok.unfortunately i´m using due board , but i´ll check it on a ramps/mega as soon as i find the time
  • Ok thanks RAyWB... In the mean time I'm going to take your code and play around with it a bit to see if I can get some of this to work... from what I've read the Due and 2560 are similar in coding just different pin assignments and such... but I'm no expert...
  • some of the files are different, but these are not affected by the mod
  • Hi, very good job. Again after year  i try to give my 3axis analog joystick type model:OM400A-M4(button switch on top, 10k pots) into code for linear moving of my milling machine. I found good function for this in code, but after using fast speed is controller freezing, without possibility to reset by RESET button. Is any way how to emulate arduino code, because i can't find cause of freezing? here is small write of my code:

    in UI.CPP is gived function : set_joystick_run();

    // Gets called from inside an interrupt with interrupts allowed!
    void UIDisplay::fastAction()
    {
    #if UI_HAS_KEYS == 1
        // Check keys
        InterruptProtectedBlock noInts;
        if((flags & (UI_FLAG_KEY_TEST_RUNNING + UI_FLAG_SLOW_KEY_ACTION)) == 0)
        {
            flags |= UI_FLAG_KEY_TEST_RUNNING;
            uint16_t nextAction = 0;
        //if (Printer::isAutomount())//!Printer::isXYZMove())

           set_joystick_run();     //ACZ move by joystick in 3 axis in the same time
          uiCheckKeys(nextAction);

    //        ui_check_Ukeys(nextAction);
            if(lastButtonAction != nextAction)
            {
                lastButtonStart = HAL::timeInMilliseconds();
                lastButtonAction = nextAction;
                flags |= UI_FLAG_FAST_KEY_ACTION;
            }
            flags &= ~UI_FLAG_KEY_TEST_RUNNING;
        }
    }

    here is set_joystick with AD:

    #include "Repetier.h"
    #include "Printer.h"
    #include "HAL.h"
    //#include "Joystick.h"
    //#include <pins.h>
    //#include "Configuration.h"
    //#include "Drivers.h"
    //#include "motion.h"


    #if defined EXT_AJOYSTICK
    #define JOY_DIR_X 1
    #define JOY_DIR_Y 1
    #define JOY_DIR_Z 1
    #define JOY_CENTER_X 2046//512
    #define JOY_CENTER_Y 2046//512
    #define JOY_CENTER_Z 2046//512
    #define JOY_DEADBAND_X 150
    #define JOY_DEADBAND_Y 150
    #define JOY_DEADBAND_Z 150
    #define JOY_MAX_X 2000
    #define JOY_MAX_Y 2000
    #define JOY_MAX_Z 2000
    #define JOY_SLOW_FEEDRATE 3//0.01
    #define JOY_FAST_FEEDRATE 30//0.01
    #define JOY_SLOW_MOTION 0.01
    #define JOY_FAST_MOTION 0.05

    #if defined EXT_AJOYSTICK
    int loop_delay = 0;
    //extern volatile uint osAnalogInputValues[ANALOG_INPUTS];

    int get_joystick_position_x()
    {
    int Joy_Position_X = 0;

    Joy_Position_X = (osAnalogInputValues[KEYPAD_ANALOG_INDEX] - JOY_CENTER_X)*JOY_DIR_X;
    if (Joy_Position_X < JOY_DEADBAND_X && Joy_Position_X > -JOY_DEADBAND_X)Joy_Position_X = 0;
    else {
    if (Joy_Position_X >= JOY_DEADBAND_X) Joy_Position_X -= JOY_DEADBAND_X;
    if (Joy_Position_X <= -JOY_DEADBAND_X) Joy_Position_X += JOY_DEADBAND_X;
    }
    return Joy_Position_X;
    }

    int get_joystick_position_y()
    {
    int Joy_Position_Y = 0;
    Joy_Position_Y = (osAnalogInputValues[KEYPAD2_ANALOG_INDEX] - JOY_CENTER_Y)*JOY_DIR_Y;
    if (Joy_Position_Y < JOY_DEADBAND_Y && Joy_Position_Y > -JOY_DEADBAND_Y)Joy_Position_Y = 0;
    else {
    if (Joy_Position_Y >= JOY_DEADBAND_Y) Joy_Position_Y -= JOY_DEADBAND_Y;
    if (Joy_Position_Y <= -JOY_DEADBAND_Y) Joy_Position_Y += JOY_DEADBAND_Y;
    }
    return Joy_Position_Y;
    }

    int get_joystick_position_z()
    {
    int Joy_Position_Z = 0;

    Joy_Position_Z = (osAnalogInputValues[KEYPAD3_ANALOG_INDEX] - JOY_CENTER_Z)*JOY_DIR_Z;
    if (Joy_Position_Z < JOY_DEADBAND_Z && Joy_Position_Z > -JOY_DEADBAND_Z)Joy_Position_Z = 0;
    else {
    if (Joy_Position_Z >= JOY_DEADBAND_Z) Joy_Position_Z -= JOY_DEADBAND_Z;
    if (Joy_Position_Z <= -JOY_DEADBAND_Z) Joy_Position_Z += JOY_DEADBAND_Z;
    }
    return Joy_Position_Z;
    }

    int get_joystick_btn()
    {
    int Joy_BtnState = 0;
    Joy_BtnState = digitalRead(JOY_BTN_PIN);
    return Joy_BtnState;
    }


    void set_joystick_run()
    {
    int ad_x, ad_y, ad_z;
    loop_delay += 1;
    if (loop_delay >= 10)
    {

    ad_x = get_joystick_position_x();
    ad_y = get_joystick_position_y();
    ad_z = get_joystick_position_z();

    if (get_joystick_btn() == 1 && ad_x != 0) //slow motion
    {
    PrintLine::moveRelativeDistanceInSteps((int32_t)(ad_x*JOY_SLOW_MOTION), 0, 0, 0, Printer::maxFeedrate[X_AXIS], false, true, true);
    }
    else if (get_joystick_btn() == 0 && ad_x != 0) //fast motion
    {
    PrintLine::moveRelativeDistanceInSteps((int32_t)(ad_x*JOY_FAST_MOTION), 0, 0, 0, Printer::maxFeedrate[X_AXIS], false, true, true);
    }
    loop_delay = 0;
    }
    }


    ...... for moving machine is used function "moveRelativeDistanceInSteps" and now only in one axis (X).
    first boolean value is set to "FALSE". This boolean value is giving possibility to check finished previous move if its set to TRUE.
    But if i try to use TRUE, controller is freezing after start. If i use FALSE, it's working in slow motion perfectly, but when i use button on top joystick (used for fast speed), after little bit time it freeze again. No chance to reset by button, is needed to disconnect power.
    So my problem is emulating, what's happened inside. Thank You for solution.
  • that´s stuff i wrote for Firmware 0.92.8   don´t know if it´s working for actual Firmwares as i didn´t continue my work on that joystick stuff.
    I´m very busy at the moment so sorry for having no time to test your code

  • thank you for response, but i don't use your code. This is new one. Only question on how to emulate to find problem in my code. Or maybe better to start new discusion? Thank You.
  • ok solved, procedure  set_joystick_run(); gived into  "void Commands::commandLoop() {....} now it's absolutely clean and fine moving at fast and slow motion. sorry for disturbing.
  • maybe you want to share your code?
  • used board RAMPS 1.4, used connector AUX2 for joystick connection. Used FW ... 0.92.8 (i hope not important).
    it's not perfect, but usable. Let me know if you find any improvement..

    -----------------------------------------------------
    add into "pins.h" section "RAMPS_V_1_3"
    -----------------------------------------------------
    #define ORIG_ADC_KEYPAD_PIN 5
    #define ORIG_ADC_KEYPAD2_PIN 9
    #define ORIG_ADC_KEYPAD3_PIN 10
    #define JOY_BTN_PIN 40

    -----------------------------------------------------
    add new code file "joystick.h"
    -----------------------------------------------------
    // Joystick.h

    #ifndef JOYSTICK_H
    #define JOYSTICK_H

    #if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
    #include "WProgram.h"


    int get_joystick_position_x();
    int get_joystick_position_y();
    int get_joystick_position_z();
    int get_joystick_btn();
    void set_joystick_run();
    void joy_print();                //only for joystick check
    #endif // JOYSTICK_H

    -----------------------------------------------------------
    add new code file "joystick.cpp"
    -----------------------------------------------------------

    #include "Repetier.h"
    #include "Printer.h"
    #include "HAL.h"
    #include "uimenu.h"


    #if defined EXT_AJOYSTICK
    #define JOY_DIR_X 1
    #define JOY_DIR_Y 1
    #define JOY_DIR_Z -1      //reversed Z rotation of joystick
    #define JOY_CENTER_X 2046//512
    #define JOY_CENTER_Y 2046//512
    #define JOY_CENTER_Z 2046//512
    #define JOY_DEADBAND_X 150
    #define JOY_DEADBAND_Y 150
    #define JOY_DEADBAND_Z 150
    #define JOY_MAX_X 2000
    #define JOY_MAX_Y 2000
    #define JOY_MAX_Z 2000
    #define JOY_SLOW_FEEDRATE 3//0.01
    #define JOY_FAST_FEEDRATE 30//0.01
    #define JOY_SLOW_MOTION 0.1  //0.01
    #define JOY_FAST_MOTION 0.5  //0.05
    #define JOYZ_SLOW_MOTION 0.01  //0.01
    #define JOYZ_FAST_MOTION 0.05  //0.05

    #if defined EXT_AJOYSTICK
    int loop_delay = 0;
    //extern volatile uint osAnalogInputValues[ANALOG_INPUTS];

    int get_joystick_position_x()
    {
    int Joy_Position_X = 0;

    Joy_Position_X = (osAnalogInputValues[KEYPAD_ANALOG_INDEX] - JOY_CENTER_X)*JOY_DIR_X;
    if (Joy_Position_X < JOY_DEADBAND_X && Joy_Position_X > -JOY_DEADBAND_X)Joy_Position_X = 0;
    else {
    if (Joy_Position_X >= JOY_DEADBAND_X) Joy_Position_X -= JOY_DEADBAND_X;
    if (Joy_Position_X <= -JOY_DEADBAND_X) Joy_Position_X += JOY_DEADBAND_X;
    }
    return Joy_Position_X;
    }

    int get_joystick_position_y()
    {
    int Joy_Position_Y = 0;
    Joy_Position_Y = (osAnalogInputValues[KEYPAD2_ANALOG_INDEX] - JOY_CENTER_Y)*JOY_DIR_Y;
    if (Joy_Position_Y < JOY_DEADBAND_Y && Joy_Position_Y > -JOY_DEADBAND_Y)Joy_Position_Y = 0;
    else {
    if (Joy_Position_Y >= JOY_DEADBAND_Y) Joy_Position_Y -= JOY_DEADBAND_Y;
    if (Joy_Position_Y <= -JOY_DEADBAND_Y) Joy_Position_Y += JOY_DEADBAND_Y;
    }
    return Joy_Position_Y;
    }

    int get_joystick_position_z()
    {
    int Joy_Position_Z = 0;

    Joy_Position_Z = (osAnalogInputValues[KEYPAD3_ANALOG_INDEX] - JOY_CENTER_Z)*JOY_DIR_Z;
    if (Joy_Position_Z < JOY_DEADBAND_Z && Joy_Position_Z > -JOY_DEADBAND_Z)Joy_Position_Z = 0;
    else {
    if (Joy_Position_Z >= JOY_DEADBAND_Z) Joy_Position_Z -= JOY_DEADBAND_Z;
    if (Joy_Position_Z <= -JOY_DEADBAND_Z) Joy_Position_Z += JOY_DEADBAND_Z;
    }
    return Joy_Position_Z;
    }

    int get_joystick_btn()
    {
    int Joy_BtnState = 0;
    Joy_BtnState = digitalRead(JOY_BTN_PIN);
    return Joy_BtnState;
    }


    void set_joystick_run()
    {
    int ad_x, ad_y, ad_z;
    loop_delay += 1;
    if (loop_delay >= 5)
    {

    ad_x = get_joystick_position_x();
    ad_y = get_joystick_position_y();
    ad_z = get_joystick_position_z();

    if (get_joystick_btn() == 1 && (ad_x != 0 || ad_y != 0 || ad_z != 0)) //slow motion
    {
            PrintLine::moveRelativeDistanceInSteps((int32_t)(ad_x*JOY_SLOW_MOTION), (int32_t)(ad_y*JOY_SLOW_MOTION), (int32_t)(ad_z*JOYZ_SLOW_MOTION), 0, Printer::maxFeedrate[X_AXIS],false, true, true);
    Commands::printCurrentPosition(PSTR("UI_ACTION_XPOSITION_FAST "));
    }
    else if (get_joystick_btn() == 0 && (ad_x != 0 || ad_y != 0 || ad_z != 0)) //fast motion
    {
            PrintLine::moveRelativeDistanceInSteps((int32_t)(ad_x*JOY_FAST_MOTION), (int32_t)(ad_y*JOY_FAST_MOTION), (int32_t)(ad_z*JOYZ_FAST_MOTION), 0, Printer::maxFeedrate[X_AXIS],false, true, true);
    Commands::printCurrentPosition(PSTR("UI_ACTION_XPOSITION_FAST "));
    }
    loop_delay = 0;
    }
    }


    void joy_print()
    {
    loop_delay += 1;
    if (loop_delay >= 100)
    {
    Com::print("X: ");
    Com::print(get_joystick_position_x());
    Com::print(" | Y: ");
    Com::print(get_joystick_position_y());
    Com::print(" | Z: ");
    Com::print(get_joystick_position_z());
    Com::print(" | Button: ");
    Com::print(get_joystick_btn());
    Com::println();
    loop_delay = 0;
    }
    }
    #endif


    ------------------------------------------------------
    add new line into code "commands.cpp" routine "commandLoop()"
    ------------------------------------------------------
    #include "Joystick.h"

    ..
    .
    .
    void Commands::commandLoop() {
        while(true) {
    #ifdef DEBUG_PRINT
            debugWaitLoop = 1;
            if(!Printer::isBlockingReceive()) {
                GCode::readFromSerial();
                GCode *code = GCode::peekCurrentCommand();
                //UI_SLOW; // do longer timed user interface action
                UI_MEDIUM; // do check encoder
                if(code) {
    #if SDSUPPORT
                    if(sd.savetosd) {
                        if(!(code->hasM() && code->M == 29))   // still writing to file
                            sd.writeCommand(code);
                        else
                            sd.finishWrite();
    #if ECHO_ON_EXECUTE
                        code->echoCommand();
                    } else
                        Commands::executeGCode(code);
                    code->popCurrentCommand();
                }
            } else {
                UI_MEDIUM;
            }
            Printer::defaultLoopActions();

    //#ifdef EXT_AJOYSTICK 
        set_joystick_run();     // joystick 
        //joy_print();
    //#endif
        }
    }

Sign In or Register to comment.