#defines & USB-HID - how to vary the RAWHID_USAGE value so I can identify Teensys?

Status
Not open for further replies.

howiemnet

Active member
#defines & USB-HID - how to vary the RAWHID_USAGE value so I can identify Teensys?

I think this is a kind of compiler question more than anything else: I've got several Teensys connected, and I've got them talking to my Mac by just using the RawHID function:

Code:
RawHID.send( myBuffer, 0 );

Seemingly no need to open or initialise anything on the Teensy - this just immediately works. Super.

The Vendor / Product / Usage page / usage values are set by #defines in ... /hardware/teensy/avr/cores/usb_rawhid/usb_private.h as far as I can tell. I think all I need to do is change the RAWHID_USAGE number to something different on each Teensy (maybe set it with jumpers), and then have my Mac app call
Code:
rawhid_open(...)
with the new value for each Teensy.

Is that an appropriate way to differentiate between different Teensys? Just having each one have a different RAWHID_USAGE value? This is just for my use, not for a product for sale?

But what would be the best way for me to change these values for different sketches?

- Should I put #ifndef / #endif around the #define in the core file, and then #define my own RAWHID_USAGE in my sketch?
- Is there a way to do it that doesn't involve those "core" files - can I copy them into my sketch folder and alter them there instead?
(I hate the idea of having to depend on alterations to files in the Arduino / Teensyduino folder structure as I know I'll forget to do it next time I install new versions of things)
 
Last edited:
You can use the serial number, which is unique and pre-programmed on every Teensy. No need to change anything. This thread (https://forum.pjrc.com/threads/25522-Serial-Number-of-Teensy-3-1) explains where it comes from and how you can read it on the Teensy.

The serial number is part of the USB descriptor and the Mac can retrieve this information the same way it retrieves the usage page. What application are you using on the Mac?
 
I'm writing my own Mac app in Swift. Got it working OK so far (despite some bloody weird Serial issues, hence moving over to USB).

Trouble with using the serial numbers is that it overcomplicates things: if I can control the ID of each Teensy, if I need to swap one out, I can just give it the right firmware, set the jumpers like the old one, and it'll look like the old one to my Mac app.

A bit more background: I'm doing motion control of a camera, so I've got Teensys driving each motor channel (slider / pan / tilt), one controlling a lens autofocus etc. Ideally, I'll just plug them into the Mac, and my app can look at what's connected, and set up the right sliders / sequencer channels on screen. So rather than having to maintain a lookup table on the Mac of serial numbers <--> motion control channels, I'd much rather be able to tell the Teensy what it's controlling (with jumpers, probably, but I could just have a variable somewhere in my Teensy code I could alter just before uploading the code).

Nothing to stop me doing a bit more negotiation when my app starts, I suppose; I could just query the Teensys, get them to respond with their channel types. Just thought I'd found a simpler solution, if only I could control the "addresses" / vendor IDs / usage thingies etc they show up as.
 
I see. So you want to identify different roles.

You COULD do this by changing the product name. There are some things to keep in mind, though:

  • These two threads explain how to do it: https://forum.pjrc.com/threads/23523-Change-device-name/page2?highlight=PRODUCT_NAME and https://forum.pjrc.com/threads/23796-How-to-change-Teensy-3-0-PRODUCT_NAME. Basically, you can either change usb_desc.h, but that would do the change for ALL compiled sketches, as it is part of the shared Arduino library. Better to include a separate .c file in each of your sketches that specifies the changed values.
  • The name must be defined in an array of letters {'U','S','B',' ','N','a','m','e'}, as USB uses 16-bit characters
  • Windows caches the names through its VID, PID and bcdDevice codes. This means, that you must change more than just the name. You could change PID and VID values, but that might interfere with existing software, which might expect specific value. Furthermore, PID and VID are assigned centrally by the USB forum and PJRC paid for the currently used values. You also could change bcdDevice, but that requires more changes in usb_desc.c, as the value has not been defined as customizable.
  • The USB serial number is derived from the MAC address stored in Teensy's flash memory - or vice versa. Another option would be to change the code that derives the serial number from the flash data. That code is in usb_init_serialnumber() in usb_desc.c. You could add a letter or digit that indicates the specific Teensy's role.

On the other hand, I believe that a SINGLE Teensy can easily handle three motors at the same time. It's a matter of code efficiency. Some time ago, I built a flight simulator where a single Teensy 2++ controls dozens or even hundreds of I/O lines - including some motors. If you use stepper motors, check the provided AccelStepper library. It CAN handle more than one stepper.

In general, you should try to avoid the delay() function. It works for simple tasks, but effectively it inhibits concurrent tasks. You don't need it. If you develop your code as a "state machine", you can easily process three motors at the same time. Furthermore, three Teensies require three USB ports - or even a hub. (This tip might kill some of PJRC's revenue, but I'm sure that Paul wants you to use your Teensy efficiently...)

If you still want to use three Teensies, the easiest way might actually be to define an "identification" message that responds with an identifier specifying the Teensy's role.
 
Hehe - I've actually got 6 hooked up at the moment through a hub, but that number changes regularly. Which is why I'm sticking to one Teensy per motor / actuator / lens / light panel at the moment; it means I can plug/unplug channels as I need them. (Plus the Teensys actually fit inside the case of the Leadshine drivers I use, making them a neat monolithic USB-smooth-stepper-driver package, yay woo)

I'll probably implement some sort of ident message I guess... useful to know how to alter the USB stuff though; many thanks for the help.
 
Status
Not open for further replies.
Back
Top