hidcomp
- Introduction
- Installing hidcomp
- hidcomp
- hidconfig
- Permissions
- Problem Devices
- Known Issues
- ToDo List
- Change History
Introduction
hidcomp is an EMC/LinuxCNC user mode component to provide access to USB HID devices. A HID device is a Human Interface Device, things like joysticks, gamepads, multimedia controllers (like the Shuttle Pro), and more exotic devices like barcode scanners, alphanumeric displays, medical instruments and home made USB pendants.
Why another HID interface component when EMC/LinuxCNC already has hal_input and hal_joystick?
- hidcomp was written to support my home made USB pendant (this is another project, GenericHID)
- hidcomp uses the low level USB protocols and does its own HID interfacing, so it can, or can be modified to, work with non-standard, or just more complex devices.
- It supports additional controls on a device...
- Encoder support, which allows devices like Contour Design's, Shuttle Pro to work
- Alphanumeric displays, currently only supporting text mode displays
- Hat switches.
- Selector switches.
- Adds scaling and shaping of analogue inputs (e.g. joystick axis)
- hidconfig makes it easier to find and configure HID devices
- Correctly finds and handles multiple identical devices, e.g. 2 Logitech gamepads
What doesn't hidcomp do?
- It still only provides a set of HAL pins that need to be connected up to other HAL components in a .hal file. hidcomp doesn't help you multiplex buttons and switches.
- Probably many things. I wrote hidcomp to support my USB devices, so it has only had minimal testing. However, USB devices are generally pretty simple, so it should work with most. If it doesn't, because hidcomp was written to interface devices at the lowest level, changes can be made to support them.
Installing hidcomp
A debian (Ubuntu) package is available to install hidcomp. The source code is also available. This package is build against EMC/LinuxCNC 2.6.7, and Debian 7.
The files can be download here.
To install hidcomp, download the binary package and install it with your favourite package manager. Or install it from the command line...
sudo dpkg -i hidcomp_1.7_i386.deb
hidcomp can be uninstalled using ...
sudo dpkg -r hidcomp
To build the source, unpack the .tgz source package and read the README file. hidcomp requires Qt 4.5.2. The release package is built against a static library build of Qt.
Changes to emc.nml/linuxcnc.nml
In order to support displaying EMC/LinuxCNC information on an LCD display, hidcomp must hook into the EMC/LinuxCNC messaging system. This is done by adding the following lines to the emc.nml/linuxcnc.nml file. (The file may be called something else - check for the NML_FILE parameter in the EMC section in the ini file)
P hidcomp emcCommand LOCAL localhost W 0 10.0 0 10 P hidcomp emcStatus LOCAL localhost R 0 10.0 0 10 P hidcomp emcError LOCAL localhost R 0 10.0 0 10
Note - this change is only necessary if an LCD module is used.
Note 2 - The NML file now normally lives in /usr/share/linuxcnc/linuxcnc.nml. To customise your version, copy this file to your config directory and add the hidcomp lines. Don't forget to add the NML_FILE parameter to the EMC section of the ini file to tell EMC/LinuxCNC to use your version.
hidcomp
The hidcomp component provides a hal representation of a USB HID device. The pins exposed by hidcomp are defined using the hidconfig application.
Supported Controls
USB Data Type | Common Usage | Description |
Input Value 1 Bit | Button | An input value which has a 1 bit data length is interpreted as a button, although it could be any digital input. |
Input Value > 1 Bit | Axis, Selector switch, jog Wheel, volume control | An input value which has a data length greater than 1 bit, has its value exposed as an integer value. This may be an analogue joystick, or a selector switch. |
Input Value > 1 Bit, with wrap | Encoder | When an input value has the wrap bit set in its description, the control is interpreted as an encoder. The wrap bit implies the counter wraps around to 0 when it hits its maximum value (or vice-versa). |
Input Value > 1 Bit, usage=HATSWITCH | Hat switch | The hat switch is a special case of an input value. The devices sets the control's recommended usage to HATSWITCH. The data is then interpreted as a directional key press. If the key isn't pressed, an out of range value is returned. |
Output Value 1 Bit | LED | An output value which has a 1 bit data length is interpreted as an LED, although it could be any digital output. |
Output Value > 1 Bit | Multi-Colour LED | The Generic HID device can support bi-colour and tri-colour LEDs, which is how these devices are set. Only a simple integer output is supported at this time. |
USAGE=ALPHA_NUMERIC_DISPLAY | LCD |
hidcomp supports standard character only alphanumeric displays. It has been tested with 1x8, 2x20 and 4x20 displays, but should be able to cope with any size. This has only been tested against a home made USB Alphanumeric display, and as such, may need to be tweaked to make work with other displays. The requirements at the moment are...
|
Synopsis
hidcomp [-ini inifile] [-d] [-n name] configfile ...
Options
-ini inifileThe ini file that is used to start EMC/LinuxCNC. This defaults to emc.ini. If it is not emc.ini, or in a location that hidcomp can't find it, it must be specified.
-dTurn on debugging. Debugging sends volumous amounts of data to stderr. In order to catch the debug, start EMC/LinuxCNC on the command line and redirect stderr to a file. For example.../usr/bin/linuxcnc mill.ini 2> logfile
-n nameChange the name of the component as seen by HAL. The default name is hidcomp.
configfile ...One or more configuration files. These files are created with the hidconfig application. Each device is accessible in HAL as hidcomp.n, where n is the number of the device, starting at zero, as it appears on the command line.
Usage
hidcomp is a user space component so it must be loaded into EMC/LinuxCNC using loadusr...
loadusr -W hidcomp -ini lathe.ini pendant.hidhidcomp can take a while to start, so it is recommended to use the -W option of loadusr to wait for the component to start.
If more than one USB device is used, there are two ways to support this. First, two configuration files can be specified on the command line. For example...
loadusr -W hidcomp -ini lathe.ini pendant1.hid pendant2.hid
This will make the two devices available as hidcomp.0.* and hidcomp.1.*
The other way to support multiple devices is to load hidcomp multiple times with different names. For example...
loadusr -Wn joypad -name joypad -ini lathe.ini joypad.hid
loadusr -Wn gamepad -name gamepad -ini lathe.ini gamepad.hid
The devices in the above example can then be accessed as joypad.0.* and gamepad.0.*
Exported Pins
When run, hidcomp will export a large number of pins based on the definition in the configuration file. These can then be used in the EMC/LinuxCNC HAL file to control parts of the EMC/LinuxCNC machine, usually via halui(1).
The exported pins are defined in the configuration file created by hidconfig. The name of each control (button, axis, encoder, etc) can be changed using hidconfig but the suffix remains the same.
Control Type | Pin Suffix | Data Type | Direction | Description |
---|---|---|---|---|
Button | *.in | bit | out | The button state. 1 when pressed, 0 when not pressed. |
*.in-not | bit | out | The inverted button state. 0 when pressed, 1 when not pressed. | |
Hat switch | *.raw | s32 | out | The raw value from hat switch control. Usually 0 to 7 representing the 8 directions, and a number outside this range, e.g. 8, meaning not pressed |
*.direction | float | out | The direction the switch has been pressed in degrees, 0-315° for an 8 position switch. -1 represents no press. | |
Value (axis) | *.raw | s32 | out | The raw value from control. The range varies. |
*.ivalue | u32 | out | The scaled *.raw value as an u32 type. Scaling is configured using the hidconfig application. | |
*.fvalue | float | out | The scaled *.raw value as a float type. Scaling is configured using the hidconfig application. Scaling is usually configured by user to make this value range from -1.0 to 1.0 | |
Encoder | *.raw | s32 | out | The raw value from control. The range varies. |
*.count | s32 | out | The accumulated count value as an integer. | |
*.position | float | out | The accumulated count value, scaled to a floating point value. Scaling is set using the hidconfig application. | |
*.reset | bit | io | When the bit is set, the counter is reset to 0. The *.reset bit is then set back to 0. | |
LED | *.out | bit | in | Toggle an LED on and off. An LED can generically be used as a digital output. |
Output Value | *.ivalue | s32 | in | A generic output of data size > 1 bit. |
Alphanumeric Display | *.page-select | s32 | in | Used to select a page of information on the display. Pages are user defined using hidconfig. |
*.pages | s32 | out | Returns the number of user defined pages. This is a pin so it can be connected to a page turning component to set the maximum number of pages at run time. | |
*.max-page | s32 | out | The same as *.pages - 1. More useful because pages are number 0 to pages-1. | |
*.in-bit-n | bit | in | User defined input bit. Used to display items that are not available from hidcomp's internal database base. n can be any integer value. | |
*.in-float-n | float | in | User defined input float. Used to display items that are not available from hidcomp's internal database base. n can be any integer value. | |
*.in-s32-n | s32 | in | User defined input s32. Used to display items that are not available from hidcomp's internal database base. n can be any integer value. | |
*.in-u32-n | u32 | in | User defined input u32. Used to display items that are not available from hidcomp's internal database base. n can be any integer value. |
The simplest way to list all of the pins is to add the loadusr hidcomp -ini my.ini device.hid line to an EMC/LinuxCNC hal file, run EMC/LinuxCNC, then browse the pins using the configuration browser. This is the "Show Hal Configuration" menu option in the "Machine" menu in Axis.
hidconfig
The hidconfig application is used to create configuration files used by hidcomp. This is a convenient way to find devices, identify controls and adjust the function of the controls.
Main screen
hidconfig is run from the command line...
hidconfig [file.hid]optionally specifying an existing configuration file to edit. The default extension for the hidcomp configuration files is ".hid".
hidconfig is a graphical application built using Qt, so a graphical Windowing System must be running. The next image shows the start up screen.
To create a new configuration, hit the "New" button on the tool bar, or select "New" from the "File" menu. Alternatively, an existing file can be opened using the "Open" button, or "Open" menu item.
Selecting "New" will prompt with the "Select Device" dialog, shown below.
The "Select Device" dialog box will show a list of USB HID devices that have been recognised by hidconfig. Those devices that hidconfig has permission to access are shown with the full manufacturer name and device name. When hidconfig doesn't have permission to access a USB HID device, only the vendor id (VID) and product id (PID) are shown, with an asterisk (*) next to the name.
If all devices appear with an asterisk, you will not be able to configure any devices. The correct solution is set up the udev permissions correctly. See the section on permissions. A quick and dirty work around is to run hidconfig as root, i.e. use...
sudo hidconfigBut that is only a temporary solution. hidcomp wont work, and any configuration file you create will have root ownership permissions which you need to address.
When a device is loaded, hidconfig will show all the available controls in a functional display. Below is an screen shot of my Logitech dual action game pad.
The window is broken up into two parts: the "Device Search Criteria" frame (top part), and the "HID Device Input/Output items" (the large bottom part).
Device Search Criteria
The "Device Search Criteria" is used to identify the USB device. Most applications only use the VID and PID (Vendor ID and Product ID). This is fine if you only have one device.
If you only have one USB device, mark the PID and VID checkboxes.
This wont work, however, if you have more than one of the same device. You need to specify additional attributes to check when searching for the USB device. These can be the Manufacturer name, the Product name, the Serial Number (S/N), or the system id.
The Manufacturer name, Product name, and Serial Number are self explanatory and generally wont vary across identical devices. The system id, will always be unique. It represents the USB port that the device is plugged into. For two identical devices, this is the only way to distinguish them. As long as the device isn't moved from one USB port to another, it will always locate the same device.
The "Test Criteria" button can be used to check how many devices are found using the current criteria. You will be warned when saving the file if the criteria doesn't match exactly one device. This is important. If hidconfig cannot uniquely identify the device specified in the configuration file it will not be able to reload the file. Similarly, hidcomp will not be able to locate the USB device.
HID Device Input/Output items
The majority of the hidconfig display shows all of the USB device's controls and configuration laid out in a table.
Each row represents one of the device's controls. On the Logitech gamepad shown above, the first 4 rows show the joystick axis, then one row for the hat switch, 12 rows for the buttons and then 23 rows (only the first 3 shown) for some undocumented gamepad magic.
There are 5 columns in the table.
- Current Value - this shows the current raw value of the USB Device control. Use this to test and identify which control is which on the device.
- USB Name - the shows the USB Device allocated Usage Page and Usage. These are the suggested usages of the control.
- Enabled Check Box - unless the check box is ticked, the control will not be available.
- Hal Pin name - the unique pin name (prefix) for the control. This can be set to any meaningful name. The name must be unique among enabled pins. The total name length (hidcomp.n.<pin name>.suffixes) must not be more than 40 characters. This is checked before the configuration file is saved.
- Configuration button - some controls, value type and LCDs have additional configuration that can be accessed via the button.
Value Config Dialog
The Value Config Dialog is used to customise USB value controls. A screen shot is shown below.
Overrides
The first section of the dialog is the Overrides section. This allows modification of controls that don't behave as expected. Currently, the only control that misbehaves is the Wheel on the Shuttle Pro, which claims a Logical Min/Max of -128/127, but only generates values of -7/7.
The Type combo box doesn't do anything. Yet.
Output
The Output section controls the scaling of output values. Specify a min/max value, and the control's logical min/max will be scaled between them. The output type combo box is not used, as both a floating point scaled value (.fvalue) and a scaled integer value (.ivalue) are output.
The Reverse Axis check box will reverse the direction of the value. This can also be accomplished by swapping the min/max values (although the changes will only be visible when using the device in hidcomp).
Response
Checking the Use Response Curve check box will enable the response curve. This allows the behaviour of an axis to be changed. In the example above, there is a dead zone specified in the middle, and a non-linear behaviour when moved.
The display is broken up into two parts. The response curve plot, which shows the position of the raw input value as a vertical red line, and the control output, displayed as a single bar.
The nodes on the curve can be moved, added and deleted. When the mouse cursor is over a node, the mouse pointer will change to a hand. Click and drag the node.
Nodes are deleted by right clicking on them and selecting delete node from the context menu.
Nodes can be added by right clicking anywhere on the line and selecting add node from the context menu.
If changes are made to the curve, the curve is save as the "Custom" curve. The buttons at the bottom, "1", "2", "3", "4", and "Custom" can be used to cycle through the built-in curves and the custom curve. If a built-in curve is changed, the changes are saved to the custom curve.
The Snap to Grid check box helps align nodes. It only assists when moving nodes. It doesn't automatically move nodes that aren't aligned to the grid.
LCD Config Dialog
The LCD (Alphanumeric Display) interface is implemented as a series of pages containing display fields. Multiple pages can be defined and then selected using the *.page-select hal pin. Each page contains a series of formatted data fields. These fields display values that are present on hal input pins, or via a list of predefined values that hidcomp knows about.
The LCD Configuration dialog is shown below
Pages
On the left side of the dialog is the pages list. The "New Page" and "Delete Page" buttons below the list are used to add and remove pages.
Pages are always numbered consecutively from 0. The "Page Name" in the list is only used in hidconfig for information.
The up and down arrows to the right of the page list is used to change the order of the pages. Moving pages will change the page number.
In the example above, there are 3 pages. The main page, #0, is the default and will be shown at start-up. A button is wired to the hal updown counter component then wired to the .page-select pin to cycle through the pages. The tool change page, #2, is configured to be selected when a tool change is requested.
LCD Display
The top right section of the dialog shows a simulated LCD display. It will show the contents of each page as the page items are edited. The same display will also be shown on the LCD display of the USB Device.
Display Items
The table underneath the LCD display contains a list of all of the fields that will be displayed on a page. The example above shows an overly complex display, but is a good example of what can be done.
The table has 7 columns...
Column | Description |
---|---|
Col | The column number that data is to appear on. Column numbers start at 0. |
Row | The row number that data is to appear on. Row numbers start at 0. |
Value | What is to be displayed. This can be one of the build in data fields, or an external pin. The fields are listed below. |
Format | How the data is formatted. More on this below. |
Scale | A multiplier applied to the data before it is displayed. Only used on integer and floating point data fields. Typically used to convert 0-1 to 0-100%, or unit conversions. |
Index | Some data fields require an additional index. For example, the Actual Position field, requires an index to specify the axis (0=x, 1=y, 2=z, etc). When a format is selected, a tool tip will describe if an index is required. |
Test Value | Used to populate the LCD display with sample data. Use this field to test all values that may displayed in the LCD. In particular test min/max values to ensure fields don't overflow. |
The "Refresh Period (ms)" field specifies how often the display should be updated.
Data Values
The data values displayed on the LCD can be selected from the internal database of known values, or a data value that has been set via an input pin. The list of all data values is listed in the table below...
Operator Error | Operator Error Messages |
Operator Text | Operator Text Messages |
Operator Display | Operator Display Messages |
Operator Message | The last Operator Messages |
Mode | EMC/LinuxCNC Task Mode - 1=Manual, 2=Auto, 3=MDI |
State | EMC/LinuxCNC Task State - 1=E-Stop, 2=E-Stop/Reset, 3=Off, 4=On |
Execution State | EMC/LinuxCNC Executing state 1=Error, 2=Done, 3=Waiting for Motion, 4=Waiting for Motion Queue, 5=Waiting for IO, 6=Waiting for Pause, 7=Waiting for Motion and IO, 8=Waiting for Delay, 9=Waiting for System Cmd |
Interpreter State | EMC/LinuxCNC Interpreter state - 1=Idle, 2=Reading, 3=Paused, 4=Waiting |
Motion Line | The line in the GCode file that corresponds to the current motion position |
Current Line | The line in the GCode file that corresponds to the line the interpreter is looking at |
Optional Stop State | Optional Stop State |
Block Delete State | Block Delete State |
GCode File Path | The full path of the current GCode program |
GCode File Name | The file name of the current GCode program |
GCode Command | The current GCode command being interpreted |
Active GCodes | Active GCodes. Index from 0 to 15 |
Active MCodes | Active MCodes. Index from 0 to 9 |
Active Settings | Active settings. Index from 0 to 2 |
Paused | Task Paused |
Trajectory Mode | Trajectory Mode 1=Free, 2=Coord, 3=Teleop |
Trajectory Enabled | Trajectory Enabled |
In Position | Motion in position |
Paused | Motion paused |
Commanded Position[axis] | Commanded Position for each axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Actual Position[axis] | Actual Position for each axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
System Velocity | System velocity for subsequent moves |
System Acceleration | System acceleration for subsequent moves |
Last Probe Trip Pos[axis] | Last probe trip position for each axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Probe Tripped | Probe tripped since last clear // int EMC_TRAJ_STAT.probe_tripped; // Has the probe been tripped since the last // clear. |
Probing | We are currently probing |
Probe Value | Current probe value |
Distance to Go | Distance to go in current move |
Distance to Go[axis] | Distance to go for each individual axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Current Velocity | Velocity of current move |
Feedrate Override Enabled | Feedrate override enabled |
Spindle Override Enabled | Spindle override enabled |
Adaptive Feed Enabled | Adaptive feed enabled |
Feed Hold Enabled | Feed Hold Enabled |
FError[axis] | Current following error for this axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Command Output Position[axis] | Current Command Position for this axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Current Input Position[axis] | Current Input Position for this axis. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
In Position[axis] | The axis is currently at the requested position. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Homing[axis] | The axis is currently homing. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Homed[axis] | The axis is homed. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Fault[axis] | The axis has faulted. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Enabled[axis] | The axis is enabled. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Min Soft Limit[axis] | The axis has exceeded the min soft limit. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Max Soft Limit[axis] | The axis has exceeded the max soft limit. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Min Hard Limit[axis] | The axis has exceeded the min hard limit. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Max Hard Limit[axis] | The axis has exceeded the max hard limit. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Override Limits[axis] | Override the limits. Axis numbers from 0-8 represent axis x,y,z,a,b,c,u,v,w |
Spindle Speed | Spindle speed in RPM |
Spindle Direction | Spindle direction. 0=stopped, 1=forward, -1=reverse |
Spindle Brake | Spindle brake. 0=released, 1=engaged |
Spindle Increasing | Spindle Speed Increasing. 1=increasing, -1=decreasing, 0=steady |
Spindle Enabled | Spindle enabled |
Tool Prepped | Tool ready for loading. 0 is no tool |
Tool In Spindle | Tool in spindle. 0 is no tool |
Coolant-Mist | Mist coolant. 0 - off, 1 - on |
Coolant-Flood | Flood coolant. 0 - off, 1 - on |
E-Stop | E-Stop - 0 means run, 1 stopped |
Lube On | Lube on - 0=off, 1=on |
Lube Level | Lube level - 0=low, 1=okay |
User S32[index] | Custom User S32 value on pin <device>.lcd-s32-<index>. Any Index values can be used |
User U32[index] | Custom User U32 value on pin <device>.lcd-u32-<index>. Any Index values can be used |
User Float[index] | Custom User Float value on pin <device>.lcd-float-<index>. Any Index values can be used |
User Bit[index] | Custom User Bit value on pin <device>.lcd-bit-<index>. Any Index values can be used |
The last four rows show how to set up user defined data sources. By specifying a User data type and an index, hidcomp will provide a hal input pin for custom data. For example, selecting "User U32[index]" and index 17, hidcomp will create an input pin hidcomp.0.LCD.in-u32-17
Format
The LCD data fields are formatted using printf format strings. A format string can contains plain text and optionally an embedded format tag of the form...
%[flags][width][.precision][length]specifierNote - it only make sense to use the correct format string for the correct data type, i.e. %d,%u for integers, %f,%g,%e for floating point values, etc. Using the incorrect format specifier will produce unpredictable results.
For a detailed description of the format string, see the printf(3) man page or do an internet search on printf.
In addition to all the standard printf format strings, a custom enumeration type, %b is also supported. The syntax of this format is as follows...
%[flags][width][.precision][length]:id,string[:id,string]:bAs you can see, the format is the same as the printf syntax followed by a colon separated list of (id,string) pairs, followed by the specifier, b. id, is an integer that is matched against input data and the matching string is used as the output. The id,string pair is used as the default when the data value does not match. Internally, when the string is formatted, the (id,value):b data is stripped out and replaced with the s specifier, turning the format into a string format. It only makes sense to use this format for integer data.
For example, in the screen shot above, line 4 shows how to display an * (asterisk) when an axis has not been homed...
%1:0,*:1, :bThe formatting starts with the % (percent symbol) to indicate the formatting tag, followed by a 1 (one) to specify the field width. So far is a standard printf format. Then comes the : (colon), which indicates the first id,string pair. The first pair is 0,* which means if the data value is 0, display a *. The next pair is 1, (one comma space), which means if the value is one, display a space character. Additionally, because it is the last pair, a space character will be displayed if any other value is present. Internally, the value pairs are stripped from the format string and replaced with the s specifier, in this case leaving "%1s".
When designing a format string for data, make sure the final result is a fixed width string otherwise artefacts may be left on the screen. The example below shows the difference between using %d and %5d for formatting an integer value. The Acc column shows the accumulated result on the LCD after the value has been displayed. The Acc %5d column looks fine (dots are used to represent spaces). Acc %d however does not display the Value of 5 correctly - it has failed to erase the text underneath it. That's why a fixed width string format should be used to erase the previous contents
Value | %d | Acc %d | %5d | Acc %5d |
---|---|---|---|---|
1 | 1 | 1 | ....1 | ....1 |
123 | 123 | 123 | ..123 | ..123 |
5 | 5 | 523 | ....5 | ....5 |
When a Data Value is selected in the table, its default format string is selected, if no previous edits have been made to the existing format string.
User Fonts
hiconfig support user font characters. Each display can have up to 8 user defined characters. These characters are shared between the pages of the display.
Hit the "User Fonts" button to edit the fonts. The "User Fonts" button only appears if the LCD display supports user defined fonts. This shows the Edit Font dialog...
The font above is the degrees symbol. Left click to set a dot. Right click to clear a dot. 8 characters can be defined.
LCD External Access Port
The "LCD External Access Port" provides an external interface to the LCD display. The port is a TCP Socket Port number, in the range 1 to 32767, that provides a simple text based interface to the LCD. The port number can be any free port; I use 29090.
The External Access Port allows any application to connect to hidcomp and write directly to the LCD display. It uses a series of simple text commands to access the LCD display. All commands are terminated by a newline character ('\n' or 0x0A), and respond with "OK\n" if successful, or "?\n" when not. The following is a list of the commands supported by the external interface.
hello | Connection initialisation command. This currently doesn't do anything, but can be used to check if the display is present. |
cls | Clears the screen. For displays that support different colours, this command will clear the display to to the current background colour. |
fg R,G,B | Sets the current foreground colour on devices that
support colour. R/G/B are the Red/Green/Blue
components of the colour and range from 0-255. For
example, to set the foreground colour to red, fg 255,0,0 |
bg R,G,B | Sets the current background colour on devices that
support colour. R/G/B are the Red/Green/Blue
components of the colour and range from 0-255. For
example, to set the background colour to black, bg 0,0,0 |
text x, y, data | Displays text on the screen at character position
x,y. data is a quoted string. For graphic
based devices, the current foreground and background
colours are used. For example, text 0,1, "Test string" |
textp x, y, data | Displays text on the screen at pixel position x,y.
data is a quoted string. For graphic based
devices, the current foreground and background colours
are used. This will only work on devices that support
pixel positioning. For example, textp 92,27, "Test string" |
font id | Changes the font to 'id'. This only works on
devices that support fonts. For example, font 0 |
backlight intensity | Sets the LCD backlight to 'intensity' from 0-100.
0 is off. Only works with devices that support
changing the backlight intensity. For eaxmple... backlight 50 |
rect x,y,w,h | Draw a rectangle with its top corner at (x,y), width
w, and height h. The rectangle is drawn with the
current foreground colour. Only works with devices that
support rectangles. For example... rect 0,0,320,240 |
fill x,y,w,h | Draw a filled rectangle with its top corner at (x,y),
width w, and height h. The rectangle is filled
with the current foreground colour. Only works with
devices that support rectangles. For example... fill 0,0,320,240 |
A simple way to test the display is to use a telnet session...
> telnet localhost 29090 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. hello OK cls OK text 0,0,"This is text line 1" OK ^] telnet> quit Connection closed.
This is an example using python...
import socket lcd = None host='localhost' port=29090 for i in range(10): try: lcd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) lcd.connect((host, port)) break except: pass time.sleep(1) if lcd == None: print "Failed to connect to LCD socket - host:" + host + ", port:" + `port` exit() def cls(): lcd.send('cls\n') def text(x,y,s): lcd.send('text ' + `x` + ',' + `y` + ', "' + s + '"\n') cls() text(0,0,"Test string")
The external interface is useful for interactive displays. See Lathe Pendant for an example.
Permissions
Note - this information applies to Ubuntu 8.04 and may or may not work for other versions.
When you insert a USB device, by default, the device is owned by root. As mentioned above, a quick and dirty fix is to run hidconfig as root but that will only allow a configuration file to be built, not run hidcomp.
The correct solution is to create a udev rules file. A file is create in /etc/udev/rules.d which tells udev (the dynamic device management system) what to do when the device is inserted. We only need to set permissions.
Here is an example of a udev rules file. In my /etc/udev/rules.d/ folder I have created the file 99-hid.rules. The name of the file is not important, as long as it has the extension .rules.
# Generic HID device
ATTR{idProduct}=="04d9", ATTR{idVendor}=="1c40", MODE="0660", GROUP="plugdev"
# Logitech dual action
ATTR{idProduct}=="c216", ATTR{idVendor}=="046d", MODE="0660", GROUP="plugdev"
# Contour design, shuttle pro
ATTR{idProduct}=="0030", ATTR{idVendor}=="0b33", MODE="0660", GROUP="plugdev"
Note - the rules syntax has changed. Use ATTR instead of SYSFS for newer versions of udev. |
# Generic HID device |
In my file, each data line has 4 parts. The first two specify the PID and VID of the USB device that this line applies to. The last 2 parts refer to the commands to run when a device is found. In this case, we set the permissions on the device to 0660 (owner=read/write, group=read/write), and we set the group of the device to plugdev.
The lines beginning with # are comments.
For this file to work, there must also be a group on the system called plugdev, and the user account that runs EMC/LinuxCNC must belong to this group. This can be done with the commands...
sudo addgroup plugdev
sudo addgroup myloginname plugdev
To find the PID and VID of the USB device, run the lsusb command...
frankt@workshoppc:$ lsusb
Bus 004 Device 002: ID 05e3:0606 Genesys Logic, Inc. D-Link DUB-H4 USB 2.0 Hub
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 017: ID 1c40:04d9
Bus 001 Device 016: ID 046d:c216 Logitech, Inc. Dual Action Gamepad
Bus 001 Device 015: ID 046d:c216 Logitech, Inc. Dual Action Gamepad
Bus 001 Device 014: ID 0b33:0030 Contour Design, Inc.
Bus 001 Device 009: ID 413c:2010 Dell Computer Corp.
Bus 001 Device 008: ID 0409:005a NEC Corp.
Bus 001 Device 007: ID 1532:0101
Bus 001 Device 006: ID 0079:0006
Bus 001 Device 005: ID 413c:1003 Dell Computer Corp.
Bus 001 Device 004: ID 05e3:0606 Genesys Logic, Inc. D-Link DUB-H4 USB 2.0 Hub
Bus 001 Device 003: ID 2001:f103 D-Link Corp. [hex]
Bus 001 Device 002: ID 05e3:0606 Genesys Logic, Inc. D-Link DUB-H4 USB 2.0 Hub
Bus 001 Device 001: ID 0000:0000
The pair of hexadecimal numbers are PID:VID. Use these in the .rules file. If you cannot identify your device, you can run lsusb as root to see if that helps. If it doesn't, run lsusb with the device unplugged, then again with the device plugged in to identify the new device.
The rules file will take effect next time the device is plugged in.
There is more information about the rules file in udev(7) man page. The man page for hal_input(1) also has a good write up of USB permissions.
Problem Devices
- Griffin Technologies, Powermate - The LED can't be driven because it uses vendor defined messages to program the LED state. The dial sends timed updates as it is rotated. If the device doesn't move, hidcomp outputs the last movement value, making it look like the device is stuck on.
Known Issues
- When hidconfig is run remotely (using an X terminal), USB devices with high update rates (like the Logitech gamepads which update 100 times per second) the display can lag behind the device motion until it comes to rest.
- There is a known resizing problem on the LCD setup screen. Sometimes the virtual LCD display overlaps the data table and uses 100% of the cpu repainting the overlap. Resizing the window by dragging a corner will stop this.
ToDo List
- When a long operator message is displayed, make it scroll or something so the whole message can be seen.
Change History
1.7 |
|
1.6 | Build for EMC2 2.5. |
1.5 | Build for EMC2 2.4.6. Add checking for version mismatches. |
1.4 | "Reverse Axis" option on a value axis was not working. Now it is. |
1.3 | Add LCD External Access Port to allow external socket interface to LCD display. Also support advanced displays as used in Lathe Pendant. |
1.2 | Update LCD handling to bring in line with GenericHID release. Correctly handle multiple LCDs. Support user defined characters. And MRU list. |
1.1 | Remove need for emc.nml changes if an LCD display isn't being used |
1.0 | Initial Release |