TC4Server: Eagle HAL Device

Dan Newman’s TC4Server turns the TC4 thermocouple board into a USB HID input device that’s compatible with HAL’s hal_input module:

TC4 on ProtoScrewShield on Leonardo

TC4 on ProtoScrewShield on Leonardo

For simplicity (i.e., to avoid writing a special driver), TC4Server misrepresents itself as a nine-axis joystick-like device suited for RC airplane control:

halrun
halcmd: loadusr -W hal_input +A Leonardo
halcmd: show
... snippage ...
Component Pins:
Owner   Type  Dir         Value  Name
     5  s32   OUT          2941  input.0.abs-rudder-counts
     5  s32   IN           4095  input.0.abs-rudder-flat
     5  s32   IN            255  input.0.abs-rudder-fuzz
     5  bit   OUT          TRUE  input.0.abs-rudder-is-neg
     5  bit   OUT         FALSE  input.0.abs-rudder-is-pos
     5  float IN        32767.5  input.0.abs-rudder-offset
     5  float OUT    -0.9102464  input.0.abs-rudder-position
     5  float IN        32767.5  input.0.abs-rudder-scale
     5  s32   OUT          2947  input.0.abs-rx-counts
     5  s32   IN           4095  input.0.abs-rx-flat
     5  s32   IN            255  input.0.abs-rx-fuzz
     5  bit   OUT          TRUE  input.0.abs-rx-is-neg
     5  bit   OUT         FALSE  input.0.abs-rx-is-pos
     5  float IN        32767.5  input.0.abs-rx-offset
     5  float OUT    -0.9100633  input.0.abs-rx-position
     5  float IN        32767.5  input.0.abs-rx-scale
     5  s32   OUT         65535  input.0.abs-ry-counts
     5  s32   IN           4095  input.0.abs-ry-flat
     5  s32   IN            255  input.0.abs-ry-fuzz
     5  bit   OUT         FALSE  input.0.abs-ry-is-neg
     5  bit   OUT          TRUE  input.0.abs-ry-is-pos
     5  float IN        32767.5  input.0.abs-ry-offset
     5  float OUT             1  input.0.abs-ry-position
     5  float IN        32767.5  input.0.abs-ry-scale
     5  s32   OUT         65535  input.0.abs-rz-counts
     5  s32   IN           4095  input.0.abs-rz-flat
     5  s32   IN            255  input.0.abs-rz-fuzz
     5  bit   OUT         FALSE  input.0.abs-rz-is-neg
     5  bit   OUT          TRUE  input.0.abs-rz-is-pos
     5  float IN        32767.5  input.0.abs-rz-offset
     5  float OUT             1  input.0.abs-rz-position
     5  float IN        32767.5  input.0.abs-rz-scale
     5  s32   OUT         65535  input.0.abs-throttle-counts
     5  s32   IN           4095  input.0.abs-throttle-flat
     5  s32   IN            255  input.0.abs-throttle-fuzz
     5  bit   OUT         FALSE  input.0.abs-throttle-is-neg
     5  bit   OUT          TRUE  input.0.abs-throttle-is-pos
     5  float IN        32767.5  input.0.abs-throttle-offset
     5  float OUT             1  input.0.abs-throttle-position
     5  float IN        32767.5  input.0.abs-throttle-scale
     5  s32   OUT          2957  input.0.abs-wheel-counts
     5  s32   IN           4095  input.0.abs-wheel-flat
     5  s32   IN            255  input.0.abs-wheel-fuzz
     5  bit   OUT          TRUE  input.0.abs-wheel-is-neg
     5  bit   OUT         FALSE  input.0.abs-wheel-is-pos
     5  float IN        32767.5  input.0.abs-wheel-offset
     5  float OUT    -0.9097581  input.0.abs-wheel-position
     5  float IN        32767.5  input.0.abs-wheel-scale
     5  s32   OUT          2942  input.0.abs-x-counts
     5  s32   IN           4095  input.0.abs-x-flat
     5  s32   IN            255  input.0.abs-x-fuzz
     5  bit   OUT          TRUE  input.0.abs-x-is-neg
     5  bit   OUT         FALSE  input.0.abs-x-is-pos
     5  float IN        32767.5  input.0.abs-x-offset
     5  float OUT    -0.9102159  input.0.abs-x-position
     5  float IN        32767.5  input.0.abs-x-scale
     5  s32   OUT          2942  input.0.abs-y-counts
     5  s32   IN           4095  input.0.abs-y-flat
     5  s32   IN            255  input.0.abs-y-fuzz
     5  bit   OUT          TRUE  input.0.abs-y-is-neg
     5  bit   OUT         FALSE  input.0.abs-y-is-pos
     5  float IN        32767.5  input.0.abs-y-offset
     5  float OUT    -0.9102159  input.0.abs-y-position
     5  float IN        32767.5  input.0.abs-y-scale
     5  s32   OUT          2940  input.0.abs-z-counts
     5  s32   IN           4095  input.0.abs-z-flat
     5  s32   IN            255  input.0.abs-z-fuzz
     5  bit   OUT          TRUE  input.0.abs-z-is-neg
     5  bit   OUT         FALSE  input.0.abs-z-is-pos
     5  float IN        32767.5  input.0.abs-z-offset
     5  float OUT     -0.910277  input.0.abs-z-position
     5  float IN        32767.5  input.0.abs-z-scale
     5  s32   OUT          2941  input.1.abs-rudder-counts
     5  s32   IN           4095  input.1.abs-rudder-flat
     5  s32   IN            255  input.1.abs-rudder-fuzz
     5  bit   OUT          TRUE  input.1.abs-rudder-is-neg
     5  bit   OUT         FALSE  input.1.abs-rudder-is-pos
     5  float IN        32767.5  input.1.abs-rudder-offset
     5  float OUT    -0.9102464  input.1.abs-rudder-position
     5  float IN        32767.5  input.1.abs-rudder-scale
     5  s32   OUT          2947  input.1.abs-rx-counts
     5  s32   IN           4095  input.1.abs-rx-flat
     5  s32   IN            255  input.1.abs-rx-fuzz
     5  bit   OUT          TRUE  input.1.abs-rx-is-neg
     5  bit   OUT         FALSE  input.1.abs-rx-is-pos
     5  float IN        32767.5  input.1.abs-rx-offset
     5  float OUT    -0.9100633  input.1.abs-rx-position
     5  float IN        32767.5  input.1.abs-rx-scale
     5  s32   OUT         65535  input.1.abs-ry-counts
     5  s32   IN           4095  input.1.abs-ry-flat
     5  s32   IN            255  input.1.abs-ry-fuzz
     5  bit   OUT         FALSE  input.1.abs-ry-is-neg
     5  bit   OUT          TRUE  input.1.abs-ry-is-pos
     5  float IN        32767.5  input.1.abs-ry-offset
     5  float OUT             1  input.1.abs-ry-position
     5  float IN        32767.5  input.1.abs-ry-scale
     5  s32   OUT         65535  input.1.abs-rz-counts
     5  s32   IN           4095  input.1.abs-rz-flat
     5  s32   IN            255  input.1.abs-rz-fuzz
     5  bit   OUT         FALSE  input.1.abs-rz-is-neg
     5  bit   OUT          TRUE  input.1.abs-rz-is-pos
     5  float IN        32767.5  input.1.abs-rz-offset
     5  float OUT             1  input.1.abs-rz-position
     5  float IN        32767.5  input.1.abs-rz-scale
     5  s32   OUT         65535  input.1.abs-throttle-counts
     5  s32   IN           4095  input.1.abs-throttle-flat
     5  s32   IN            255  input.1.abs-throttle-fuzz
     5  bit   OUT         FALSE  input.1.abs-throttle-is-neg
     5  bit   OUT          TRUE  input.1.abs-throttle-is-pos
     5  float IN        32767.5  input.1.abs-throttle-offset
     5  float OUT             1  input.1.abs-throttle-position
     5  float IN        32767.5  input.1.abs-throttle-scale
     5  s32   OUT          2957  input.1.abs-wheel-counts
     5  s32   IN           4095  input.1.abs-wheel-flat
     5  s32   IN            255  input.1.abs-wheel-fuzz
     5  bit   OUT          TRUE  input.1.abs-wheel-is-neg
     5  bit   OUT         FALSE  input.1.abs-wheel-is-pos
     5  float IN        32767.5  input.1.abs-wheel-offset
     5  float OUT    -0.9097581  input.1.abs-wheel-position
     5  float IN        32767.5  input.1.abs-wheel-scale
     5  s32   OUT          2942  input.1.abs-x-counts
     5  s32   IN           4095  input.1.abs-x-flat
     5  s32   IN            255  input.1.abs-x-fuzz
     5  bit   OUT          TRUE  input.1.abs-x-is-neg
     5  bit   OUT         FALSE  input.1.abs-x-is-pos
     5  float IN        32767.5  input.1.abs-x-offset
     5  float OUT    -0.9102159  input.1.abs-x-position
     5  float IN        32767.5  input.1.abs-x-scale
     5  s32   OUT          2942  input.1.abs-y-counts
     5  s32   IN           4095  input.1.abs-y-flat
     5  s32   IN            255  input.1.abs-y-fuzz
     5  bit   OUT          TRUE  input.1.abs-y-is-neg
     5  bit   OUT         FALSE  input.1.abs-y-is-pos
     5  float IN        32767.5  input.1.abs-y-offset
     5  float OUT    -0.9102159  input.1.abs-y-position
     5  float IN        32767.5  input.1.abs-y-scale
     5  s32   OUT          2940  input.1.abs-z-counts
     5  s32   IN           4095  input.1.abs-z-flat
     5  s32   IN            255  input.1.abs-z-fuzz
     5  bit   OUT          TRUE  input.1.abs-z-is-neg
     5  bit   OUT         FALSE  input.1.abs-z-is-pos
     5  float IN        32767.5  input.1.abs-z-offset
     5  float OUT     -0.910277  input.1.abs-z-position
     5  float IN        32767.5  input.1.abs-z-scale

