Re: Jog wheel (with code attached)
starting about a year ago I did some collaboration with Alan Marconett on
the CCED list on the handwheel interface ,hammering out the best ways to
get the input into the control and looking into what problems might come up
the result was the pendant Alan made from junk box parts shown here
check the pendant 1 and 2 jpegs
http://photos.groups.yahoo.com/group/cad_cam_edm_dro/lst?.dir=/Driver-PS+%26+Pendant
compare Alan's pendant with the $300-$500 versions
http://www.maxmar.com/mpg.htm
http://www.sumtak.com/contents/product/handLGB601/indexLGB601.htm
http://www.cui.com/encoders/encd_tools.htm
functionally they are pretty much the same
for the encoder I would use one of the optical panel mount encoders
like the CUI RE20 shown here
http://www.cui.com/encoders/encd_paneloptic.htm
available as Digi-Key Part Number 102-1012-ND
*********IMPORTANT NOTE***********************
check the data sheet before trying to get the detented versions
of the the RE20s
the detented version has 25 lines (100 quad transitions) with only
25 detents (4 transitions per detent) lined up with the A&B high phase
this is not what we you want
instead get the non-detented encoder and build the detents into
the knob using an index plate with 100 dimples and a spring pin under
the handwheel knob
***************************************************
the code I've attached is a rough port to Linux/EMC of
the code Alan came up with for his pendant mixed with some
of the code from the jog sections of Xemc or Keystick
it uses the 4 button inputs of the game port only and handles the
encoder and two push buttons to set the axis and jog increment
and sends the same messages to EMC as the GUI would
I've tested parts of it and the encoder bit works fine with no
extra external logic on the encoder lines using a home built
encoder setup I hacked together just keep it simple and run
the A and B lines right into the game port
the idea is to build this as a standalone task module that can be
loaded alongside ANY of the existing user interfaces without
having to rewrite all of them to include this feature
all of the current interfaces are already set to display the selected axis
and increment on each refresh so it dosent matter if the message
came from the UI itself or another module
making it into a loadable module is the bit I'm still having trouble with
task timing
the handwheel task should only be active while in jog mode
and should be scheduled to run just fast enough to keep up
with the average Joe spinning the knob at a controlled rate
so maybe one hundred times per second max if the axis can even keep up
at this ( max_jog_speed * max_jog_increment) combination
(the real world is SOOO much slower than the CPU world)
spinning the knob faster than this will cause some incremental jog commands
to be skipped over ,the axis will still move as fast as it can as long as
you are spinning but will stop on a multiple of the increment without
overshooting as soon as you quit turning the wheel
this would give it a nice ,predictable and fairly safe behavior
Brian
//EMC handwheel jog module for the gameport
/*!
the game port pinouts for machine jog controls
power and ground ,two of these are commonly used for the MIDI port
check the docs on your port from the motherboard or soundcard manual
and break them out seperatly so the MIDI port is still available later on
pins 1,8,9,15 = +5V (both outermost pairs)
pins 4,5,12 = gnd (three in the center)
analog pins are not used
pin-3 = analog-1 = bit-0 of port 0x201
pin-6 = analog-2 = bit-1
pin-11 = analog-3 = bit-2
pin-13 = analog-4 = bit-3
the four digital pins on upper nibble are used
but must be shifted over and masked off in the code
these pins are normaly open (pulled up) the buttons should close to GND
pin-2 = digital-1 = bit-4 axis select button
pin-7 = digital-2 = bit-5 jog increment select button
pin-10 = digital-3 = bit-6 encoder ch-A
pin-14 = digital-4 = bit-7 encoder ch-B
the axis and jog increment selection buttons are used to scroll thru a list of values shown on
the screen by the GUI
the handwheel encoder is polled and compaired to its last value to test for step and direction
a CUI RE20NC25C20RA (Digi-Key Part Number 102-1012-ND) 25 line encoder would be
fine for this
note do not use the inexpensive detented encoders as they only have 25 detents
instead build the detents (100 of them) into the pannel knob and use the non-detented
25 line encoders
/*
/*set the port address */
#define GAMEPORT 0x201
/*we need a function to read the port for Linux we can use this*/
get_joystatus(int port)
{
unsigned char ch;
ioperm(port,1,1);
ch=inb(port);
return ch;
}
//set up variables
unsigned char joystatus ,last_joystatus ,handwheel ,last_handwheel ,axis_btn ,incr_btn;
static double jogIncrement = 0.0001;
static double jogSpeed = 60.0;
static int axisSelected =0;
//=====================================================================
//activate in manual mode only
if (emcStatus->task.mode == EMC_TASK_MODE_MANUAL)
{
/* first initialize joystatus and handwheel */
{
last_joystatus = get_joystatus(GAMEPORT);
last_handwheel=(last_joystatus>>0x06) & 0x03 ;
}
/*then in the jog loop*/
joystatus=(get_joystatus(GAMEPORT));
if (joystatus!= last_joystatus) /*something has changed*/
{
//set to jog incremental
jogMode = JOG_INCREMENTAL;
// get current values for increment and axis select buttons and handwheel state
axis_btn=(joystatus>>0x04) & 0x01
incr_btn=(joystatus>>0x05) & 0x01
handwheel=(joystatus>>0x06) & 0x03
}
// check the buttons first -button pressed=0 open=1
// and scroll thru values
if ( !axis_btn) {
axisSelected++
if (axisSelected < 0 || axisSelected >= EMCMOT_MAX_AXIS)
{
axisSelected=0;
}
}
if ( !incr_btn){
jogIncrement *= 10.0;
if (jogIncrement >= 0.1)
{
jogIncrement = 0.0001;
}
}
// test for handwheel change
if (handwheel != last_handwheel)
{
switch (handwheel){
case 0x00:
if(last_handwheel == 0x03)
jogSpeed = jogSpeed; /*fwd*/
else if(last_handwheel == 0x01)
jogSpeed = -jogSpeed; /*rev*/
else // should never get here
jogSpeed=0.0; /*error -do nothing*/
break;
case 0x01:
if(last_handwheel == 0x00)
jogSpeed = jogSpeed;
else if(last_handwheel == 0x02)
jogSpeed = -jogSpeed;
else
jogSpeed=0.0;
break;
case 0x02:
if(last_handwheel == 0x01)
jogSpeed = jogSpeed;
else if(last_handwheel == 0x03)
jogSpeed = -jogSpeed;
else
jogSpeed=0.0;
break;
case 0x03:
if(last_handwheel == 0x02)
jogSpeed = jogSpeed.;
else if(last_handwheel == 0x00)
jogSpeed = -jogSpeed;
else
jogSpeed=0.0;
break;
default :// should never get here
jogSpeed=0.0;
}
last_handwheel=handwheel; // store value for next time
// pass the new values to EMC
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisSelected;
emc_axis_incr_jog_msg.vel =jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
}
}
Date Index |
Thread Index |
Back to archive index |
Back to Mailing List Page
Problems or questions? Contact