... snippage ...
Parameters:
Owner   Type  Dir         Value  Name
     5  s32   RO          65535  input.0.abs-rudder-max
     5  s32   RO              0  input.0.abs-rudder-min
     5  s32   RO          65535  input.0.abs-rx-max
     5  s32   RO              0  input.0.abs-rx-min
     5  s32   RO          65535  input.0.abs-ry-max
     5  s32   RO              0  input.0.abs-ry-min
     5  s32   RO          65535  input.0.abs-rz-max
     5  s32   RO              0  input.0.abs-rz-min
     5  s32   RO          65535  input.0.abs-throttle-max
     5  s32   RO              0  input.0.abs-throttle-min
     5  s32   RO          65535  input.0.abs-wheel-max
     5  s32   RO              0  input.0.abs-wheel-min
     5  s32   RO          65535  input.0.abs-x-max
     5  s32   RO              0  input.0.abs-x-min
     5  s32   RO          65535  input.0.abs-y-max
     5  s32   RO              0  input.0.abs-y-min
     5  s32   RO          65535  input.0.abs-z-max
     5  s32   RO              0  input.0.abs-z-min
     5  s32   RO          65535  input.1.abs-rudder-max
     5  s32   RO              0  input.1.abs-rudder-min
     5  s32   RO          65535  input.1.abs-rx-max
     5  s32   RO              0  input.1.abs-rx-min
     5  s32   RO          65535  input.1.abs-ry-max
     5  s32   RO              0  input.1.abs-ry-min
     5  s32   RO          65535  input.1.abs-rz-max
     5  s32   RO              0  input.1.abs-rz-min
     5  s32   RO          65535  input.1.abs-throttle-max
     5  s32   RO              0  input.1.abs-throttle-min
     5  s32   RO          65535  input.1.abs-wheel-max
     5  s32   RO              0  input.1.abs-wheel-min
     5  s32   RO          65535  input.1.abs-x-max
     5  s32   RO              0  input.1.abs-x-min
     5  s32   RO          65535  input.1.abs-y-max
     5  s32   RO              0  input.1.abs-y-min
     5  s32   RO          65535  input.1.abs-z-max
     5  s32   RO              0  input.1.abs-z-min
... snippage ...

Dan’s program assigns the outputs thusly:

  • Wheel – ambient temperature as measured on TC4 board
  • X Y Z Rudder – thermocouples – channels 1 through 4
  • RX RY RZ  Throttle – thermistors – channels 5 through 8

I created a huge Eagle device that encapsulates the whole thing. A simple demo schematic includes the constants that make the temperatures come out in °C:

TC4Server - Eagle Schematic

TC4Server – Eagle Schematic

That picture produces this HAL file:

# HAL config file automatically generated by Eagle-CAD ULP:
# [/mnt/bulkdata/Project Files/eagle/ulp/hal-write-2.5.ulp]
# (C) Martin Schoeneck.de 2008
# Charalampos Alexopoulos 2011
# Mods Ed Nisley KE4ZNU 2010 2013
# Path        [/mnt/bulkdata/Project Files/eagle/projects/LinuxCNC for M2/]
# ProjectName [LinuxCNC M2 - TC4Server Test]
# File name   [/mnt/bulkdata/Project Files/eagle/projects/LinuxCNC for M2/TC4Server.hal]
# Created     [20:03:16 03-Jun-2013]

####################################################
# Load realtime and userspace modules
loadusr -W hal_input -A +Leonardo
loadrt threads name1=servo-thread period1=1000000
loadrt constant        count=4
loadrt conv_float_s32        count=2

####################################################
# Hook functions into threads
addf constant.0        servo-thread
addf constant.1        servo-thread
addf constant.2        servo-thread
addf constant.3        servo-thread
addf conv-float-s32.0        servo-thread
addf conv-float-s32.1        servo-thread

####################################################
# Set parameters

####################################################
# Set constants
setp constant.0.value    10
setp constant.1.value    2732
setp constant.2.value    0
setp constant.3.value    0

####################################################
# Connect Modules with nets
net n_2 constant.2.out conv-float-s32.1.in
net n_3 constant.3.out conv-float-s32.0.in
net tc4-ambient input.0.abs-wheel-position
net tc4-flat input.0.abs-wheel-flat input.0.abs-x-flat input.0.abs-y-flat input.0.abs-z-flat input.0.abs-rudder-flat input.0.abs-rx-flat input.0.abs-ry-flat input.0.abs-rz-flat input.0.abs-throttle-flat conv-float-s32.1.out
net tc4-fuzz input.0.abs-throttle-fuzz input.0.abs-rz-fuzz input.0.abs-ry-fuzz input.0.abs-rx-fuzz input.0.abs-rudder-fuzz input.0.abs-z-fuzz input.0.abs-y-fuzz input.0.abs-x-fuzz input.0.abs-wheel-fuzz conv-float-s32.0.out
net tc4-offset input.0.abs-wheel-offset input.0.abs-x-offset input.0.abs-y-offset input.0.abs-z-offset input.0.abs-rudder-offset input.0.abs-rx-offset input.0.abs-ry-offset input.0.abs-rz-offset input.0.abs-throttle-offset constant.1.out
net tc4-scale input.0.abs-wheel-scale input.0.abs-x-scale input.0.abs-y-scale input.0.abs-z-scale input.0.abs-rudder-scale input.0.abs-rx-scale input.0.abs-ry-scale input.0.abs-rz-scale input.0.abs-throttle-scale constant.0.out
net tcouple-1 input.0.abs-x-position
net tcouple-2 input.0.abs-y-position
net tcouple-3 input.0.abs-z-position
net tcouple-4 input.0.abs-rudder-position
net tmistor-5 input.0.abs-rx-position
net tmistor-6 input.0.abs-ry-position
net tmistor-7 input.0.abs-rz-position
net tmistor-8 input.0.abs-throttle-position

Fire it up with halrun to see the temperatures (alphabetically by the pin name):

halrun -I -f TC4Server.hal
halcmd: start
halcmd: show pin *position
Component Pins:
Owner   Type  Dir         Value  Name
     5  float OUT          20.9  input.0.abs-rudder-position ==> tcouple-4
     5  float OUT          21.5  input.0.abs-rx-position ==> tmistor-5
     5  float OUT        6280.3  input.0.abs-ry-position ==> tmistor-6
     5  float OUT        6280.3  input.0.abs-rz-position ==> tmistor-7
     5  float OUT        6280.3  input.0.abs-throttle-position ==> tmistor-8
     5  float OUT          22.5  input.0.abs-wheel-position ==> tc4-ambient
     5  float OUT            21  input.0.abs-x-position ==> tcouple-1
     5  float OUT            21  input.0.abs-y-position ==> tcouple-2
     5  float OUT          20.8  input.0.abs-z-position ==> tcouple-3

The sensors do not correspond to the picture at the top: only the first thermocouple and first thermistor are connected ; the ADC returns bogus data for disconnected inputs, which means you must be careful about tightening the wires and checking the result. Dan’s firmware has the ability to disable unused sensors, in which case you get a huge value; when used for heater control, a sensor failing high means the heater will turn off, but, should you use this gadget in a freezer, you might want them to fail low (so modify the code for your own use).

The ambient temperature reported for the board runs 1 or 2 °C higher than the actual ambient air temperature, probably because of all those components doing useful things up close to the sensor chip. That particular ambient temperature serves as the cold junction reference for the thermocouples; the other temperatures don’t change very much as the board warms up, so it’s all good.

Remember to issue the start command in halrun, because otherwise nothing changes.

Also remember that you must configure TC4Server with the thermistor characteristics before you use it as a hal_input device.

About these ads

,