PDA

View Full Version : Many axis joystick



PaulStoffregen
05-13-2013, 09:36 PM
Moderator Edit: the latest many-axis source code is attached to reply #36 (http://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942).

------------

Teensyduino currently implements a 6 axis joystick. When I wrote the Teensy 3.0 version, I briefly tried 8 axes, but ran into trouble. Windows seemed to detect the device, but it would not show up in the Joystick control panel as 8 axes. With limited time, I reverted to the 6 axis HID descriptor from Teensy 2.0.

Robert Ferguson send me a link to this project which seems to work with 7 axes.

http://www.imaginaryindustries.com/blog/?p=80

This product implements 8 and has screenshots of the Windows control panel.

http://www.leobodnar.com/products/BU0836/

This forum topic is my reminder to again investigate 8 (or more) axis support. I need the actual HID descriptors from these devices, or some other way of figuring out how to write the descriptors so Windows will recognize the device and show it properly.

I'm also hoping anyone interested in many-asix joystick support will subscribe to this thread. I *really* need your help with testing, when I work on this. In fact, I probably will wait to work on it until at least a couple people have volunteered here to help test.

RobF
05-13-2013, 11:46 PM
Here is another project using an Arduino that supports 40 buttons and 8 axes... HID descriptor is listed on the project web page at http://hunt.net.nz/users/darran/weblog/15f92/:

HID Descriptor

This is the HID descriptor for the joystick. You can learn more about them from the USB HID Usage Tables.




0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */

0xa1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */

/* 8 axes, signed 16 bit resolution, range -32768 to 32767 (16 bytes) */
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x32, /* Usage (Analog1) */
0x09, 0x33, /* Usage (Analog2) */
0x09, 0x34, /* Usage (Analog3) */
0x09, 0x35, /* Usage (Analog4) */
0x09, 0x36, /* Usage (Analog5) */
0x09, 0x37, /* Usage (Analog6) */
0x16, 0x00, 0x80, /* Logical Minimum (-32768) */
0x26, 0xff, 0x7f, /* Logical Maximum (32767) */
0x75, 16, /* Report Size (16) */
0x95, 8, /* Report Count (8) */
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
0xc0, /* End Collection */

/* 40 buttons, value 0=off, 1=on (5 bytes) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 1, /* Usage Minimum (Button 1) */
0x29, 40, /* Usage Maximum (Button 40) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 1, /* Report Size (1) */
0x95, 40, /* Report Count (40) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0xc0 /* End Collection */

lil_head
05-15-2013, 05:24 AM
I'm very interested in this Paul. I've been trying to add more axis (throttle type not x,y,z) and have been toying with descriptors and the like but I haven't been able to write a HID for it as I don't seem to have the software capable. The hid tool from USB.org always crashes when I try to save one. I'm a nooby but still trying and willing to assist and test.
I have 2 teensy 3's and a setup with 12 or 16 pots so I can easily test 8 plus axis.

I'll check out those link provided too.

lil_head
05-16-2013, 05:27 AM
Other desc examples I've looked at only call 1 each of a number of types of axis like Zr, Yr, slider, dial, knob, throttle etc. (Like the lufa example above) Where as I've been trying to include multiples of one type or 2 types only, like slider and throttle which seems to be less successful.
I edited to include a similar setup as the lufa eg. And managed to see the 8 axis in windows but haven't tested properly yet as nothing was connected to my board.

PaulStoffregen
05-16-2013, 06:13 AM
I wonder if more than 8 can work in Windows?

Even if only 8 show up in the control panel, can Windows give more to programs reading the joystick?

lil_head
05-20-2013, 12:01 AM
I'm using the very basic and free version of visual studio to edit the descriptor and arduino to program the joystick. I can change the desc. file all day long and see various different results but do i need to change any other files? What files get loaded to the chip other than the descriptor and .ino. do new axis need to be defined in USB_joystick.c or .h? I'm kinda stuck at this point. Also in desc should we using 8 16 or 32 bit ints for logical min and Max etc.

CharlieSears
06-03-2013, 08:06 PM
I wonder if more than 8 can work in Windows?

Even if only 8 show up in the control panel, can Windows give more to programs reading the joystick?

I'm working on a 16-20 bit joystick interface.

I had (IIRC) 9 axes at one point in my testing but never checked the windows control panel. I had X, Y, Z, Rx, Rz and 4 sliders.

I'll play with my HID Descriptor tonight and see if it 1, actually works and 2, what happens when there are that many axes available to windows.

PaulStoffregen
06-03-2013, 08:49 PM
I had (IIRC) 9 axes at one point in my testing but never checked the windows control panel. I had X, Y, Z, Rx, Rz and 4 sliders.

What software are you using to test the joystick?

CharlieSears
06-03-2013, 08:53 PM
What software are you using to test the joystick?

I was using iRacing, a simulation racing game.

When calibrating wheels/pedals it displays the current device being tracked (based on largest diff in min/max registered across all device axes) min, max, and current vals. It also lists the device number and axis number.

I had a 9 axis HID being read by windows, I'm not positive I could use all 9 as I only tested 1 as a proof of concept.

Testing 1st 20 bit axis on the 2nd usb joystick device registered by windows.
541

I'll get that device up and running again, verify I can use all the axes and post my HID Descriptor. I'm at work right now.

CharlieSears
06-03-2013, 10:10 PM
Well, it doesn't error when there are more than 8 axes available at any point in development. However the axes are not shown in the Windows descriptor nor are their values visible in any way I can test. I can only access up to the 8th axis.

My Descriptor
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x18, // REPORT_COUNT (24)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x18, // USAGE_MAXIMUM (Button 24)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x08, // REPORT_COUNT (8)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x09, 0x40, // USAGE (Vx)
0x09, 0x41, // USAGE (Vy)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x36, // USAGE (Slider)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION


Windows 'joy.cpl':
542

lil_head
06-04-2013, 12:05 AM
Did you have to program these in arduino aswell? If so, how did you reference the extra axis?

RobF
09-05-2013, 06:10 PM
Here is the device descriptor for the BU0836A:

Connection Status Device connected
Current Configuration 1
Speed Full (12 Mbit/s)
Device Address 1
Number Of Open Pipes 1

Device Descriptor BU0836A Interface
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 idVendor 2 16C0h VOTI
10 idProduct 2 05BAh
12 bcdDevice 2 0122h 1.22
14 iManufacturer 1 01h "Leo Bodnar"
15 iProduct 1 02h "BU0836A Interface"
16 iSerialNumber 1 03h "B31071"
17 bNumConfigurations 1 01h

Configuration Descriptor 1 Bus Powered, 100 mA
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 0022h
4 bNumInterfaces 1 01h
5 bConfigurationValue 1 01h
6 iConfiguration 1 00h
7 bmAttributes 1 80h Bus Powered
4..0: Reserved ...00000
5: Remote Wakeup ..0..... No
6: Self Powered .0...... No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0) 1.......
8 bMaxPower 1 32h 100 mA

Interface Descriptor 0/0 HID, 1 Endpoint
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 01h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 00h

HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0110h 1.10
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0067h 103 bytes

Endpoint Descriptor 81 1 In, Interrupt, 4 ms
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0020h 32 bytes
6 bInterval 1 04h 4 ms

Interface 0 HID Report Descriptor Joystick
Item Tag (Value) Raw Data
Usage Page (Generic Desktop) 05 01
Usage (Joystick) 09 04
Collection (Application) A1 01
Usage (Pointer) 09 01
Collection (Physical) A1 00
Usage (X) 09 30
Usage (Y) 09 31
Usage (Z) 09 32
Usage (Rx) 09 33
Usage (Ry) 09 34
Usage (Rz) 09 35
Usage (Dial) 09 37
Usage (Slider) 09 36
Logical Minimum (0) 15 00
Logical Maximum (4095) 26 FF 0F
Report Size (16) 75 10
Report Count (8) 95 08
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
End Collection C0
Usage Page (Button) 05 09
Usage Minimum (Button 1) 19 01
Usage Maximum (Button 32) 29 20
Logical Minimum (0) 15 00
Logical Maximum (1) 25 01
Report Size (1) 75 01
Report Count (32) 95 20
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
Usage Page (Generic Desktop) 05 01
Usage (Hat Switch) 09 39
Logical Maximum (7) 25 07
Physical Minimum (0) 35 00
Physical Maximum (315) 46 3B 01
Unit Exponent (0) 55 00
Unit (Eng Rot: deg^4) 65 44
Report Size (4) 75 04
Report Count (1) 95 01
Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit) 81 42
Unit (None) 65 00
Report Count (1) 95 01
Report Size (4) 75 04
Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03
Collection (Logical) A1 02
Usage Page (Vendor-Defined 1) 06 00 FF
Usage (Vendor-Defined 1) 09 01
Logical Minimum (0) 15 00
Logical Maximum (255) 26 FF 00
Report Size (8) 75 08
Report Count (17) 95 11
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) B1 02
End Collection C0
End Collection C0

RobF
09-08-2013, 04:37 PM
OK, i want to work on this in earnest now, but I'm having trouble getting started...
I have built a prototype of my cockpit controller with 36 digital inputs and 8 analog controls, but even after reading the Teensy documentation on the main website and perusing these forums for hours, I haven't a clue how to edit the firmware for this teensy 2++. I see how to edit/load/run sketches, but obviously there's a lot more underlying code that handles the hardware. For example, where do I find the USB descriptor and how do I change it? There are obviously libraries that are being called when a sketch is compiled, but where are they located (Ubuntu)?

neocalm
12-08-2013, 12:47 AM
I'm also interested in an updated 7-axis or 8-axis Joystick for Teensy, and can help debug.

buffington
01-16-2014, 05:28 PM
@RobF - my knowledge on this is still forming since I've just started trying to sort this all out myself. But I'll describe what I do know.

I'm not sure of the exact location on Ubuntu, but the location of the Teensy libs might follow a similar pattern as OSX or Windows.

On OSX you can find all of the Teensy libraries here:



/Applications/Arduino.app/Contents/Resources/Java/hardware/teensy/cores


On Windows:


/Program Files (x86)/Arduino/hardware/teensy/cores


Assuming you have the latest Teensyduino installed you'll have the following directories:



teensy
teensy3
usb_disk
usb_flightsim
usb_hid
usb_midi
usb_rawhid
usb_serial
usb_serial_hid


Depending on the board (Teensy 3.x vs Teensy 2, etc) and device USB type (Serial, Serial+Joystick, etc), you'll find what you're looking for in different places. You mentioned the Teensy 2.0++. Assuming you're creating a "Serial + Keyboard + Mouse + Joystick" device, you'll want to look at these files (starting at [root Arduino path]/hardware/teensy/cores):



usb_serial_hid/usb_private.h
usb_serial_hid/usb.c


In usb_private.h you can adjust the device name, manufacturer name, serial number, vendor ID and product ID.
In usb.c you'll find all the HID report descriptions. There's a ton of stuff to tweak here. I learned a lot about USB HID Reports from Frank Zhao. Before you touch anything in usb.c make sure you read his tutorial on HID reports (http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/).

You'll probably want to pore over the other files within usb_serial_hid as there's more to tweaking stuff than the two files I mentioned.

buffington
01-16-2014, 05:36 PM
Just ran across this - libraries for making an 8 axis (16 bits resolution per axis), 40 button joystick with an Arduino Uno:

https://github.com/harlequin-tech/arduino-usb

Would this be portable to Teensy?

bmsi
01-16-2014, 08:00 PM
I can help with the usb interface. I have a hardware monitor that can capture the initialization sequence.

recoilfx
02-08-2014, 08:29 PM
Hi, I've managed to get the 16 bit 8 axes + 4 hats working with Teensy 3.0.

Attached are the 4 changed files from the teensy3 dir. I'm new, so I'm not sure where i could submit patches?

Couple notes: instead of 16 bytes, now the JOYSTICK_SIZE is 24, and the usb_joystick_data has 5 array items. Packet is being sent at 22 bytes (176bits).
The breakdown of the packet is 32bit(buttons) + 16 bit (4 Hats) + 128 bits (8 axes). The extra 3 hats will not be visible to Windows default game controller panel, but is visible to joystick testers such as the one from: http://www.planetpointy.co.uk/joystick-test-application/

Here is the new HID descriptor:


static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 0x08, // Report Count (8)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0xC0 // End Collection
};


Old packet structure:
1403


New packet structure:
1404

Changed files from hardware/teensy/cores/teensy3
1407

Pointy
02-08-2014, 09:37 PM
Hi, I've managed to get the 16 bit 8 axes + 4 hats working with Teensy 3.0.

Attached are the 4 changed files from the teensy3 dir. I'm new, so I'm not sure where i could submit patches?

Couple notes: instead of 16 bytes, now the JOYSTICK_SIZE is 24, and the usb_joystick_data has 5 array items. Packet is being sent at 22 bytes (176bits).
The breakdown of the packet is 32bit(buttons) + 16 bit (4 Hats) + 128 bits (8 axes). The extra 3 hats will not be visible to Windows default game controller panel, but is visible to joystick testers such as the one from: http://www.planetpointy.co.uk/joystick-test-application/

Here is the new HID descriptor:


static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 0x08, // Report Count (8)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0xC0 // End Collection
};


Old packet structure:
1403


New packet structure:
1404

Changed files from hardware/teensy/cores/teensy3
1407

Nice work recoilfx.

I have been messing about with the RawInput today, I am interested to see if extra axis are supported. The obvious limitation are the usage tables, there is still the same 6 axes as in DirectX ...

X, Y, Z, Rx, Ry & Rz

It may be though, that you can then have any number of Sliders, Dials, Wheels and Hat Switches up to the maximum packet size.

However not all games would support these, especially if they just rely on Direct Input.

I still have a little way to go but have some basic code working, I just have a few bugs to iron out. I will then try to incorporate it into the Joystick test application.

Regards,

Les

PaulStoffregen
02-08-2014, 11:14 PM
It may be though, that you can then have any number of Sliders, Dials, Wheels and Hat Switches up to the maximum packet size.


I started fiddling with code here to add 12 sliders, after the 6 axes. But it's kind of pointless if no software on Windows can read it...

Pointy
02-09-2014, 09:42 AM
I started fiddling with code here to add 12 sliders, after the 6 axes. But it's kind of pointless if no software on Windows can read it...

To be honest I would be very surprised if games just relied upon Direct Input for game controllers, I am involved in an alpha test of a commercial game so maybe I'll ask the developers.

If you have the code done for 12 sliders then please either post it here or email me a copy so I can test it with RawInput.

Regards,

Les

PaulStoffregen
02-09-2014, 07:16 PM
If you have the code done for 12 sliders then please either post it here or email me a copy so I can test it with RawInput.


It wasn't done, but I wrapped it up this morning and tested on Linux. I ended up with 128 buttons, 6 axes, 15 sliders, and 4 hat switches with 1 degree resolution.

Here's a screenshot with "jstest-gtk". Linux considers each hat switch as 2 axes. I don't know if the 64 button limit is coming from jstest or the Linux kernel.

1414
(click for full size)

Here's the code, and a simple test sketch.

PaulStoffregen
02-09-2014, 07:18 PM
All 6 axes and 15 sliders are 16 bits. In the test sketch, I just multiplied analogRead() output by 16.

Linux seems to be confused by the hat switches offering more than 8 directions. If Windows can't use them either, I'll change them back to 4 bits and use the extra space to add a couple more sliders (as if 15 isn't enough....)

Pointy
02-09-2014, 09:27 PM
I can't get it to work on window 7 here. Doesn't show up as a game controller, and trying to access it through rawInput is showing some weird results.(My rawInput code is far from complete, so may be bugged)

I need to have a proper play when I get some more time.

Regards,

Les

PaulStoffregen
02-10-2014, 03:30 PM
I tried with Windows 7 and fiddled with the report descriptor until Windows recognized it as a joystick.

This one has 128 buttons, 6 axes, 17 sliders, and 4 hat switches.

Pointy
02-10-2014, 06:04 PM
I tried with Windows 7 and fiddled with the report descriptor until Windows recognized it as a joystick.

This one has 128 buttons, 6 axes, 17 sliders, and 4 hat switches.

Nice work Paul, I wondered last night when I look at the descriptor if it was the usage min and max windows didn't like.

It's working here now but..

Only showing 1 hat under DirectX, but interestingly it is showing 128 buttons and 23 axis!

I just need to figure out how to access the extra sliders.

Regards,

Les

Pointy
02-10-2014, 06:29 PM
After another quick play it seems I am not getting any data for hat or sliders through DirectX.

Regards,

Les

PaulStoffregen
02-10-2014, 07:13 PM
Are any gamers or flight sim people following this thread? Can anyone test and see if those programs can access the many extra sliders?

Pointy
02-10-2014, 07:29 PM
rawInput is seeing 17 Sliders but still only 1 hat.

Regards,

Les

PaulStoffregen
02-10-2014, 07:38 PM
Linux reports 8 axes corresponding to the 4 hats.

Pointy
02-10-2014, 07:58 PM
Fixed Hats by tweaking descriptor...

static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x80, // Report Count (128)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x80, // Usage Maximum (Button #128)
0x81, 0x02, // Input (variable,absolute)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 23, // Report Count (23)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (20)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (20)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (20)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x65, 0x14, // Unit (20)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (variable,absolute,null_state)
0xC0 // End Collection
};

Regards,

Les

PaulStoffregen
02-10-2014, 10:07 PM
Oh, opps, I only put the usage number in 1 time. It should not be necessary to duplicate that whole section 4 times.

Does this work?



static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x80, // Report Count (128)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x80, // Usage Maximum (Button #128)
0x81, 0x02, // Input (variable,absolute)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 23, // Report Count (23)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0xC0 // End Collection
};

Pointy
02-10-2014, 11:10 PM
Oh, opps, I only put the usage number in 1 time. It should not be necessary to duplicate that whole section 4 times.

Does this work?



static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x80, // Report Count (128)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x80, // Usage Maximum (Button #128)
0x81, 0x02, // Input (variable,absolute)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 23, // Report Count (23)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0xC0 // End Collection
};


That fixes it more elegantly than my solution, but at least it showed you the way ;)

So now I can see all buttons, axis, sliders and hats, I am just having trouble reading them all.

In DirectX I can read the 6 normal axes, all 128 buttons and the 4 Hats, I can't seem to read any sliders though.

My rawInput code is still bugged so not sure yet.

Regards,

Les

PaulStoffregen
02-10-2014, 11:31 PM
Are you able to see 2 of the sliders in directx? It might be giving you the last 2, rather than the first 2.

Pointy
02-11-2014, 12:39 AM
Are you able to see 2 of the sliders in directx? It might be giving you the last 2, rather than the first 2.

Man it must be tough being right all the time ;)

Good call.

There was also a bug in my DirectX code for sliders anyway, which didn't help.

So now in DirectX I can read the 6 normal axes, all 128 buttons, 4 Hats, and 2 sliders (It does know there are 17 sliders present though, it just doesn't want to give me any data for them)

Regards,

Les

PaulStoffregen
02-11-2014, 05:46 PM
In case anyone else is following this Joystick thread, here's the latest code for Teensy 3.1. Just replace these 4 files in hardware/teensy/cores/teensy3 and your joystick will become 128 buttons, 6 axes, 17 sliders and 4 hats.

PaulStoffregen
02-11-2014, 06:08 PM
Tried the test program just now, version 091. It crashes on startup on my Win 7 test machine. :(

Edit: I tried this joystick test (http://code.google.com/p/roboticsby/wiki/JoystickTest) and also this one (http://fluxrobotics.blogspot.com/2011/07/joystick-test-application.html). Neither is able to recognize this huge joystick.

Edit again: I retested on Linux. "jstest-gtk /dev/input/js1" is able to recognize it, but only 64 buttons, and of course the 4 hats show up as the last 8 axes.

1432
(click for full size)

geekguy
02-11-2014, 09:05 PM
Are any gamers or flight sim people following this thread? Can anyone test and see if those programs can access the many extra sliders?
I don't know about these sorts, but an avid robot builder is now following this. :) I want to create a remote (wireless, of course) long range robot controller. There are many things I am going to need to have easy control of. I need to get some components (sliders, pots, joysticks, etc.), and a couple more Teensy3.1, so I can play along with you guys. :)

8-Dale

PaulStoffregen
02-12-2014, 12:01 PM
So now in DirectX I can read the 6 normal axes, all 128 buttons, 4 Hats, and 2 sliders (It does know there are 17 sliders present though, it just doesn't want to give me any data for them)


Any chance you could post the latest version? I'd love to give it a try.

I'm considering trying to bring in a wider audience of people who might be interested and who might be able to help with testing what software can and can't work with this extreme joystick. Maybe Hack-a-Day would find this interesting?

I had hoped to publish this huge joystick in Teensyduino 1.18, but obviously more work is needed to figure out what software is compatible. It can't replace the normal joystick that works with pretty much all PC and Mac software, but if we can at least get a reliable test program on Windows, I'd love to add this as a new Tools > USB Type option in version 1.19.

Oh, also, here's a photo of the breakout board I'm using.

1434
(click for full size)

It has "only" 14 pots and 34 sets of buttons... not nearly enough for all this joystick's functionality. Maybe I ought to make one with 23 pots and 128 buttons, using some sort of mux scheme to read them all?

locodog
02-13-2014, 12:45 AM
23 pots and 128 buttons would be great Paul, I would like to make a HID Dj controller (as far as my music program is concerned any HID is ok) and this would be a great starting point, (my minimum want is 24 pots, my maximum would be 48 pots)

This may become the standard for DIY HID DJ controllers.

This will be open sauce won't it? *crosses fingers*

PaulStoffregen
02-13-2014, 01:04 AM
This will be open sauce won't it? *crosses fingers*

The source code is attached to reply #36. Just scroll up and grab it. ;)

To use it, first get Arduino 1.0.5. Then install Teensyduino 1.18-rc4 (http://forum.pjrc.com/threads/25106-Teensyduino-1-18-Release-Candidate-4-Available). The replace 4 files in hardware/teensy/cores/teensy3 with the copies from reply #36. Open Arduino, and select Teensy 3.1 from Tools > Boards, and then Keyboard+Mouse+Joystick from Tools > USB Type.

Then open the example (also on reply #36) and click Upload to program it to your Teensy 3.1. You'll need to connect pots and buttons to the pins. Edit the example to your liking.

PaulStoffregen
02-13-2014, 01:16 AM
More sliders could be possible if the resolution were decreased. One of the common requests, after simply having more buttons and sliders, has been higher resolution. The existing joystick uses 10 bits. This extreme joystick uses 16 bit on all axes and sliders, to try to satisfy those requests.

Reducing to only 12 bits would allow 22 sliders. But are 5 more sliders worth the loss of resolution on all of them?

If your software could use 2 of these HID devices, that might be the best way to get to your goal.

Either way, can you give this a try with your DJ software and let me know if it works? I'd also like to know more about this software, if you can explain it. At this point, the extreme joystick appears to be working, but the main thing holding it back is testing what software can actually use it. So far, it's looking like "jstest" on Linux is the only program, and even that sees only 64 of the 128 buttons.

locodog
02-13-2014, 03:23 PM
Thanks for the reply Paul

I can't help just yet as I don't have the components, I bought a Ardiuno at xmas and have been tinkering with other open source projects ( like Unojoy (http://code.google.com/p/unojoy/)), the best I have managed is the standard limit for the microcontroller (6 pots @8bit, and a few buttons I have hardly any components)
So now I'm looking round at different projects before I buy big, (there is one guy using PICs for a HID project [impressive but no code yet], and there are several ardiuno MIDI projects) More than anything I'm looking for simplicity, Electronics is pretty easy for me but I am a coding noob. If teensy offers simplicity I'm sold.

As for resolution (a general DJ's perspective), 10 bit is absolutely fine for sliders/pots, (0.1% of any given slider) 8 bit is serviceable too (this matches the MIDI protocol) as for disc control (for scratching) 16 bit would be perfect but I can't see 12 bit being that bad (although if you want perfect scratching buy a turntable [personal perspective])


Regarding the DJ program (Virtual DJ (http://www.virtualdj.com/wiki/Controller_Definition.html)), it is quite open ended, you use this
HID trace program (http://www.virtualdj.com/download/hidtrace.exe) (it is free to download and requires no install, this might be of some use for you)
to find which bit/bits/nibble/byte/short each button or axis controls in the HID report, then in a separate xml file you define a name for any given bit-short, further to that in another xml file you map a command to a defined name.

Anyway I'm waffling, I'll be in contact once I've been shopping.

*Edit*

Instead of using hardware for testing input why not write a sketch to simulate input (forgive me if this is patronising, I'm just sharing a thought)

PaulStoffregen
02-13-2014, 03:55 PM
The example sketch does rotate the hat switches automatically. More of that could be done on the other controls. I just haven't put the time into that, especially since I already had that test board sitting here (and especially since my main focus is wrapping up the 1.18 release and getting back to working on the audio library). The test board was built long before this effort on the joystick.

For DJ controllers, which have been very popular Teensy-based projects, most people have used the USB MIDI (http://www.pjrc.com/teensy/td_midi.html) option. It's in the Tools > USB Type menu.

Pointy
02-13-2014, 07:56 PM
Any chance you could post the latest version? I'd love to give it a try.

I am still working on it, and I have been really struggling with the rawInput side. In actual fact rawInput is essentially rawHid as you have use the HidClass After several re-writes, I have the bulk of the code working, I just need to parse the actual report into the joystick values.

I don't really understand what Bitfield means here (http://msdn.microsoft.com/en-us/library/windows/hardware/ff539832(v=vs.85).aspx). For the axis and sliders it is always 0x02 but for the hats it's 0x42. This last part should be simple but my brain is frazzled, and math is not my strong point. I am sure I will get there in the end though.

Anyway I can pretty much confirm that rawInput would access all of the features of the Extreme Joystick. The device will work in DirectX, but you will just be limited to 2 sliders. Unfortunately MS hard coded the number of sliders you can access, and even though it knows there are 17 of them, it will only allow you to retrieve the data for the last 2. Another slight drawback is that DirectX doesn't seem to like lots of things changing at once. As part of my testing I was alternating between switching the 1st 64 buttons and the 2nd 64 on and off. DirectX only showed the last 15 or so changing, where as rawInput showed them all.

Regards,

Les

locodog
02-13-2014, 08:41 PM
Thanks for that link, it has shone some light on multiplexing inputs, There are many MIDI projects but I would prefer HID as it is becoming the standard for controllers (faster transmission, higher resolution, easier to configure on the dj software) I'll keep an eye on this thread.

PaulStoffregen
02-14-2014, 12:29 AM
I don't really understand what Bitfield means here (http://msdn.microsoft.com/en-us/library/windows/hardware/ff539832(v=vs.85).aspx). For the axis and sliders it is always 0x02 but for the hats it's 0x42.

I believe bit field is documented on page 30-31 (40th and 41st pages of the PDF) of the HID 1.11 spec. I'll attach a copy to this message.

Bit 6 (0x40) is set to indicate a variable has a null state. Here's the text from the HID spec:



Indicates whether the control has a state in which it
is not sending meaningful data. One possible use of
the null state is for controls that require the user to
physically interact with the control in order for it to
report useful data. For example, some joysticks
have a multidirectional switch (a hat switch).
When a hat switch is not being pressed it is in a
null state. When in a null state, the control will
report a value outside of the specified Logical
Minimum and Logical Maximum (the most
negative value, such as -128 for an 8-bit value).

Pointy
02-14-2014, 09:16 AM
I believe bit field is documented on page 30-31 (40th and 41st pages of the PDF) of the HID 1.11 spec. I'll attach a copy to this message.

Bit 6 (0x40) is set to indicate a variable has a null state. Here's the text from the HID spec:

Thanks Paul, I didn't have that pdf.

After sleeping on it, I have fixed another annoying problem this morning, so I am hopeful of a release over the next couple of days.

Regards,

Les

RobF
02-14-2014, 06:49 PM
Will any of this code work on the teensy2+?

PaulStoffregen
02-14-2014, 09:33 PM
Will any of this code work on the teensy2+?

Not directly, no. But it should be fairly straightforward to port it back to Teensy2.

I'm still debating whether this belongs in a future version of Teensyduino's Tools > USB Type menu. Maybe when there's at least a Windows test program? It'd be nice to know at least a few programs that can really use so many sliders and buttons...

Emuis
02-14-2014, 09:47 PM
Hey Paul,

This is exactly what I have been looking for. I write HID client drivers for our embedded OS (QNX) and I picked up a Teensy 2.0 and 3.0 (kickstarter) for the express purpose of testing the driver. So I am very glad to see this experiment as I wanted to test the limits of the driver. I'll load this up on the 3.0 I have here, I haven't looked at the code yet, however given that you have a breakout board leads me to believe that I'd need to have the same thing here, which isn't so great as I am terrible with electronics :)

Erick

nox771
02-14-2014, 10:11 PM
It'd be nice to know at least a few programs that can really use so many sliders and buttons...

I would be interested to know if this can be used with MAME. There are dedicated controllers like this (http://www.u-hid.com/home/index.php) and these (http://groovygamegear.com/webstore/index.php?main_page=index&cPath=76_81) and these (http://www.ultimarc.com/ipac1.html). For those controllers one of the key things is simultaneous buttons at once (not limited to 6 as some are). If it works I could see this being used as a controller for a MAME CP.

Emuis
02-14-2014, 10:27 PM
With the for 128 buttons, 6 axes, 17 sliders and 4 hats, things parsed nicely :)

http://pastebin.com/XnpWHJzU

and reports started to come in cleanly as well. I'll have to start to dump random values into each usage so I can actually test this further.

Anychance you could post the code with 8 axes as well?

Thanks,

E.

Pointy
02-14-2014, 10:45 PM
Maybe when there's at least a Windows test program? I

You will be pleased to know I have finally got something working. My UI only has 12 sliders but I can now read all sliders, axes , hats and buttons, I just got the ExtremeJoystick sketch to send out random values, and everything looked good.

I need to do some tidying up and add some error trapping, then I should be able to post a version for you guys to test. I may even squeeze in some more sliders to the UI.

1463

I don't know if you read them Paul, but I posted some comments here (http://forum.pjrc.com/threads/24433-Making-A-Custom-Teensy3-HID-Joystick?p=40850&viewfull=1#post40850) about custom USB devices. I don't know if there are any other options, but at the very least the installer should warn about overwriting all files in the teensy folder.

Regards,

Les

tyggerjai
02-15-2014, 10:12 AM
In case anyone else is following this Joystick thread, here's the latest code for Teensy 3.1. Just replace these 4 files in hardware/teensy/cores/teensy3 and your joystick will become 128 buttons, 6 axes, 17 sliders and 4 hats.

I am sitting in front of a desk with 150 custom buttons, 9 sliding pots, 6 rotary encoders and a 6-axis joystick. I would dearly love to replicate it at home, and have started doing so, and I happen to have received my teensy 3.1 last week. And I have some free time coming up...

So yes, I am following it, and very much hoping to implement most of it soon. Guess I'd better go buy a hundred odd buttons.

geekguy
02-15-2014, 07:42 PM
I am sitting in front of a desk with 150 custom buttons, 9 sliding pots, 6 rotary encoders and a 6-axis joystick. I would dearly love to replicate it at home, and have started doing so, and I happen to have received my teensy 3.1 last week. And I have some free time coming up...
I am starting to design what I hope will be a nice small remote robot controller. I found this 3-Axis joystick w/button (http://www.robotshop.com/en/3-axis-joystick-w-button.html) at RobotShop (http://www.robotshop.com). I'm thinking that having two, or maybe even three, of these, along with some sliders, buttons, and a few hats, would make for a great controller.

Right now, I'd use one joystick for motion control, with the option to configure to use two joysticks, and the third joystick to control the pan/tilt on the front. This would suit the current configuration of my W.A.L.T.E.R. 2.0 (http://forum.pjrc.com/threads/25067-W-A-L-T-E-R-2-0-and-the-Teensy-3-1) just fine.

If I don't use two joysticks for motion, I'd configure the second one to control a second pan/tilt on the top of my robot, which I have not added yet. Now, I am thinking four joysticks would be optimum for what I want to do, now and in the future - two for motion control, and one for each pan/tilt unit. I'm going to design it around a Teensy 3.1.

Afterall, can we have too many joysticks? :)

8-Dale

locodog
02-16-2014, 02:07 PM
More sliders could be possible if the resolution were decreased......
Reducing to only 12 bits would allow 22 sliders.


Regarding this, is the 'limit' the HID report size?,

I'm assuming
128 buttons @ 1bit
6 axis @ 16bit
17 sliders @ 16bit
4 hat swiches @4bit

=512 bit or 64Bytes (I remember reading that this was the largest allowed single report)

So in theory I can cut back on the number of buttons and/or reduce the resolutions on the axis (both sliders and axis) and have any number of buttons and sliders so long as it doesn't break the 64Byte limit?

Also, this is for the teensy 3.1 isn't it?

PaulStoffregen
02-16-2014, 05:37 PM
So in theory I can cut back on the number of buttons and/or reduce the resolutions on the axis (both sliders and axis) and have any number of buttons and sliders so long as it doesn't break the 64Byte limit?


Yes, the USB packet size limit is 64 bytes, and the HID code supports only single-packet reports.

You can reassign the 512 bits any way you like. All you have to do is edit the HID report descriptor, and then edit the usb_joystick.h code to put the data into the bits you allocated.



Also, this is for the teensy 3.1 isn't it?

Yes.

Pointy
02-16-2014, 08:49 PM
I have just uploaded Alpha 0.92 of the joystick test application for windows.

You can download it here (http://www.planetpointy.co.uk/?dl_id=5).

It now has RawInput & DirectX input methods, and under raw input will show up to 18 sliders.

Don't forget it's Alpha so probably has bugs, please post feedback here or on my site (http://www.planetpointy.co.uk/joystick-test-application/)!

Regards,

Les

r3l1c
02-22-2014, 11:39 PM
Hello there , is this board/shield being actually sold ? if so , please provide link ... if not, i wonder what price is the author targeting and what release date he is aiming for.

locodog
02-24-2014, 05:35 PM
Hello there , is this board/shield being actually sold .

I don't think it is a shield being developed, this is the code you would need for a tensey 3.1 to then go on and build the circuits for inputs (just a few multiplexers pots and buttons)

geekguy
02-24-2014, 08:55 PM
I'm still debating whether this belongs in a future version of Teensyduino's Tools > USB Type menu. Maybe when there's at least a Windows test program? It'd be nice to know at least a few programs that can really use so many sliders and buttons...
As soon as I have both of my robots fully operational, I'm going to start working on a wireless robot controller. This controller will have at least three 3-axis joysticks (possibly 4), some sliders, hats, and of course several buttons.

I'm looking at using this joystick (http://www.robotshop.com/en/3-axis-joystick-w-button.html), and hope to get one to play with soon. They are pretty expensive, but if they have the right specfications, I want to use them.

For instance, I could use a single one of these to control the gripper on my SES Rover (Y = raise/lower, X = open/close gripper, Z = wrist rotate). One could be used for locomotion control (Y = left motor, X = right motor, Z = rotation). Two sticks could be used for locomotion using the Y-axis of each to control left and right motors.

There are so many possible combinations for controlling robots, using this extreme joystick! :D One controller could even be used to control two robots. My controller could easily use up nine axis, with three of these joysticks, twelve axis with four of them. :)

Unfortunately, it might take me awhile to get the parts I need to start building this. :(

8-Dale

PaulStoffregen
02-25-2014, 08:22 PM
Hello there , is this board/shield being actually sold ?

Here's a blog post about the breakout board I made. It was designed for general purpose testing of the pins on a Teensy. I just used it for (partially) testing this joystick code, since it was sitting on my desk.

http://www.dorkbotpdx.org/blog/paul/input_output_analogdigitial_pin_test_circuit

This board isn't sold anywhere. But if you really want one, I do have several extra bare PCBs. You'd need buy all the parts elsewhere and solder all of them, which takes at least a few hours by hand soldering.

PaulStoffregen
02-25-2014, 08:28 PM
I've added the PCB gerber files and placement diagram on this project's blog page at DorkbotPDX.org.​

http://www.dorkbotpdx.org/blog/paul/input_output_analogdigitial_pin_test_circuit

locodog
02-27-2014, 12:07 AM
Hi Paul I see you've published on Hackaday, I've had a bit of success myself with my Arduino and I can confirm (well, suppose with authority) that your many axis joystick will be fully functional for virtual dj (my example is 128 * 1 bit and 48 *8 bit) and I can further suppose that any dj software that accepts HID will be too. (Ableton & Serato)

If you were wanting to tap into this DJ controller market, a return HID packet back to the 'joystick' controlling LEDs and such would be the next step and a then 2 packet reports,

I'll write up a promo-post at the VDJ forums.

stevos758
03-11-2014, 09:00 PM
This is awesome! I am developing my own game controllers right now with the teensy 2.0 and 3.1.

I've been keeping a close eye on this thread.

How does one integrate an encoder to one of these? My understanding on the 2.0 you use pins 5,6,7,8? I hooked one up the other day and I only had it functioning in the sketch as regular button presses. I tried using the #encoder.h and implemented the example sketch into the example joystick sketch. everything was working fine in serial mode but not back in HID mode.

Please describe as simple as possible. I am very new to this stuff.

Ill dig around and see if I can put some of these to use!

Currently i need about 32 buttons.

I would assume I can make some kind of switch matrix for this?

nonlinearmind
03-15-2014, 06:14 PM
In case anyone else is following this Joystick thread, here's the latest code for Teensy 3.1. Just replace these 4 files in hardware/teensy/cores/teensy3 and your joystick will become 128 buttons, 6 axes, 17 sliders and 4 hats.

Works great as-is with Controllermate for mac os x. Seems to recognize all inputs.

ChrisLaurie
03-16-2014, 09:28 AM
Hi there

I'm a complete electronic dunce, trying to learn and create a lighting control board that will run using HID over the usb link. So 6 axis, 17 sliders and 128 buttons is just what I'm looking for.

My biggest problem is building the connections between the sliders, axis, buttons and the teensy3 board.

The board posted here only has 33 buttons and 14 sliders on it (I assume the 6 axis is accessed via the pins on the edge of the board).

I assume the buttons uses a mapping matrix that requires the 2 parts of the switch to connect to a number of shared lines (36 runs via 12 channels 6 rows and 6 columns). So 128 buttons would work how and be connected to the Teensy how?

Any suggestions on where to start would be appreciated.

KurtE
03-16-2014, 04:02 PM
A few of us up on Lynxmotion have been playing around with a DIY remote control for awhile now (first with RC output, which I converted to XBee). First versions used a Basic Atom Pro for the micro-controller, but I have played around with some different Arduino boards as well. On those we have been using a 16 button keypad (later added some external buttons as well), that we read in on 8 IO pins (4x4, later 4x5 for external switches).

A diagram showing the keypad wiring is up on the posting: http://www.lynxmotion.net/viewtopic.php?f=21&t=5447&start=91
Note the keypad is setup that each of the switches in a row are wired to each other, likewise for columns.

On these I used external PU resistors. Probably here can get away with using internal weak PU resistors. Reading the matrix, You start off with all of the rows logically set high, and then set one of them low and then look at the inputs for the columns. If you read a low value you know the button is pressed, then you go on to the next row (set the previous row back high, and set the next row low)... Actually I was concerned about setting the rows actually high as if you press multiple ones, you will can get a direct routing of a high value to a low value, so I personally instead of setting the value to a high, changed the pin to INPUT, this way it floated and if multiple buttons were pressed it relied on the PU resistors for the other side to read high... (Sorry if I did not explain that very well).

Another approach if you have spare Analog pins available is using setting them up with a resister network, such as described in: http://forum.arduino.cc/index.php/topic,8558.0.html

geekguy
03-17-2014, 12:34 AM
A few of us up on Lynxmotion have been playing around with a DIY remote control for awhile now (first with RC output, which I converted to XBee). First versions used a Basic Atom Pro for the micro-controller, but I have played around with some different Arduino boards as well. On those we have been using a 16 button keypad (later added some external buttons as well), that we read in on 8 IO pins (4x4, later 4x5 for external switches).
Yes, indeed! You, and others there, have done great work on these controllers. I'm going to be taking a closer look at your work as I start my own controller design. It would be really interesting to see what you could do with a Teensy 3.1 in your design. :)

8-Dale

ChrisLaurie
03-17-2014, 04:22 PM
Ok so some more digging has me thinking. Let's start with my goal. It is based on the above post re a joystick of 128x1bit (buttons) and 48x8bit (sliders/axis etc) to build a control system for lighting control software (QLC+).

So as a noob I was confused about the pin descriptions of the teensy, until I read the USB-midi page. It includes a circuit diagram to connect many 74HC4051 integrated circuits to handle lots of buttons and sliders. Buttons going to a digital pin and sliders going to an analog pin. One has to use 3 digital pins that connect to all the 74HC4051 (a "bus" of some sort?) and then each of them additionally occupies either a digital or a analog pin on the teensy.

I was already aware of the button matrix method (from the BU0836A). So my first question now is this: If we use the row/column button matrix, then a 8x8 button pad (8 rows and 8 columns) would use 2 of 74HC4051 chips? They both have 8 channels and the matrix works on detecting which rows and which columns have been switched so that will work? The issue then becomes to write the software to read the signals on the eight columns an rows and interpret that to find out which buttons have been pressed. and then in turn to send this through to the HID packet.

My second question relates to the other pieces of hardware. For my goal, I do not need LED's, maybe later but not now. I also need just a signal that a button has been pressed (momentary on), so there is no latching logic required - again maybe later but not now. My initial build will probably be two 8x8 button matrices made of B3F square switches. Now the question is this: Apart from serial diodes, what other electronics needs to be fitted to the button circuit to make it work with the 74HC4051 chips?

The same question relates to the sliders. There will be 48 potentiometers (5k ohm, I guess) that each connects to 1 pin on the 74HC4051 , which in turn uses 1 analogue pin on the teensy and share the same 3 digital pins with the 74HC4051 used for the switches. What other circuit components are needed to make this work?

The USB-midi example seems to suggest: none!

So my joystick plan is this:

1. Buttons on an 8x8 keypad (with serial diodes) made in the configuration of 8 rows by 8 columns and each row and column mapping to a channel on a 74HC4051. For 128 buttons that would be four 74HC4051 chips using 3 (common) teensy digital pins plus 4 additional digital pins.

2. Sliders have one leg linked to a channel on the 74HC4051. So for 48 sliders that gives me six 74HC4051 chips, using the same 3 common chips as the buttons plus 6 more analog chips.

3. Teensy software to read and calculate button states and set the appropriate bits in the HID packet. The same software should read the values from the faders and convert it to 8 bits. This software is also a grey area to me. I'm hoping some the Teensy guru's will help here.

4. Teensy software to create the appropriate HID headers etc to make it readable by the lighting controller software.

If I can build a 128 button 48 fader joystick to run my lights, it would be fantastic!! This is exciting.

Please advise this (an hopefully future) noob(s).

f15sim
03-27-2014, 03:40 PM
I'd like to be able to use this in a couple of different flight simulator projects I'm working on. Can someone point me to the pinout needed to wire this thing up as configured in this thread? (6 axes, 12 (17?) sliders, 128 buttons) I'm assuming that the buttons are arranged on a row/column basis. Can the buttons be wired using a diode isolation matrix in order to allow many (or all) to be closed at once?

I'll be ordering two Teensy 3.1s in a few minutes. :)

Thanks All!

g.

[edit: Ordered!]

stevos758
03-27-2014, 03:47 PM
I'd like to be able to use this in a couple of different flight simulator projects I'm working on. Can someone point me to the pinout needed to wire this thing up as configured in this thread? (6 axes, 12 (17?) sliders, 128 buttons) I'm assuming that the buttons are arranged on a row/column basis. Can the buttons be wired using a diode isolation matrix in order to allow many (or all) to be closed at once?

I'll be ordering two Teensy 3.1s in a few minutes. :)



Thanks All!

g.

I am also awaiting an answer for this. I need to know how to hook up the matrix. Good luck with your projects!

f15sim
03-27-2014, 04:25 PM
stevos758, if the board uses a "typical" row & column matrix, this should work:
http://www.geneb.org/ematrix.png

I drew that up about 14 years ago (wow!) to help explain how switch matrices could be wired up to the R&R Electronics EPIC controller. Think of the "DBx" labels as "Row x" and the "Mod x, Row y" labels as "Column x"

It wouldn't take much work to convert that to a little PCB that could support row & column terminal blocks with the diodes stand on end between them.

Here's another question - with the Teensy 3.1 configured as this "mega" joystick, would it still be possible to communicate with it? I ask because it would be nice to be able to write a configuration tool that would allow you to reverse axes, tweak dead zones, adjust response curves, etc.

g.

stevos758
03-27-2014, 04:29 PM
stevos758, if the board uses a "typical" row & column matrix, this should work:
http://www.geneb.org/ematrix.png

I drew that up about 14 years ago (wow!) to help explain how switch matrices could be wired up to the R&R Electronics EPIC controller. Think of the "DBx" labels as "Row x" and the "Mod x, Row y" labels as "Column x"

It wouldn't take much work to convert that to a little PCB that could support row & column terminal blocks with the diodes stand on end between them.

Here's another question - with the Teensy 3.1 configured as this "mega" joystick, would it still be possible to communicate with it? I ask because it would be nice to be able to write a configuration tool that would allow you to reverse axes, tweak dead zones, adjust response curves, etc.

g.

Thanks for the Pro-Tip! I plan on making the matrix PCB with my CNC. I just need to know what pins to hook it up too. I actually don't need all of the buttons and axis. Just more buttons than the stock teensy.

From my newb expriments you can edit and flash in minutes very easily. It's not a pain like flashing HID to Arduino Uno's

I would also like to include some rotary encoders but I haven't figured that out yet.

f15sim
03-27-2014, 04:39 PM
Thanks for the Pro-Tip! I plan on making the matrix PCB with my CNC. I just need to know what pins to hook it up too. I actually don't need all of the buttons and axis. Just more buttons than the stock teensy.

From my newb expriments you can edit and flash in minutes very easily. It's not a pain like flashing HID to Arduino Uno's

I would also like to include some rotary encoders but I haven't figured that out yet.

Well the idea would be to have something like Pointy's slick joystick test tool, but with a tab on it that would allow you to tweak the thing without having to deal with re-uploading firmware to it at all. It would be much more end-user friendly. There's very few cockpit builders out there that want to get drug down the rabbit hole. :)

g.

f15sim
03-31-2014, 05:07 PM
steveos758, if you hadn't figured it out by now, the pin layout for the device is squirreled away in the .ino file listed in the source code post.

The full configuration will require the use of the surface mount pads on the bottom of the Teensy 3.1 - I don't know what connector would fit there though as I'm very unfamiliar with surface mount interconnects.

The device needs to be set up in the Arduino IDE as the Serial/Mouse/Keyboard/Joystick selection, so that leads me to think that building a serial based configuration tool is perfectly reasonable.

g.

Pointy
04-01-2014, 07:26 AM
I'd like to be able to use this in a couple of different flight simulator projects I'm working on. Can someone point me to the pinout needed to wire this thing up as configured in this thread? (6 axes, 12 (17?) sliders, 128 buttons) I'm assuming that the buttons are arranged on a row/column basis. Can the buttons be wired using a diode isolation matrix in order to allow many (or all) to be closed at once?

I'll be ordering two Teensy 3.1s in a few minutes. :)

Thanks All!

g.

[edit: Ordered!]


I think the whole point is , this is just the building blocks and there is no set way of wiring it up. You choose what type of analog devices and what buttons you use and then tweak the code to match. Since Paul has done all the hard work with the USB coding, which can be a nightmare to get your head around, you just have to edit the Teesny code side, which is very easy to understand and modify.


Well the idea would be to have something like Pointy's slick joystick test tool, but with a tab on it that would allow you to tweak the thing without having to deal with re-uploading firmware to it at all. It would be much more end-user friendly. There's very few cockpit builders out there that want to get drug down the rabbit hole. :)

g.

What you could have is a joystick GUI tool, something like this (http://generichid.sourceforge.net/index.html) which would do all the coding for you.

Regards,

Les

PaulStoffregen
04-01-2014, 08:23 AM
I think the whole point is , this is just the building blocks and there is no set way of wiring it up.

Yes, exactly.

But maybe there should be an example program that works with a specific wiring. Maybe a large-ish circuit board with places to add connections for all the buttons, pots, etc?

f15sim
04-01-2014, 02:34 PM
I think the whole point is , this is just the building blocks and there is no set way of wiring it up. You choose what type of analog devices and what buttons you use and then tweak the code to match. Since Paul has done all the hard work with the USB coding, which can be a nightmare to get your head around, you just have to edit the Teesny code side, which is very easy to understand and modify.

Right. I just didn't happen to notice the .ino file listed when I posted that originally. The analogs are easy to nail down and I think if it's possible to use, the Arduno key matrix library would work well for the switches, but I don't know if it would work with a diode matrix.



What you could have is a joystick GUI tool, something like this (http://generichid.sourceforge.net/index.html) which would do all the coding for you.

I've seen that ( and it's why I bought a Teensy to work with it), but he's not providing Windows binaries any longer (that I could find) due to some issue with a dll he's using. (there's commentary on his source repo about it)

What I'm thinking of is something that would allow people to invert axes, adjust dead zones, etc. No "programming" per se.

I'm interested in things that can help lower the bar for people that want to build their own flight simulator cockpits. Something like the "mega" interface that the Teensy 3.1 can do would be great, especially considering that the only device close in function (commercially) is the offerings by Leo Bodnar at over twice the price.

Here's some of the stuff I'm working on:
http://www.f15sim.com
http://www.diy-cockpits.org/coll
http://geneb.simpits.org

:D

g.

f15sim
04-01-2014, 02:35 PM
Yes, exactly.

But maybe there should be an example program that works with a specific wiring. Maybe a large-ish circuit board with places to add connections for all the buttons, pots, etc?

A reference design of sorts. :)

g.

locodog
04-01-2014, 03:41 PM
Any plans for pc to device HID communication for vibration or other feedback?

carcaes1
04-01-2014, 10:31 PM
Hello guys

I'm writing you about one issue that i have with this code/joystick of this thread

http://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41723&viewfull=1#post41723

I downloaded it and i was doing tests. It works fine with one axis X (i had a potentiometer 10k). (input analogic 0)

But now i have connected another potentiometer to input 1 (Axis Y) and in controller game/device usb i see something weird.

In axis X is perfect, from 0 to 65535 (RAW DATA and DIRECT INPUT DATA), (With RX is ok too)

but in AXIS Y, the value bar does something bad ->
RAW DATA(red arrow) begin slowly and later goes quickly. But Direct Input Data goes to the maximum (65535) at the beginning (black arrow) (With AXIS Z, RZ, SLIDER is the same).

And with AXIS RY goes slowly and later quickly , but raw data and input data is the same.

A little crazy...

http://sia1.subirimagenes.net/img/2014/04/01/14040105030238576.jpg

---

It can be the read of package bytes data by windows? Have you tested it and works fine in your pc?

Thanks in advance.

Cheers

ps=If i upload a simple sketch for reading the analogic inputs 0, 1, 2 3.... and println in serial port the value, is correct.

carcaes1
04-02-2014, 09:05 AM
false alarm, at the end was my "Dear Windows". :mad:

In joy.cpl, i have clicked in "Restore Defaults" and returned to work.

Last question.

If you do not use resistors on the analog inputs, I get noise. If you use resistors 10 kohm (I'm using standard potentiometers 10k), i disable the noise, but the values in joy.cpl ​​don't move normally/linearly (the axis starts slowly and then faster, nonlinear.)

Thanks in advance

EDIT

It looks like that with resistors of 20kohm works well. I will continue test them.

f15sim
04-02-2014, 01:25 PM
Carcaes1, make sure you're not using audio taper pots. They have a logarithmic progression to them, which appears to match what your 10K pot is doing. You want to get pots specifically labeled as linear taper. (or punt and build yourself a hall effect sensor. :D )

g.

carcaes1
04-02-2014, 01:51 PM
Thanks f15sim. :D

I have this potentiometer

http://www.dx.com/es/p/mf-diy-10k-ohm-rotary-potentiometer-module-for-funduino-black-green-red-dc-5v-204178#.UzwHKqh_uSo

And another 10 k lineal (i think, because i toldthe shop's clerk that i wanted a lineal pot)

Now they are working good (after reset defaults the data value of joystick windows) and with 20 kohm resisntance.
With 10 kohm resistance the value is not lineal....

f15sim
04-02-2014, 02:50 PM
Good to see you got it working! For "typical" joystick applications, a 100k pot has been a traditional choice, but I think that has more to do with the RC circuit that the pre-USB joystick/game interfaces used on the PC platform.

g.

carcaes1
04-02-2014, 02:59 PM
Thanks again

Now i'm using these potentiometers only for testing at the beginning.

Cheers !!!

phoenixcomm
04-09-2014, 02:15 PM
Hi all just found this tread... would like to get 7-8 axis on an arduino I have just picked up a Leonardo... I am waiting to test the code their.. my system IS NOT Windows! This should work in my Linux environment as well. I have wanted one of Leo's boards but never got around to throw some cash his way..
Cris
here is my blog:
http://www.element14.com/community/people/phoenixcomm/blog

Headroom
04-09-2014, 10:59 PM
Hi phonixcomm,

This forum is dedicated to the Teensy family of boards and the PJRC products in general ;-)

nonlinearmind
04-11-2014, 09:39 PM
How would I add LEDs to a joystick like this? I'm creating a keypad and need about 20 Leds.

carcaes1
04-25-2014, 12:30 PM
One question, this update for big joystick is compatible with teensy 2.0 (atmega32U4)?

I think not, but can you confirm it?

Regards

PaulStoffregen
04-25-2014, 02:41 PM
One question, this update for big joystick is compatible with teensy 2.0 (atmega32U4)?

No. The code on reply #36 (http://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942) is for Teensy 3.0 and 3.1 only.

carcaes1
04-25-2014, 02:43 PM
No. The code on reply #36 (http://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942) is for Teensy 3.0 and 3.1 only.


Thanks Paul.

Tristan
06-04-2014, 08:26 AM
Hi Paul,

Firstly I'd just like to express my gratitude to you for your work. I'm an experienced web developer just entering the micro controller world and I just love what you're doing with the Teensy, it's fantastic!

I'm very interested in the work you've been doing on this thread with this extreme joystick. I'm currently creating a custom controller for the forthcoming Elite Dangerous game and am using your extreme joystick example with a teensy and a USB host shield to hack a Saitek X52 pro HOTAS which will form part of my custom controller.

Whilst working on this I noticed what I believe to be a minor bug in the hat(...) function in the extreme joystick usb_joystick.h

The function as it stands will set the val variable to 1 if the direction passed in is -1 (i.e. no direction being applied to the hat).

I believe that val should be set to 15 if no hat direction is being applied as per the hat function in usb_joystick.h that ships with Teensyduino in hardware\teensy\cores\teensy3.

Other than the zip file in this thread is the extreme joystick source available on any source hosting e.g. Github? I plan to open source the sketch I'm using to hack the X52 (hopefuly by contributing to your USB_Host_Shield_2.0 repository) but there's a dependency on your usb_*.* files which I'd need to resolve somehow.

Best wishes,

Tristan

buznee
07-19-2014, 11:40 PM
Hey Paul!

I'm in the process of creating my own USB joystick and my goal is to have true 16 bit resolution. I was using your extreme joystick 3 code including the usb descripter and joystick files which the axes controls I checked are set to 16 bit (65536). I understand that you multiplied your analog input in your arduino sample joystick code by 64. Why is this? I noticed that by doing that it truly is still not 16 bit resolution. I can tell by looking at the raw data counts during the calibration I can see each step is 64 apart. Meaning in reality the controller is still working with 10 bit. Anotherwords if I decide not to multiply my analog output by 64 I now get a 1024 resolution range but essentially the same steps because now I can see each individual step in the raw count as I move the axis. Something seems funny with regards to the code. Is there any way in the usb_joystick.h file to change the nominal range from 1024 (10 bit) to 65536 (16 bit) so that I truly get the 16 bit resolution I'm looking for? Thanks for all the work you did with that by the way, big help!

-Dan

UPDATE: I figured it out.... You have to use

analogReadResolution(bit);

I set it to 16. Without it the analogread function defaults to 10 bits.

PaulStoffregen
07-20-2014, 01:27 AM
Yes, analogRead defaults to 10 bits.

Even if you set it to 16, the "effective number of bits" is only about 13, even if your circuitry is perfect. The lower 3 bits are always noise.

To get "true" 16 bits, you'll need a number better ADC chip and excellent analog circuity to keep the noise very low.

giliep
07-21-2014, 08:06 AM
Hi Paul,

First, thank you for your work it looks awesome!! I can't wait to build a controller for my iRacing simulator.
I do have a question about exporting the code from teensy 3.1/.0 to the teensy 2.0++, Since I'm a nob on this field (Mechanical Engineer) I would like a guidance to how I should do it. By guidance i mean links to how i do it. Or a link to a forum post about it if possible. I couldn't find something myself, and reading all this material is kinda overwhelming right now...

Is it possible at all to do it on the teensy 2.0++? (could be dumb question but i don't know right now fully the differences between the boards)

Thanks!!

brydling
07-27-2014, 08:12 PM
DCS supports at least 128 buttons, 8 axes and 4 POV hats on each gaming device. I developed a joystick controller a few years ago with 248 buttons, 2 POV hats and 13 axes divided over two devices with 124 buttons, 1 POV hat and 8/5 axes each. You could download and install DCS World to test all 128 buttons. A customer of mine also developed a test utility to display all the buttons in Windows. It can be found on https://code.google.com/p/bne-joystick-tester/source/browse/. You will also need SlimDX SDK from http://slimdx.org/download.php. Actually I have never tested it myself since I have not produced many boards since he made it.

giliep
07-28-2014, 09:57 AM
@brydling

Was that for me?
Its a bit over my head. I'm not a programmer so i don't understand it. I want to know what i need to change in order to make it compatible for the teensy 2.0++

brydling
07-30-2014, 06:55 AM
@brydling

Was that for me?
Its a bit over my head. I'm not a programmer so i don't understand it. I want to know what i need to change in order to make it compatible for the teensy 2.0++

No, that was for Paul. I read that he needed a way to test all the inputs on the controller.

U.K
12-31-2014, 04:08 AM
Hello Paul,

your joystick project is really good. I am very new to this electronic stuff and i really need help. Now, i want to make this huge joystick and use it as flight simulator controller. However i dont know how to connect this many buttons to the pins on teensy. Because there is no enough pins for all buttons. Do you have any scheme how to connect this 128 buttons 17 sliders and others ? I saw you published some breakboard but its not fully functional, i want to use all of buttons and sliders. Could you make a scheme or something like that maybe pcb scheme ( i am not sure what it is ). So i can take it and make cool joystick. Thank you very much Happy new years

PaulStoffregen
12-31-2014, 01:45 PM
There are many ways to connect lots of buttons. Three are widely used:

1: A row-column matrix
http://www.pjrc.com/teensy/td_libs_Keypad.html

2: Using shift registers, like 74HC165

3: Using I2C I/O expanders, read with the Wire library
https://www.adafruit.com/product/593

f15sim
12-31-2014, 02:12 PM
Paul, I've got some boards designed that allow me to easily create diode-isolated input matrices for the exact kind of project that U.K. is working on. Can the keypad library deal with having some (or all!) of the switches in a matrix closed? Can it handle a large (say 8x32) matrix?

Thanks for your time!

g.

U.K
01-03-2015, 05:41 AM
There are many ways to connect lots of buttons. Three are widely used:

1: A row-column matrix
http://www.pjrc.com/teensy/td_libs_Keypad.html

2: Using shift registers, like 74HC165

3: Using I2C I/O expanders, read with the Wire library
https://www.adafruit.com/product/593

Thank you very much for your answering.

Bum_Pilot
02-09-2015, 06:10 PM
Hello Paul.

Been very much interested in this project, i`m new here and building a home cockpit, so i would need that many buttons (128+) as (ON/OFF). (ON/OFF/ON) and soo on.

I would like to know if you could do a list of how to or such for those of us with simple knowledge, kind of PDF walkthrough. And i`m reading through to buy the stuff and really test this out.

I know the wiring, switches and the interface with the Sim. software, but the kind of materials not soo much, but keen to learn.

Thanks for your time

DangerMouse
03-17-2015, 09:45 PM
Yes, having it broken down barny style would really be nice.

For example, how does one physically wire a bunch of switches into a matrix? Can we follow diagrams written for the Epic card?

The keypad link seems to talk about coding, not wiring

zelfor
06-06-2015, 10:31 PM
I recently ran into a compilation error using the extreme joystick library from post #36 (https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942) in this thread.

I detailed the error in a post here (https://forum.pjrc.com/threads/28830-Error-Compile-error-using-Many-Axis-joystick-lib-and-test-file?p=74795#post74795), but basically one of the structs in usb_desc.h was being included twice and throwing a compiler error.

I fixed by wrapping the following code, located near the bottom of usb_desc.h from the extreme joystick lib with a #ifndef...



#ifndef _usb_dec_t
#define _usb_dec_t
extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS];

typedef struct {
uint16_t wValue;
uint16_t wIndex;
const uint8_t *addr;
uint16_t length;
} usb_descriptor_list_t;

extern const usb_descriptor_list_t usb_descriptor_list[];
#endif


Can anyone else see if they get the same error and confirm that the fix works for them. It's working for me.

It may be a bandaid, not a proper fix, but I'm not familiar enough with C to know what the best approach would be. Also, usb_desc.h has its own #ifndef at the top, I would have thought that would have covered the above struct.

ChrisLaurie
06-17-2015, 10:09 PM
Can anyone help out noob here, please? I have changed my HID header to be 64 buttons and 28 sliders (no axes, no hats) - this will be used in Linux only as we know windows has their own idea about the HID spec.

My problem comes in not knowing exactly what changes to make in usb_joystick.h Below is the code I have now and I can see the buttons being pressed in DiView but not the sliders move. The serial monitor shows the data changing as expected. The original extreme joystick worked fine.


int usb_joystick_send(void);
extern uint32_t usb_joystick_data[16];


class usb_joystick_class
{
public:
void begin(void) { }
void end(void) { }
void button(unsigned int num, bool val) {
if (--num >= 64) return;
uint32_t *p = usb_joystick_data + (num >> 5);
num &= 0x1F;
if (val) *p |= (1 << num);
else *p &= ~(1 << num);
if (!manual_mode) usb_joystick_send();
}
void slider(unsigned int num, unsigned int position) {
if (--num >= 28) return;
analog16(num, position);
}
void useManualSend(bool mode) {
manual_mode = mode;
}
void send_now(void) {
usb_joystick_send();
}
private:
void analog16(unsigned int num, unsigned int value) {
if (value > 0xFFFF) value = 0xFFFF;
uint16_t *p = (uint16_t *)(&usb_joystick_data[4]);
p[num] = value;
if (!manual_mode) usb_joystick_send();
}
static uint8_t manual_mode;
};
extern usb_joystick_class Joystick;



and the new hid descriptor (in usb_desc.c):



0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x40, // REPORT_COUNT (64)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x40, // USAGE_MAXIMUM (Button 64)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x27, 0xff, 0xff, 0x00, 0x00, // LOGICAL_MAXIMUM (65535)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x1C, // REPORT_COUNT (28)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION

Deezle
08-30-2015, 04:06 AM
Hi guys, new here. I have a working Teensy 3.1 in flight sim switch panel already. I'm not interested in using more than the 34 digital inputs, however I've like to be able to send a different button press when a toggle switch is turned off vs when it's turned on, this gives my the greatest versatility with different aircraft and how the developers have chosen to create button assignments for them (some use the same button to toggle a switch, others offer a button for each position of the switch). I understand how to do this in my sketch, however I need my "joystick" to have more than 32 button assignments available.

That's where this thread comes in. I have downloaded the USB code and the example .ino file in post #36. If I use the included "extremejoysticktest.ino" file, the joystick shows up (in Pointy's joystick tester) with all 128 buttons. As soon as I upload the my sketch to the Teensy, only 32 buttons show up. I was under the impression that the USB code is what determined how many buttons and axis' the "joystick" has, I don't understand why using other sketches breaks it.

This code is an adaptation of the "buttons" example.


/* Buttons to USB Joystick Example

You must select Joystick from the "Tools > USB Type" menu

This example code is in the public domain.
*/

#include <Bounce.h>
#include <usb_names.h>

// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(0, 10);
Bounce button1 = Bounce(1, 10); // 10 = 10 ms debounce time
Bounce button2 = Bounce(2, 10); // which is appropriate for
Bounce button3 = Bounce(3, 10); // most mechanical pushbuttons
Bounce button4 = Bounce(4, 10);
Bounce button5 = Bounce(5, 10);
Bounce button6 = Bounce(6, 10);
Bounce button7 = Bounce(7, 10);
Bounce button8 = Bounce(8, 10);
Bounce button9 = Bounce(9, 10);
Bounce button10 = Bounce(10, 10);
Bounce button11 = Bounce(11, 10); // 10 = 10 ms debounce time
Bounce button12 = Bounce(12, 10); // which is appropriate for
Bounce button13 = Bounce(13, 10); // most mechanical pushbuttons
Bounce button14 = Bounce(14, 10);
Bounce button15 = Bounce(15, 10);
Bounce button16 = Bounce(16, 10);
Bounce button17 = Bounce(17, 10);
Bounce button18 = Bounce(18, 10);
Bounce button19 = Bounce(19, 10);
Bounce button20 = Bounce(20, 10); // 10 = 10 ms debounce time
Bounce button21 = Bounce(21, 10); // which is appropriate for
Bounce button22 = Bounce(22, 10); // most mechanical pushbuttons
Bounce button23 = Bounce(23, 10);
Bounce button24 = Bounce(24, 10);
Bounce button25 = Bounce(25, 10);
Bounce button26 = Bounce(26, 10);
Bounce button27 = Bounce(27, 10);
Bounce button28 = Bounce(28, 10);
Bounce button29 = Bounce(29, 10);
Bounce button30 = Bounce(30, 10);
Bounce button31 = Bounce(31, 10);
Bounce button32 = Bounce(32, 10);
Bounce button33 = Bounce(33, 10);



void setup() {
// Configure the pins for input mode with pullup resistors.
// The pushbuttons connect from each pin to ground. When
// the button is pressed, the pin reads LOW because the button
// shorts it to ground. When released, the pin reads HIGH
// because the pullup resistor connects to +5 volts inside
// the chip. LOW for "on", and HIGH for "off" may seem
// backwards, but using the on-chip pullup resistors is very
// convenient. The scheme is called "active low", and it's
// very commonly used in electronics... so much that the chip
// has built-in pullup resistors!
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP); // Teensy++ LED, may need 1k resistor pullup
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
pinMode(16, INPUT_PULLUP); // Teensy++ LED, may need 1k resistor pullup
pinMode(17, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
pinMode(19, INPUT_PULLUP);
pinMode(20, INPUT_PULLUP);
pinMode(21, INPUT_PULLUP);
pinMode(22, INPUT_PULLUP);
pinMode(23, INPUT_PULLUP);
pinMode(24, INPUT_PULLUP);
pinMode(25, INPUT_PULLUP);
pinMode(26, INPUT_PULLUP); // Teensy++ LED, may need 1k resistor pullup
pinMode(27, INPUT_PULLUP);
pinMode(28, INPUT_PULLUP);
pinMode(29, INPUT_PULLUP);
pinMode(30, INPUT_PULLUP);
pinMode(31, INPUT_PULLUP);
pinMode(32, INPUT_PULLUP);
pinMode(33, INPUT_PULLUP);
}

void loop() {
// Update all the buttons. There should not be any long
// delays in loop(), so this runs repetitively at a rate
// faster than the buttons could be pressed and released.
button0.update();
button1.update();
button2.update();
button3.update();
button4.update();
button5.update();
button6.update();
button7.update();
button8.update();
button9.update();
button10.update();
button11.update();
button12.update();
button13.update();
button14.update();
button15.update();
button16.update();
button17.update();
button18.update();
button19.update();
button20.update();
button21.update();
button22.update();
button23.update();
button24.update();
button25.update();
button26.update();
button27.update();
button28.update();
button29.update();
button30.update();
button31.update();
button32.update();
button33.update();

// Check each button for "falling" edge.
// Update the Joystick buttons only upon changes.
// falling = high (not pressed - voltage from pullup resistor)
// to low (pressed - button connects pin to ground)
if (button5.fallingEdge()) {
Joystick.button(6, 1);
}
if (button6.fallingEdge()) {
Joystick.button(7, 1);
}
if (button7.fallingEdge()) {
Joystick.button(8, 1);
delay(200);
Joystick.button(8, 0);
}
if (button8.fallingEdge()) {
Joystick.button(9, 1);
delay(200);
Joystick.button(9, 0);
}
if (button9.fallingEdge()) {
Joystick.button(10, 1);
delay(200);
Joystick.button(10, 0);
}
if (button10.fallingEdge()) {
Joystick.button(11, 1);
delay(200);
Joystick.button(11, 0);
}
if (button11.fallingEdge()) {
Joystick.button(12, 1);
delay(200);
Joystick.button(12, 0);
}
if (button12.fallingEdge()) {
Joystick.button(13, 1);
delay(200);
Joystick.button(13, 0);
}
if (button13.fallingEdge()) {
Joystick.button(33, 1);
delay(200);
Joystick.button(33, 0);
}
if (button14.fallingEdge()) {
Joystick.button(15, 1);
delay(200);
Joystick.button(15, 0);
}
if (button15.fallingEdge()) {
Joystick.button(16, 1);
delay(200);
Joystick.button(16, 0);
}
if (button16.fallingEdge()) {
Joystick.button(17, 1);
delay(200);
Joystick.button(17, 0);
}
if (button17.fallingEdge()) {
Joystick.button(18, 1);
delay(200);
Joystick.button(18, 0);
}
if (button18.fallingEdge()) {
Joystick.button(19, 1);
delay(200);
Joystick.button(19, 0);
}
if (button19.fallingEdge()) {
Joystick.button(20, 1);
delay(200);
Joystick.button(20, 0);
}
if (button20.fallingEdge()) {
Joystick.button(21, 1);
delay(200);
Joystick.button(21, 0);
}
if (button21.fallingEdge()) {
Joystick.button(22, 1);
delay(200);
Joystick.button(22, 0);
}
if (button22.fallingEdge()) {
Joystick.button(23, 1);
delay(200);
Joystick.button(23, 0);
}
if (button23.fallingEdge()) {
Joystick.button(24, 1);
delay(200);
Joystick.button(24, 0);
}
if (button24.fallingEdge()) {
Joystick.button(25, 1);
}
if (button25.fallingEdge()) {
Joystick.button(26, 1);
delay(200);
Joystick.button(26, 0);
}
if (button26.fallingEdge()) {
Joystick.button(27, 1);
delay(200);
Joystick.button(27, 0);
}
if (button27.fallingEdge()) {
Joystick.button(28, 1);
delay(200);
Joystick.button(28, 0);
}
if (button28.fallingEdge()) {
Joystick.button(29, 1);
delay(200);
Joystick.button(29, 0);
}
if (button29.fallingEdge()) {
Joystick.button(30, 1);
delay(200);
Joystick.button(30, 0);
}
if (button30.fallingEdge()) {
Joystick.button(31, 1);
delay(200);
Joystick.button(31, 0);
}
if (button31.fallingEdge()) {
Joystick.button(32, 1);
delay(200);
Joystick.button(32, 0);
}
if (button32.fallingEdge()) {
Joystick.button(5, 1);
delay(200);
Joystick.button(5, 0);
}
if (button33.fallingEdge()) {
Joystick.button(4, 1);
}


// Check each button for "rising" edge
// Update the Joystick buttons only upon changes.
// rising = low (pressed - button connects pin to ground)
// to high (not pressed - voltage from pullup resistor)
if (button5.risingEdge()) {
Joystick.button(6, 0);
}
if (button6.risingEdge()) {
Joystick.button(7, 0);
}
if (button7.risingEdge()) {
Joystick.button(3, 1);
delay(200);
Joystick.button(3, 0);
}
if (button8.risingEdge()) {
Joystick.button(9, 1);
delay(200);
Joystick.button(9, 0);
}
if (button9.risingEdge()) {
Joystick.button(10, 1);
delay(200);
Joystick.button(10, 0);
}
if (button10.risingEdge()) {
Joystick.button(11, 1);
delay(200);
Joystick.button(11, 0);
}
if (button11.risingEdge()) {
Joystick.button(12, 1);
delay(200);
Joystick.button(12, 0);
}
if (button12.risingEdge()) {
Joystick.button(13, 1);
delay(200);
Joystick.button(13, 0);
}
if (button13.risingEdge()) {
Joystick.button(14, 0);
}
if (button14.risingEdge()) {
Joystick.button(15, 1);
delay(200);
Joystick.button(15, 0);
}
if (button15.risingEdge()) {
Joystick.button(16, 1);
delay(200);
Joystick.button(16, 0);
}
if (button16.risingEdge()) {
Joystick.button(17, 1);
delay(200);
Joystick.button(17, 0);
}
if (button17.risingEdge()) {
Joystick.button(18, 1);
delay(200);
Joystick.button(18, 0);
}
if (button18.risingEdge()) {
Joystick.button(3, 1);
delay(200);
Joystick.button(3, 0);
}
if (button19.risingEdge()) {
Joystick.button(20, 0);
}
if (button20.risingEdge()) {
Joystick.button(21, 0);
}
if (button21.risingEdge()) {
Joystick.button(22, 0);
}
if (button22.risingEdge()) {
Joystick.button(23, 0);
}
if (button23.risingEdge()) {
Joystick.button(24, 0);
}
if (button24.risingEdge()) {
Joystick.button(25, 0);
}
if (button25.risingEdge()) {
Joystick.button(26, 0);
}
if (button26.risingEdge()) {
Joystick.button(27, 1);
delay(200);
Joystick.button(27, 0);
}
if (button27.risingEdge()) {
Joystick.button(28, 1);
delay(200);
Joystick.button(28, 0);
}
if (button28.risingEdge()) {
Joystick.button(29, 0);
}
if (button29.risingEdge()) {
Joystick.button(30, 0);
}
if (button30.risingEdge()) {
Joystick.button(31, 0);
}
if (button31.risingEdge()) {
Joystick.button(32, 0);
}
if (button32.risingEdge()) {
Joystick.button(5, 0);
}
if (button33.risingEdge()) {
Joystick.button(4, 0);
}
}

Deezle
08-30-2015, 08:07 AM
Well, I've found that incrementing bcdDevice in usb_desc.c every time I upload a sketch will make the joystick show up with 128 buttons, however I'm unable to get any buttons to respond using the sketch I posted above. Works fine with the default USB code.

98abaile
01-01-2016, 01:12 AM
Will this code work on a teensy 3.2? I'm trying to get a PS/2 keyboard to output as a game controller.

EDIT:
It turns out I've actually got a teensy 3.1 built into another controller and a spare 2.0 lying around that was originally intended for that project. Still, an answer to the question might be useful to others.

PaulStoffregen
01-03-2016, 01:02 PM
It should work on Teensy 3.2. It was written and tested on Teensy 3.1, which is identical to Teensy 3.2 as far as this code (https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942) is concerned.

Quite a lot has changed and improved in Teensyduino since it was written almost 2 years ago. If there are any issues, 3.1 and 3.2 will likely be impacted the same way.

potatomasher
01-20-2016, 11:17 PM
i'm working to create a trim box with 6 rotaries and maybe 6 on-on switches. would i be ok using an existing HID or should i try to pare down until i only have the axis and buttons i require?

konfu
02-04-2016, 08:19 PM
Hi everyone.

I'm trying to set up a joystick with 128 buttons (no need for sliders etc). But it seems like the patch from Paul isn't working on the latest Teensy build. Can anyone confirm?

I just downloaded the files from the last patch Paul provided and moved them to the teensy folder (replacing the 4 files).

I get the following error message during compiling:


/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/usb_joystick.c: In function 'usb_joystick_send':
/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/usb_joystick.c:78:36: error: 'TX_TIMEOUT' undeclared (first use in this function)
if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
^
/Applications/Arduino.app/Contents/Java/hardware/teensy/avr/cores/teensy3/usb_joystick.c:78:36: note: each undeclared identifier is reported only once for each function it appears in
exit status 1

Could anyone give me a hand here? I don't know where to start ...

Drambit
02-09-2016, 04:18 AM
I'm trying to make a much more basic arcade stick than the things people are making here, just 10 buttons and a 4 way digital joystick. I'm trying to adapt the Teensy stock example for joystick_complete to work for what I'm doing, but I ran into a few serious problems:

1. Even though my computer recognizes my device (computer+mouse+joystick teensy 2.0), if I go into controller properties, the window that would normally show you the POV hat as well as all the button functions, is completely empty, it's not even like it shows the red button symbols but I can't get them to work, straight up the window that is supposed to show that is empty.

2. I can't figure out how to get the POV hat working to begin with. I think the example is set up so that you can put one in directly, but I have no idea how to actually go about doing so.

Here is my code, any help is greatly appreciated, I've been trying to get this thing working for a really long time.


const int numButtons = 14;
// Changes numButtons to be the specific pins that are wired rather than being incremental 0-16
const uint8_t buttons[numButtons] = { 0, 1, 2, 3, 16, 17, 18, 19, 20, 21 /* ... */ };

void setup() {
// you can print to the serial monitor while the joystick is active!
Serial.begin(9600);
// configure the joystick to manual send mode. This gives precise
// control over when the computer receives updates, but it does
// require you to manually call Joystick.send_now().
Joystick.useManualSend(true);
for (int i=0; i<numButtons; i++) {
pinMode(buttons[i], INPUT_PULLUP);
}
Serial.println("Begin Complete Joystick Test");
}

byte allButtons[numButtons];
byte prevButtons[numButtons];
int angle=0;

void loop() {


// read digital pins and use them for the buttons
for (int i=0; i<numButtons; i++) {
if (digitalRead(buttons[i])) {
// when a pin reads high, the button is not pressed
// the pullup resistor creates the "on" signal
allButtons[i] = 0;
} else {
// when a pin reads low, the button is connecting to ground.
allButtons[i] = 1;
}
Joystick.button(i + 1, allButtons[i]);

}

// make the hat switch automatically move in a circle
angle = angle + 1;
if (angle >= 360) angle = 0;
Joystick.hat(angle);

// Because setup configured the Joystick manual send,
// the computer does not see any of the changes yet.
// This send_now() transmits everything all at once.
Joystick.send_now();

// check to see if any button changed since last time
boolean anyChange = false;
for (int i=0; i<numButtons; i++) {
if (allButtons[i] != prevButtons[i]) anyChange = true;
prevButtons[i] = allButtons[i];
}

// if any button changed, print them to the serial monitor
if (anyChange) {
Serial.print("Buttons: ");
for (int i=0; i<numButtons; i++) {
Serial.print(allButtons[i], DEC);
}
Serial.println();
}

// a brief delay, so this runs 200 times per second
delay(5);
}

carcaes1
03-03-2016, 11:13 AM
It should work on Teensy 3.2. It was written and tested on Teensy 3.1, which is identical to Teensy 3.2 as far as this code (https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41942&viewfull=1#post41942) is concerned.

Quite a lot has changed and improved in Teensyduino since it was written almost 2 years ago. If there are any issues, 3.1 and 3.2 will likely be impacted the same way.

Hello again Paul

Do you think that code of "joystick" (this link) in teensy 3.1 is compatible with teensy LC? I want to buy one.

https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41730&viewfull=1#post41730

masawee
11-16-2016, 09:37 PM
just registrating to forum and im newbie, and want ask, what i need make ONLY 16 axes analog input (i hear arduino mega board can do) i not need buttons/switch or encoders. only analog input my flight sim X yuoke,rudder,trottle, trimm etc.
i have at home some arduino mega 2560 board whit ch340 chip, can i use this or need me orden teensy or other board ?
how make description and compile to hex file ?
how burn hex file to possiple board ?
or can somebody make me hex file what use ONLY maximum axes and slider what can add to board ?
i no understand anythink how this made but i need my fsx analog input i made own yuoke rudder trottle, trim wheel, etc.

can anyone help me how made or make to me hex file mega 2560 board or teensy and what version teensy i need orden ? how many analog teensy can add ?
mail me if can made to me hex file and /or descition to mega or teensy board. (we talk how much cost)

just has make ready arduino mega 2560 board whit 4x max 7219 chip led matrix board to use 5 digit 7-segment display (5digit x 4 radiopanel = 20 number) com nav 1 activ+standby and 2xchange button and 2xencoder have. easy made whit mobiflight software working fine.
but need analog axes too and mobiflight not support analog input.

my computer have WIN8, FSX gold edition, own radio panel, mobiflight software, fsuipc4,wideview,fs-panel,landing gears,many led and switch,annuincator,
future need made ADF,autopilot,yuoke,rudder,trottle,trim wheels,brake,etc.

Frank B
11-16-2016, 11:12 PM
i have at home some arduino mega 2560 board whit ch340 chip, can i use this or need me orden teensy or other board ?

The arduino mega can't do that. You need a Teensy.




how make description and compile to hex file ?

oh... it's not plug and play..you need some programming skills, of course.
Download Arduino, Teensyduino, and write the needed Software ;)




how burn hex file to possiple board ?

Press "upload" in Arduino.


or can somebody make me hex file what use ONLY maximum axes and slider what can add to board ?

What do you pay ? :-) :cool:

No, with a bit luck, maybe, someone from this forum is willing to help..

masawee
11-16-2016, 11:19 PM
What teensy version have best to me ? axis and slider analog input maxim ?
i looking teensy 3.2 have maximum input analog pin what can use,
can all use whit usb-hid to fsx ?

teensy have wery expensive VS, arduino mega have only under 10€ were have cheapen place orden teensy and what version(looking first guestion)

hmm, you mean arduino IDE ? what is teensyduino ? ok, teensyduino have addon -on arduino IDE, must loadin then have orden teensy 3.2.


Press "upload" in Arduino. mean arduino IDE ? burn bootloader or upload ino file. 2 different,


What do you pay ? :-) :cool: what u want :D

shit here not can orden teensy whit paypal :( no thanks, must looking ebay what have :(

No, with a bit luck, maybe, someone from this forum is willing to help..[/QUOTE]

My project photos https://drive.google.com/open?id=0B6fpBSKeeyqfOU03X2NyNnp3SEU
last have arduino mega fsx/x-plane radio panel com/nav 1

masawee
11-17-2016, 12:14 AM
ok, just looking what teensy can buy and there not can buy anythink not have paypal and ebay i glad have all up to 30-40€ wery expensive one chip same prize can buy 2 rasberry pi or 10 arduino board, huh :(
cheapen have only teensy 2.0 but have only 12 analog input :(
maybe this must orden only :(
all 3.X version what i looking ebay have ower 50€ too expensive , who buy if have 10 arduino board cost ?
same cost can buy better board leo bodnar buox card same cost. ower 50€ :(
and have ready to use no need burn own code.
were can buy cheapen 3.X version ??? i no have money vaste lot.
normal good prize have one board about 10€
maybe better i forget all teensy because not have any better than all arduino mega boards but expensive lot.

johan_16
11-27-2016, 02:37 AM
In case anyone else is following this Joystick thread, here's the latest code for Teensy 3.1. Just replace these 4 files in hardware/teensy/cores/teensy3 and your joystick will become 128 buttons, 6 axes, 17 sliders and 4 hats.

Hi.. I'm new in this forum, I'm looking for hardware that have so many botton and analog... I found this forum. but I dont know why, I can not download those file that you give...
is it still possible for me to ask those files (again).
thanks.

nb. sorry poor english..

Rolli.Berry
01-25-2017, 07:56 PM
Hi,
is there a way to accomplish the whole thing in the latest version of Teensyduino?

PaulStoffregen
01-25-2017, 09:44 PM
Ok, I've updated this code and merged it into the official core library.

https://github.com/PaulStoffregen/cores/commit/f5f05e9adee9ab9eca1ca83897e4114bf6e767fa

If you want to play with it now, you can get the updated files from github and put them into your copy of Arduino. Starting with 1.36-beta2 they will always be there by the installer.

To actually use this (after you have the new files installed), edit usb_desc.h. Change JOYSTICK_SIZE from 12 to 64. Remember, there's 4 copies for the different USB Types which use joystick. Edit the one you need, or all of them if unsure. I've set everything else to automatically adapt.

As always, on Windows your old USB device detection might be cached in the Windows Registry. You might need to increase the BCD version number or change the product ID or do other stuff to get Windows to re-detect the device.

konfu
02-06-2017, 10:36 AM
Change JOYSTICK_SIZE from 12 to 64.

What about the 128 buttons from the original version?

PaulStoffregen
02-06-2017, 10:58 AM
What about the 128 buttons from the original version?

Did you actually try using this yet?

All 128 button still exist. This JOYSTICK_SIZE define is the number of bytes for the entire HID report, not the number of any particular type of field within the report.

The 128 buttons use 1 bit each, so they consume only the first 16 of these 64 bytes. The many axes account for most of the report size.

kbral
03-03-2017, 03:06 PM
Hi Paul, i was searching a lot for the best setup for a 16bit flight controller, i was wondering does Extreme Joystick works with rotary encoders and rotary switches ??
I want to buy the Teensy 3.1 for the project, but i found mmjoy too that uses teensy 2++, so im a bit confused what is the best.
Since this thread is from a very long time, does extreme joystick have had any update ??
and... if i would like to use a bigger resolution like 20bit, can it be done on teensy 3.1 ?

thanks very much

PaulStoffregen
03-04-2017, 04:21 PM
i was wondering does Extreme Joystick works with rotary encoders and rotary switches ??

Teensy is about DIY electronics. The USB Joystick function (either standard or extreme) is meant to allow you to create such things.

You write relatively simple code in Arduino which reads whatever encoders or switches you like. When then change, you use the joystick functions to transmit joystick events. You could use pots instead of encoders. Or you could connect a ethernet module and allow network communication to send joystick events.

If you haven't already installed the software, get Arduino & Teensyduino. Select Teensy in the Tools > Boards menu (the other menus update based on the board). Then look at some of the examples, in File > Examples > Teensy > USB_Joystick and File > Examples > Encoder. To accomplish a project like this, you'll be copying bits of code from these examples. You can download the software and look at this code before buying anything, and doing so can give you a much better idea of how this all works. It's not a finished, fixed-function product. It's a system that allows you to create things.

Natefp
03-16-2017, 06:32 AM
Hi Paul,

I am using the USB Joystick Complete example (that comes with Teensyduino) for a custom joystick. The axes are X, Y, Z, Zrotate, sliderLeft, sliderRight. The joystick shows up like the attached pict under Windows 10. The second slider axis won't work in a game (Overload) and I suspect it is because they are both named slider. I have tried renaming sliderLeft and sliderRight to Xrotate and Yrotate in the .ino sketch, usb_joystick.h, and usb_api.h. I also changed joystick_report_desc in usb_desc.c and usb.c as follows:

Changed:
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)

To:
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)

After uninstalling the joystick under Device Manager and reinstalling it, it still comes up the same way with two sliders. Am I missing something?

Thanks in advance.

9988

PaulStoffregen
03-17-2017, 01:33 PM
It can be tough to get Windows to "forget" the prior info it stores about a USB device.

Usually the best thing is to increment the BCD version number in the USB device descriptor. Windows will see it's a newer version and re-read everything.

Natefp
03-17-2017, 05:53 PM
I did try incrementing the bcdDevice number (usb_desc.c, line 90), as well as the vendor ID and product ID and then flashed the firmware to the Teensy. Nothing made it reinstall the device short of going to device manager and right clicking on the correct USB composite device and uninstalling. In that case, after unplugging and plugging it in again, windows installed it fresh (however sliders still show as in the pict). Are there any other places other than the files I mentioned that need to be changed for the sliders to change to Rx and Ry? Thanks for your help!

zombierevel
03-27-2017, 05:15 AM
Ok, I've updated this code and merged it into the official core library.

https://github.com/PaulStoffregen/cores/commit/f5f05e9adee9ab9eca1ca83897e4114bf6e767fa

If you want to play with it now, you can get the updated files from github and put them into your copy of Arduino. Starting with 1.36-beta2 they will always be there by the installer.

To actually use this (after you have the new files installed), edit usb_desc.h. Change JOYSTICK_SIZE from 12 to 64. Remember, there's 4 copies for the different USB Types which use joystick. Edit the one you need, or all of them if unsure. I've set everything else to automatically adapt.

As always, on Windows your old USB device detection might be cached in the Windows Registry. You might need to increase the BCD version number or change the product ID or do other stuff to get Windows to re-detect the device.

Hello Paul, thank you for your work on this project, I am kind of new using the teensy boards since I just got my first one a week ago(teensy ++ 2.0) for a project and was afraid i will not have enough axis for it. Looking this project was from 2014 I was losing hope that i will be able to use it now.

This might be a dumb question but will this work with the teensy ++ 2.0? (I ask since the project was for the teensy 3.1 originally)

PaulStoffregen
03-27-2017, 02:42 PM
but will this work with the teensy ++ 2.0?

No, sorry, it's written for the new USB stack in Teensy LC & 3.x.

In theory, with enough work someone skilled with the USB code could rewrite it all for the older Teensy 2.x USB code. But in practice, that's very unlikely to ever happen...

zombierevel
03-28-2017, 02:13 AM
Well that's unfortunate, but thank you for your honest reply. Since Teensy boards arent sold here its kind of difficult to get one, and was only able to get a ++ 2.0. The cheapest Teensy 3.x seems to be at least close to 50$ so I think i will need to stay with the ++2.0 for some time, if the project goes well maybe i will be able to get another teensy and try this. If you dont mind me asking for future reference, if I would like to modify the files, what will be the hardest part? Modifying the HID descriptor?

PaulStoffregen
04-02-2017, 11:05 AM
Where is "here"? None of these distributors are close?

https://forum.pjrc.com/threads/23601-Official-Distributors

On porting, modifying the code is fairly easy. Getting it to actually work is the hard part! It'd be particularly difficult without a known-good board for comparison and a USB protocol analyzer so you can see what's actually communicated over the USB lines.

zombierevel
04-02-2017, 04:02 PM
Where is "here"? None of these distributors are close?

https://forum.pjrc.com/threads/23601-Official-Distributors

On porting, modifying the code is fairly easy. Getting it to actually work is the hard part! It'd be particularly difficult without a known-good board for comparison and a USB protocol analyzer so you can see what's actually communicated over the USB lines.

Thank you for the reply. Seems like its not an easy job for a noob like me, but fortunately i think i can get enough axis and buttons with the teensy ++ 2.0 for my project.
I am from Peru (South America). Doesnt seems like my region is supported, so best case I need to import from USA. But i think one of my friends is going to travel to USA so maybe I will be able to get a Teensy 3.2 from him.

MichaelMeissner
04-02-2017, 07:16 PM
If your friend is going to a city with a Microcenter (http://www.microcenter.com/), they often times have various Teensys for sale in a retail setting.

zombierevel
04-02-2017, 09:41 PM
If your friend is going to a city with a Microcenter (http://www.microcenter.com/), they often times have various Teensys for sale in a retail setting.

Great man, thank you for the information. Will tell him.

Technicus
11-21-2017, 02:18 AM
I have a similar question that I posted in a different thread: < https://forum.pjrc.com/threads/24433-Making-A-Custom-Teensy3-HID-Joystick?p=160215&viewfull=1#post160215 >. Instead of more axis and buttons, I am trying to understand how to make the device show up with less axis and fewer buttons. Does anyone have recommendations on how to do that?

KurtE
11-21-2017, 05:10 AM
I have not worked much with T2s, mostly know trying to add T3.6 host support... Including plugging in another Teensy... Including Joystick support.

But For the 3.x I would look in the file: D:\arduino-1.8.5\hardware\teensy\avr\cores\teensy3\usb_desc.c
Most likely your path will be different...
For this section:

#ifdef JOYSTICK_INTERFACE
#if JOYSTICK_SIZE == 12
static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x04, // Report Count (4)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x02, // Report Count (2)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0 // End Collection
};

I believe the line I put in RED above controls the number of buttons: in particular the 0x20 (which is 32)

The Number of Axis is a little more complicated, Some of the lines associated with it are in Green
That is for example you have the section, that defines X, Y, Z, Rz which there are 4 of them. (report count).

Likewise with sliders. Note: The HAT fields earlier in the report also probably show up as axis.

Again I have not looked at where it is defined for Teensy 2.0, but I would suspect it would be something similar.
On my system I believe it is in the file: D:\arduino-1.8.5\hardware\teensy\avr\cores\usb_hid\usb.c

Technicus
11-21-2017, 05:27 AM
Thanks,

The path on my machine is: '/usr/share/arduino/hardware/teensy/avr/cores/teensy3/'.
That file exists in the teensy3 directory, however there is no teensy2 directory.
Perhaps it defaults to the teensy directory, but the file is not in that directory.
Is it possible that the file in teeny3 is being used?
I'll make changes to the file, then flash a teensy 2 and see if it makes a difference.

Edit:

Okay, so I tried that, but I think I messed something up.
I think what I really want to do now, is peal back this obtuse layer of arduino abstraction and get a real sense of what is actually going on.
What is the bare minimum that I would need to compile and flash the teensy2 from a terminal?
What compiler do I need, what library files do I need?
What utility do I need to flash the compiled hex?
Again the goal is still to make a joystick, but I just want to understand what is going on and what files are absolutely necessary.

KurtE
11-21-2017, 02:28 PM
On my linux box: My arduino Installation is similar: kurt@kurt-UP-CHT01:~/Desktop/arduino-1.8.5/hardware/teensy/avr/cores$
Under that directory is teensy3 for the stuff I mentioned.

For a Teensy2, the sources are in the directory: teensy
As I mentioned in the first post, some of the USB code (usb.c) includes code from other directories for the different USB configurations. The code I mentioned associated with the joystick is in the directory: kurt@kurt-UP-CHT01:~/Desktop/arduino-1.8.5/hardware/teensy/avr/cores/usb_hid$
If you look in usb.c you will find the joystick HID descriptor.

However just changing the descriptors will not be sufficient. This tells the other side how the data is packed on the messages that follow from the logical joystick.
You then also need to update the usb_joystick_class which is in the usb_api.h and usb_api.cpp files in that directory to make the data match the format that you describe in the descriptor.

So again currently in the usb.c you have:

static const uint8_t PROGMEM joystick_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x04, // Report Count (4)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x02, // Report Count (2)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0 // End Collection
};

This translates into:
32 bits - Buttons
4 bits - Hat switch
10 bits for X (axis)
10 bits for y (axis)
10 bits for Z (axis)
10 bits for RZ (axis)
10 bits for Slider
10 bits for Slider
= 96 bits of data or 12 bytes.

So if you look at the usb_joystick_class you will see how it is packing all of the data into the appropriate areas of the report on a bit boundary. So if you change the report descriptor, you will need to pack the data in your new format...

Now as to the minimal stuff needed to build and program. There are several threads on forum on how to program using bare metal. You might do a search. I typically just install Arduino and Teensyduino and use it that way

TG626
12-17-2017, 07:06 AM
...snip...

However just changing the descriptors will not be sufficient. This tells the other side how the data is packed on the messages that follow from the logical joystick.
You then also need to update the usb_joystick_class which is in the usb_api.h and usb_api.cpp files in that directory to make the data match the format that you describe in the descriptor.
...snip...

I'm using a Teensy 2.0 and would dearly love 37 buttons. Could I add a byte to the buttons by:


Editing the descriptor
Editing usb_api.h by changing
extern uint8_t joystick_report_data[12]; to
extern uint8_t joystick_report_data[13]; and adding conditional code in the usb_joystick_class
else if (button < 40) joystick_report_data[4] |= mask;
Editing usb_api.cpp
UEDATX = joystick_report_data[12]; after line 662



Is that really all there is to it?

PaulStoffregen
12-17-2017, 09:18 AM
That's most of it. But you'll also need to alter all the writes to joystick_report_data[4] to joystick_report_data[11] to one index farther in the array, since you'll now be using joystick_report_data[4] for something else. Of course, if you add fewer than 8 buttons, you'll need to add a const field to the descriptor to fill up the rest of joystick_report_data[4] with bits the HID parser will ignore. Adding exactly 8 more is easiest.

If using Windows, don't forget to increment the BCD version. Windows loves to cache USB info in the Windows Registry, even when it's silly to do so because it has to read all that stuff anyway as it detects the device. If you don't increment the BCD version or change the VID or PID, Windows may happily ignore your changes and use the stale info from its registry.

lesoreilly
02-04-2018, 07:56 PM
Okay so I must be missing something or totally inept.

I have a 3.5 and trying to use the Extreme Joystick sample but it will not compile. I have updated to the most current Teensy software and also the current 1.8.5 IDE.

My guess is that I somehow now need to declare the joystick to be 64?? for it to use the correct portion of the USB Joystick. However where in the Extreme example that was posted many many moons ago do I put this and what is the correct syntax?

Again I am asking if I am missing something -- ie is there documentation besides the examples that come with Teensy that I am missing. Second would it be possible in the future updates to the Teensy to add the Extreme example that seems to now be working by others into the examples? So inanition to the Complete that works having an EXTREME as a 4th option?

Second -- sorry. How do you declare what pins are connected for the HAT? In the complete we just have auto updating data, but nothing explains how to setup Pins for a HAT.

Third -- yes again really sorry. When using the 3.5 the analog pins get setup where buttons would be (also pin 13 does not really work well as a button) Does anyone have an idea of what happens to pins above the Analog that are used? I can't seem to make Pins 24 and up into buttons.

PaulStoffregen
02-04-2018, 08:16 PM
You need to edit hardware/teensy/avr/cores/teensy3/usb_desc.h, within the Arduino folder. If using a Mac, control-click Arduino and "show package contents" to access the folder. On Windows and Linux, Arduino is just an ordinary folder. If you used the Windows installer, the default install location is C:\Program File (x86)\Arduino.

Find this line within the file.


#define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick

This line is actually repeated several times, for the different choices in Tools > USB Type which have Joystick. If you're unsure, edit ALL of them.

Just change 12 to 64 and save the file. Your next upload will build as the extreme joystick.

lesoreilly
02-05-2018, 05:15 AM
Okay thanks -- that was exactly the part I could not seem to sort out.

When I started "hacking" at the files I can say that I am getting it a little better.

On the 3.5 trying to figure out what decides the buttons and hat connections? I thought I found an example else where on how to "remap" the buttons but that did not seem to work. Basically I want to skip PIN 13 and have the buttons be from 0-12 then 14-32.

Thanks for the Info thus far

obzai
08-26-2018, 05:54 AM
I've recently started looking at using one of my Teensy 3.5 boards to build a game controller switch panel to supplement my T.Flight HOTAS X in Elite Dangerous.

When I first started entertaining the idea of custom switches I thought I might just make a simple switch panel for handling secondary (non-combat) commands much like many people before have already done, but now I'm starting to consider integrating it further with the T.Flight to opportunistically fix some of its design issues as well. The T.Flight has non-linear behaviour on the axes, with some pretty heinous deadzones around the neutral points. I've used vJoy to partially rectify the non-linearity but the only real fix for the deadzones will be to transfer the worst offending analog signals over to the Teensy so I can have full control over what's going on and leave the existing T.Flight factory electronics to continue handling what remains of the joystick (buttons, hats, etc), with both the T.Flight and the Teensy plugged into the PC over their own USB cables. This is not new ground, this forum post (https://forum.pjrc.com/threads/33371-Thrustmaster-T-Flight-Hotas-X-Teensy-MCU-mod-%28USB-Flight-Joystick-Throttle%29) shows me I won't be the first person to fix a T.Flight with a Teensy so it feels pretty safe so far. In fact I will most likely start here and build on DogP's work to adapt it for my own approach.

My question is this; If I set Tools > USB Type to "Serial + Keyboard + Mouse + Joystick" can I get a bit radical and add something like a rotary encoder into the mix and have the Teensy handle it with a Mouse.scroll() routine on top of the required joystick features? I have been starting to consider extra controls like adding an analog hat joystick for vertical and lateral thrusters alongside the existing joystick axes. If a rotary encoder will work I can think of some useful things to do with it so I might add that in as well. Before I go to the trouble of laying out a full design based on hopes and dreams, can anyone confirm that what I'm thinking would / would not be possible at the Teensy level? Elite Dangerous itself seems to be pretty flexible with control definitions, I've got the T.Flight set for all the obvious stuff (some through vJoy) but I also have a PS4 gamepad, mouse and keyboard defined simultaneously alongside for certain aspects of the control scheme and ED seems to just work with no real trouble. If the Teensy side can pass it to the PC I think(?) ED might simply be OK with it.


TLDR; Can anyone see any problems with trying to use a rotary encoder to act as a Mouse.scroll() wheel in a Teensy build of a hybrid mouse-keyboard-gamepad-mega-joystick with more than 8 axes?

GremlinWrangler
08-26-2018, 06:45 AM
You should be able to use mousewheel or other keyboard or mouse inputs this way. The limitations happen when you use an absolute UI element (like a pot) for scroll or a toggle switch for a button where you need output from the game about where it thinks UI elements are.

obzai
08-26-2018, 07:07 AM
Thanks GremlinWrangler, much appreciate the fast reply. Sounds like an understandable limitation.

I just fired up ED to confirm it will accept the traditional mouse scrollwheel for the inputs I'm considering using it on, so I might go ahead now and build a quick proof of concept Teensy + Encoder and test it out with that next. Before any holes get drilled in anything...

PaulStoffregen
08-26-2018, 11:43 AM
Can anyone see any problems with trying to use a rotary encoder to act as a Mouse.scroll() wheel in a Teensy build of a hybrid mouse-keyboard-gamepad-mega-joystick with more than 8 axes?

This should be possible. Certainly Teensy gives you the way to implement these HID interfaces and precisely control what actually gets sent to your PC.

To specifically answer your question, here are some challenges you might face.

If using Microsoft Windows, the default joystick driver might not recognize more than 8 axes, even though it's properly implemented on the Teensy side (assuming you've edited the code to enable the bigger HID joystick report - or otherwise edited the USB code).

In designing your code on the Teensy side, you'll want to avoid delays, so you're always being responsive to all the input signals. Simple as this sounds, real-world signals often aren't as nice as you might like and require "debouncing" or other techniques. Many people have gone down a path of adding delays in their code, which tends to work for only 1 signal, but then becomes really difficult when the delays to clean up 1 signal cause everything to be unresponsive to all the others. Teensyduino has features like elapsedMillis (https://www.pjrc.com/teensy/td_timing_elaspedMillis.html) to make this easier, so if you need to do this sort of work I recommend using those and avoid delay().

HID provides fixed bandwidth. At best you can send 1000 events per second. That's usually plenty, but it can quickly become a limitation if you do things inefficiently. The joystick functions have a way to freeze, so you can change multiple settings and have it all go out the USB cable to your PC as a single packet.

If you do approach the bandwidth limits, those functions to send will end up waiting. If using the Encoder library, you may see the result of several changes at once. Likewise for other inputs, if those functions have to wait, your code may be "blind" to changes. Teensy's USB stack does buffer several outgoing packets, which gives you some flexibility. But as a general rule, if you try to sustain close to or more than 1000 updates per second, you will run into HID bandwidth limits and ultimately your code will suffer waits in the transmit functions.

obzai
08-26-2018, 11:59 AM
Fantastic, thanks for the detailed reply Paul.

Sounds like I could reasonably expect to build something that will work using this approach. I'll see how I go.
Thanks for your work on the Teensy boards Paul, they're my favourite "do anything" solution. I always keep a couple on hand.

estark
09-12-2018, 08:40 AM
I tried to code a 8 axis joystick. I took the many axis joystick disabling all sliders beyond 2. Only data from the 6 axis are transmitted, sliders remain at zero
14715

nicodh
07-11-2019, 04:17 PM
Hello Paul, i replaced the files and now i'm getting a serial error, like it was not recognized:
"C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -D__MK20DX256__ -DTEENSYDUINO=144 -DARDUINO=10807 -DF_CPU=96000000 -DUSB_EVERYTHING -DLAYOUT_US_ENGLISH "-IC:\\Users\\NICOLA~1\\AppData\\Local\\Temp\\arduin o_build_113933/pch" "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teen sy3" "C:\\Users\\NICOLA~1\\AppData\\Local\\Temp\\arduino _build_113933\\sketch\\sbus2joystick.ino.cpp" -o "C:\\Users\\NICOLA~1\\AppData\\Local\\Temp\\arduino _build_113933\\sketch\\sbus2joystick.ino.cpp.o"
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_serial.h:34:0,

from C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/WProgram.h:54,

from C:\Users\NICOLA~1\AppData\Local\Temp\arduino_build _113933/pch/Arduino.h:6,

from C:\Users\NICOLA~1\AppData\Local\Temp\arduino_build _113933\sketch\sbus2joystick.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/usb_desc.h:297:48: error: 'NUM_ENDPOINTS' was not declared in this scope

extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS];

Any idea?
thanks

Brion Sohn
07-12-2019, 10:29 AM
I have a question.. I sort of asked this in another thread where I was pointed to here, so this will probably be a better place to ask this..

I have read through the thread and think I understand a bit about what is going on here but then again maybe not because I have never messed with this stuff..

Anyway, what I would like to do is Expand the USB HID Joystick interface to access at least 64 buttons, Maybe 128. Unlike most of the examples on here I am not really in need of extending the Axis Count, However I also need to retain serial functions for the device for other things I plan on doing.

I would LIKE TO do this to the Teensy LC as that is the primary device I am using, though I have noticed that most of this work has been done on the 3's so I am not sure of the possibility. I have located the USB headers information based on an earlier post but don't see anything specifically for the LC in there so any info on where to do adjustments would be helpful if it is even possible to do..

Because I am not familiar with HID headers pointers in where to research this or guidance on the changes would be greatly appreciated.

Thank you

KurtE
07-12-2019, 02:56 PM
I am no expert on this end of it. I have done more on the side of usbhost_t36 to try to handle different USB devices... I don't think there is much difference here between T3.x and TLC for this, they both use the teensy3 directory under cores.

But if I were doing it, I think some of the areas I would look to change include:

usb_desc.c - need to change the number of buttons... For example if you look for the JOYSTICK_SIZE==12 portion, you will see:

0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)

So would try changing those 0x20 (32) to the size you need. Note: That will change the JOYSTICK_SIZE. Each 8 bits will add 1 byte to the size...
So you may want to either modify these tables and/or make another copy #elif JOYSTICK_SIZE == <YOUR SIZE>

You will need to update usb_desc.h to have the new size for your joyststick data...

You will probably need to update usb_joystick.h to handle the additional buttons, that is the code again has specific code for size ==12 and == 64 again not knowing enough of which way you wish to start from (like how many axis) not sure which one is easiest for you to start from.

My guess is probably the 64 one as the ==12 assumes all of the buttons fit into one uint32_t value and all of the axis are aligned to the 32 bit starting memory locations... Actually both assume a certain alignment in memory for where the axis values are stored...

Again there are probably other things I am missing, but that is where I would start

Brion Sohn
07-12-2019, 06:48 PM
Yea that is my concern as in some ways it seems so simple , but is it really just a matter of changing the size of those parameters.. Thank you though on the information about the LC using the T3 core code as that one makes it seem feasible and two points me in the direction of the files to mess with..

I think I may be able to figure it out from there but if anyone else or you have any further information it is always appreciated.

Brion Sohn
07-12-2019, 07:27 PM
Oh Hmm.. It looks like Paul has included the code for the extreme Joystick IN the core data as I was just looking at the usb_desc.c in the teensy3/Core/avr and noted this:

"
#elif JOYSTICK_SIZE == 64
// extreme joystick (to use this, edit JOYSTICK_SIZE to 64 in usb_desc.h)
// 128 buttons 16
// 6 axes 12
// 17 sliders 34
// 4 pov 2
"

This will be beyond of course what I generally would need but hey seems much easier now

silco69
08-29-2019, 12:15 PM
Oh Hmm.. It looks like Paul has included the code for the extreme Joystick IN the core data as I was just looking at the usb_desc.c in the teensy3/Core/avr and noted this:

"
#elif JOYSTICK_SIZE == 64
// extreme joystick (to use this, edit JOYSTICK_SIZE to 64 in usb_desc.h)
// 128 buttons 16
// 6 axes 12
// 17 sliders 34
// 4 pov 2
"

This will be beyond of course what I generally would need but hey seems much easier now

Hi, your thread has helped me greatly in creating my own custom flight sim controls. I am having the issue of not being able to get more than 6 axis working at one time however and have tried tweaking the usb_joystick.h file with no success. I've tried the vanilla extreme joystick test and still cant get more than 6 axis working at once. Am I missing something here? Any help would be greatly appreciated!

- Silco

smee_ger_ac
09-19-2019, 06:19 AM
Hi, is it maybe possible to emulate an USB Hub and group the control axis like 4 throttle, pitch, mixture, oil & water cooler so that windows has no problem to find all axis, it would also make the settings in the actual sim easier? Thx

Hawky
10-08-2019, 06:37 PM
Somewhat of a newbie here. Planning on making a controller that is entirely standard aside from the addition of 6 more sliders.

I'm thinking of ordering a Teensy 4.0 just because. I haven't delved too deep into this thread yet, so I still barely know where to start, but I did see that everything here isn't compatible with Teensy 2.x boards, since it was done on 3.x. Will there be any compatibility problems if I were to do this on the 4.0?

Thanks

GremlinWrangler
10-09-2019, 09:32 AM
4.0 is very new, unsure how complete USB joystick support is. It also has ADC hardware that seems to take more effort to get good results out of. You certainly do not need the performance for this, so would suggest the LC or 3.2 would be a better fit. What may get complicated is your axis, and the number of them, both Teensy LC and 3.2 have only 10 analog inputs that are easy to access so 4 axis but two sliders will only just fit. You will also need to make decisions about how much hacking around you want to do making those 10 axis work. The less pretty solution may involve having two teensies sharing the axis in a more default configuration.

Certainly before buying anything would download and install https://www.pjrc.com/teensy/td_download.html teensyduino and put together some test code and make sure it compiles.

Abtzero
10-20-2019, 10:25 AM
I am trying to make a 64-Button Joystick since days, but I am stuck to compilation errors.
I used the Arduino IDE 1.8.9 with Teensyduino 1.47 and 1.8.10 with 1.48 on Windows 10 with a teensy 3.2.
In Tools set the USB Type to "Keyboard + Mouse + Joystick" and tried different values in "Optimize:".

I started with a simple Joystick .ino demo and the default headers and .c files in ...\teensy\avr\cores\teensy3 and I got a 32-Button Joystick.ok.
Then I replaced the 4 files of the .zip of post 36 of this thread into the teensy3 dir and got compilation errors which were similar to zeflor's of post #108.
I fiddled around (don't remember) until (after a change to a version which I already tried before) until it compiled without an error for the 1st time and I uploaded it to the teensy.
I got a 32-button joystick with the hat moving (from the .ino file of post #36).
The I tried to customize the header and .c files for my needs but got compilation errors again.
I always copied back the "original" files of post 36 and sometimes it compiled without an error.

The strange thing: After a successful compile I just added a whitespace in usb_desc.c behind a line-comment(!) and it gave me a compilation error. Restored the "original" file and got no error.

I also installed v1.8.10 and v1.48 on a Mac, used the 4 files of post #36 and go a compilation error (only one try).
Are the files no longer valid for the newer Arduino IDE/teensduino versions , since this thread is pretty old...?

All in all I never had a 128-button joystick (which the unchanged files of post #36 should give). It has always 32 buttons. (also by setting the value 64 (for extreme) instead of 12 (don't remember, where)

Question 1:
I believe there is a pre-compiler cache that causes this problem. I do not know, how to tell the IDE to do a complete new compile.
Deleting any files in my Windows profile?
Starting the IDE new before compiling does not help.

Question 2:
I fiddled around in lots of tries and managed it sometimes to upload it to the teensy. But in joy.cpl I saw no changes.
Except plugging it into a "fresh" PC and there I saw my custom name for the joystick (no longer "Keyboard/Mouse/Joystick").
Then I saw the notes in this thread (and in usb_dec.h), that Windows caches the joystick informations and won't show new capabilities or name until the version or PRODUCT_ID has changed.

But where to change the version in usb_desc.c?
Trying different things ended often with a compilation-error (see question 1) or did not change anything windows recognized as a new joystick...

Is it the line 86 which is untouched: 0x16, 0x01, // bcdDevice?

#endif
EP0_SIZE, // bMaxPacketSize0
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
0x16, 0x01, // bcdDevice
1, // iManufacturer
2, // iProduct
3, // iSerialNumber
1 // bNumConfigurations
};

changing to 0x16, 0x02 ? Or a different line?
How to count up a version-number?

Thanks in advance for Your help!

vjmuzik
10-20-2019, 10:56 AM
For question 2 the easiest way I find to do this with my midi devices is by changing the serial number, this is really simple for midi, but I don’t remember if it works for all devices types or not. For midi you can create a file called name.c in your project folder and this lets you change the manufacturer name, the product name, and the serial number.

Here’s an example of what that looks like:

// To give your project a unique name, this code must be
// placed into a .c file (its own tab). It can not be in
// a .cpp file or your main sketch (the .ino file).

#include "usb_names.h"

// Edit these lines to create your own name. The length must
// match the number of characters in your custom name.

#define MANUFACTURER_NAME {'O','p','e','n',' ','L','a','b','s'}
#define MANUFACTURER_NAME_LEN 9
#define MIDI_NAME {'N','E','K','O'}
#define MIDI_NAME_LEN 4
#define SERIAL_NUM {'F','a','d','e','r',' ','P','a','n','e','l'}
#define SERIAL_NUM_LEN 11

// Do not change this part. This exact format is required by USB.

struct usb_string_descriptor_struct usb_string_manufacturer_name = {
2 + MANUFACTURER_NAME_LEN * 2,
3,
MANUFACTURER_NAME
};

struct usb_string_descriptor_struct usb_string_product_name = {
2 + MIDI_NAME_LEN * 2,
3,
MIDI_NAME
};


struct usb_string_descriptor_struct usb_string_serial_number = {
2 + SERIAL_NUM_LEN * 2,
3,
SERIAL_NUM
};

Like I say, this may or may not work for anything other than midi but if it does it the easiest way to change things per project instead of messing with the core files.

Abtzero
10-20-2019, 11:34 AM
Well, I do not use the name.c file since it can be done in desc.h. But changing the MANUFACTURER_NAME or PRODUCT_NAME alone does not lead to a new devie in my case.
Anyway: Thanks for Your note, but I want to create a joystick, not a midi-device.c

But You statet: "...name.c in your project folder".
I try to put the customized core files into my project folder; but have no hope...

vjmuzik
10-20-2019, 11:56 AM
Indeed changing the name is not enough, it’s when the serial number gets changed that the device is registered as new so the existing cache from the old number isn’t used. Changing the serial number is also what you have to do to connect multiple of the same device types, devices are assigned by their serial numbers so everything else can be the same but the serial number has to be different between each device. That applies to all devices and not just midi, although this tends to come up more for midi devices in this forum since it’s more common to need to connect multiple to one system. So just changing the serial number is enough to get the device registered as “new” without having to delete any kind of cache files from the system and is the simplest way to do so.

Abtzero
10-20-2019, 03:44 PM
Ok, I get a new configuration by editing the VENTOR_ID in usb_dec.h now (counting up in hex 0x16yy, yy= is now D3)
But I never get a Joystick that has more buttons than 32.

I had to make 2 changes to let it compile without errors:
in usb_desc.h I had to make the changes of zeflor's of post #108, to get no error
"...usb_desc.h:304:3: error: conflicting declaration 'typedef struct usb_descriptor_list_t usb_descriptor_list_t'"


#ifndef _usb_dec_t
#define _usb_dec_t
extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS];

typedef struct {
uint16_t wValue;
uint16_t wIndex;
const uint8_t *addr;
uint16_t length;
} usb_descriptor_list_t;

extern const usb_descriptor_list_t usb_descriptor_list[];
#endif

But I am not sure, if that is a proper solution.

To get no error "TX_TIMEOUT is undefined", I had to bring the hole block of if-statements of the newer original file usb_joystick.c

#define TX_TIMEOUT_MSEC 30
#if F_CPU == 256000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1706)
#elif F_CPU == 240000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1600)
#elif F_CPU == 216000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1440)
#elif F_CPU == 192000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1280)
#elif F_CPU == 180000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1200)
#elif F_CPU == 168000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 1100)
#elif F_CPU == 144000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 932)
#elif F_CPU == 120000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 764)
#elif F_CPU == 96000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596)
#elif F_CPU == 72000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 512)
#elif F_CPU == 48000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428)
#elif F_CPU == 24000000
#define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262)
#endif

So it compiles now.
But I do not get more than 32 buttons. Due to the typedef struct which only will defined when #ifndef _usb_dec_t?

And the hat does not move in a circle in joy.cpl, in the .ino the code is unchanged:

// make the hat switch automatically move in a circle
angle = angle + 1;
if (angle >= 360) angle = 0;

Joystick.hat(1, angle);
Joystick.hat(2, angle);
Joystick.hat(3, angle);
Joystick.hat(4, angle);

Joystick.send_now();

(yesterday it was working...)

Abtzero
10-21-2019, 12:04 PM
Oh man,
it was working all the times (when having a successfull compile!
Some pages older I saw a screenshot from Pointy of a diagnostic tool showing 128 buttons. I just looked at the thumnail in the post and thought, this would be the UI of joy.cpl of Win7.
I just testet with joy.cpl and only saw 32 buttons...
No! It may look like joy.cpl but it is Pointy's Joystick Test!
Loading this one and testing my teensy is showing my 64 I defined. Yeah!
2 days of senseless debugging...

Now I can work in my sketch for 8 encoders and 48 buttons.
I will post it, when it's done to share my way to deal with the encoders

TwoDogs
10-21-2019, 10:38 PM
Congrats,
Look forward to seeing that script.

Dran
03-23-2020, 12:27 PM
Hi everybody! Sorry for the marketing of another thread, but I thought it'd be better than a proper hijack :). Initially I was hoping to make a "translation" of a radio controller to USB gamepad/joystick, by utilizing 12 of the many axis provided here. But then I found out from the thread that this code won't work on a teensy 2.0. Google brought my to Les "Pointy"'s blog post (http://www.planetpointy.co.uk/custom-teensy-2-0-joystick/)on the subject of a custom Teensy++ 2.0 joystick, and based on that I started this thread (https://forum.pjrc.com/threads/60122-Teensy-2-0-12-axis-joystick-gamepad?p=233645#post233645) to ask for your guidance on my project, and hopefully it will be of use to other as well!

Sparrowhawk120
05-05-2020, 06:53 PM
Hello! I've been trying to use this forum to make a joystick, and have run into the issue that while using the modified descriptors I can't use the slider!
The code inside the loop is
Joystick.slider(0,analogRead(0));
delay(50);
I set the read resolution to 16 bit, and the pinmode to input_pullup
What is wrong here?

EDIT: note that the exact same circuit works when I change from using a slider to using the X, Y, or Z axes

Sparrowhawk120
05-06-2020, 03:43 AM
I solved my issue, I was unaware that number 17 corresponded to slider 0, makes no sense to me :/

GMachineRC
05-13-2020, 04:59 PM
In case anyone else is following this Joystick thread, here's the latest code for Teensy 3.1. Just replace these 4 files in hardware/teensy/cores/teensy3 and your joystick will become 128 buttons, 6 axes, 17 sliders and 4 hats.

Have you updated these files to suit the Teensy 4.0?
If so, will they allow the correct use of analogReadResolution to set the 16bit setting?

edemers
07-04-2020, 09:00 AM
Hi Paul,

first of all thank you for this excellent extreme joystick support.

I am using 13bits for my axes and its working quite nicely.

I was wondering if there was any progress on a tester for Windows 10. The default one in control panel doesn't show all sliders, buttons etc.

Cheers,
E.

edemers
07-08-2020, 11:41 AM
Hi Guys,

Because of compatibility issues with my target software, I had to get rid of 64 buttons and the top hat switches.

After pulling my hair our for 3 days not knowing much about how usb descriptors worked, I finally got it sorted. I could not have figured it out without all your posts so thank you very much.

Here is my code so anyone who needs it can use it.

In usb_joystick.h add

#elif JOYSTICK_SIZE == 54
void button(unsigned int num, bool val) {
if (--num >= 64) return;
uint32_t *p = usb_joystick_data + (num >> 5);
num &= 0x1F;
if (val) *p |= (1 << num);
else *p &= ~(1 << num);
if (!manual_mode) usb_joystick_send();
}
void X(unsigned int position) { analog16(0, position); }
void Y(unsigned int position) { analog16(1, position); }
void Z(unsigned int position) { analog16(2, position); }
void Xrotate(unsigned int position) { analog16(3, position); }
void Yrotate(unsigned int position) { analog16(4, position); }
void Zrotate(unsigned int position) { analog16(5, position); }
void slider(unsigned int num, unsigned int position) {
if (--num >= 17) return;
analog16(num + 6, position);
}

and also at the end.

#if JOYSTICK_SIZE == 54
void analog16(unsigned int num, unsigned int value) {
if (value > 0xFFFF) value = 0xFFFF;
uint16_t *p = (uint16_t *)(&usb_joystick_data[2]);
p[num] = value;
if (!manual_mode) usb_joystick_send();
}
#endif

Note the position of the data has shifted because I reduced the buttons from 128 to 64

in usb_desc.h, change the joystick size

#define JOYSTICK_SIZE 54

In usb_desc.c, add the following

#elif JOYSTICK_SIZE == 54
// delta joystick (to use this, edit JOYSTICK_SIZE to 54 in usb_desc.h)
// 64 buttons
// 6 axes
// 17 sliders
static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x40, // Report Count (128)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x40, // Usage Maximum (Button #128)
0x81, 0x02, // Input (variable,absolute)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 0x17, // Report Count (23)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0xC0 // End Collection
};

Cheers,
E.

antares190
08-24-2020, 01:02 PM
Hi, I'm trying to create a custom class so to use a custom device (pretty similar to JOYSTICK_INTERFACE, but with different bit resolution, for few axes, and few more buttons).
The first step I did was modifying the JOYSTICK_INTERFACE (in usb_desc.c), and usb_joystick.c and usb_joystick.h, and everything is working as expected (axis and buttons are recognized).

So I created my custom usb_cougar.c, and usb_cougar.h, which mirrors usb_joystick.c and usb_joystick.h, and modified :
* usb_desc.c
* usb_desc.h
* boards.txt
* usb_inst.cpp
* WProgram.h

The Arduino app shows the new entry "Cougar", under Tools--> USB Type ... But when I compile and upload, it something gets broken (fails to connect to the usb device and returns the error below).


No Teensy boards were found on any USB ports of your computer.
Please press the PROGRAM MODE BUTTON on your Teensy to upload your sketch.

So: question time:
* Am I missing some file that needs to be modified?
* Is it possible to have an USB_TYPE which is only a plain JOYSTICK and not a sort of hub/group of (Serial)+Keyboard+Mouse+Joystick?
* Is it possible to change the names of the axis which are shown in Windows, (e.g. to something more appealing than Rx Ry Rz)?


BTW thanks for the very interesting info in this post!

Brion Sohn
08-25-2020, 02:35 AM
OK So I have been reading over this thread again since it has been a while since changing my descriptors to use the Extreme Joystick but I have only been using the 128 buttons and nothing else at the moment..

However I have a couple of questions as I wasn't to move into using the axis and possibly sliders (not sure if those will work on the primary programs I use) but in any case my question has to do with the relation of the hardware to the Profiles.

I am currently using the Teensy LC for my system but I was trying to figure out how the Hardware input to the Joystick actually relates as from what I understand the ADC's only put out a value of 1024 (-512 / +512) but the joystick will of course output 16bit.. So my understanding is essentially even though the the joystick is reporting 16bit because the ADC is only at 10 bits the DC is the bottle neck..

Im trying to figure out by what method I might get a true 16 bit signal or if it is even possible..

Thank you

antares190
08-25-2020, 08:01 AM
As far as I understand, considering that you are using the Teensy LC, according to tech specs (https://www.pjrc.com/teensy/techspecs.html), you are limited to 12bit max (its ADC has an usable resolution of 12bit).

You may change the resolution of the analogRead, with analogReadResolution(desired bit), so analogReadResolution(12) at most for Teensy LC. That's the raw data, as far as what you pass to the Joystick class, it really depends on how your code is implemented.

So I would say that with the Teensy LC there is a limitation to 12bit raw signal, while, then you may map it / modify it, smooth it within Arduino.

Ultimately, on the OS side, it expects a sequence of data, formatted according to the contents of usb_desc.c (JOYSTICK_INTERFACE or the interface you are using), so if it expect 16bit data, it will read (at most) 16bit data for the axis.

Just my 0.02$.

Brion Sohn
08-25-2020, 09:17 AM
As far as I understand, considering that you are using the Teensy LC, according to tech specs (https://www.pjrc.com/teensy/techspecs.html), you are limited to 12bit max (its ADC has an usable resolution of 12bit).

You may change the resolution of the analogRead, with analogReadResolution(desired bit), so analogReadResolution(12) at most for Teensy LC. That's the raw data, as far as what you pass to the Joystick class, it really depends on how your code is implemented.

So I would say that with the Teensy LC there is a limitation to 12bit raw signal, while, then you may map it / modify it, smooth it within Arduino.

Ultimately, on the OS side, it expects a sequence of data, formatted according to the contents of usb_desc.c (JOYSTICK_INTERFACE or the interface you are using), so if it expect 16bit data, it will read (at most) 16bit data for the axis.

Just my 0.02$.

That was sort of what I was thinking is that re-mapping would give me the 16bit to the computer but in REALITY it would only be 10bit with maybe some interpolation algorithm (which I will need to look into as that will be new for me) as the actual RAW would only be 10 bit (using default).. Thank you for the tip on the 12bit though as I didn't realize that as that will give me a bit more raw resolution.. So that is a hel, Thank you..


ANOTHER QUESTION: (though you sort of asked the same question above.. so for someone else :-) )

What might be done to the USB header file if I wanted to remove the Keyboard and Mouse functionality so that ONLY Joystick and Serial are used.. I really kind hate that my device in the end shows up as a Keyboard in windows, but, I can't just use Joystick as I need Serial for some other communication and as well I found that having the Serial as well is the ONLY way to get Windows to recognize a custom device name.

antares190
08-27-2020, 01:53 PM
Ok, I managed to find the error of my implementation, as it was related to one of the question I arose, I thought of reporting it here, as if you are going to implement your own joystick it may be of use.

All the additions/modifications were fine, but since I took as reference the "Serial/Keyboard/Mouse/Joystick" interface, it had a lot of stuff (I'm not really interested in having), among them:

KEYMEDIA_INTERFACE

The problem is that its KEYMEDIA_INTERFACE_DESC_POS is defined taking into account MTP_INTERFACE_DESC_POS, which in turn is defined taking into account JOYSTICK_INTERFACE_DESC_POS+JOYSTICK_INTERFACE_DES C_SIZE, so I simply had to add my interface size to the MTP_INTERFACE_DESC_POS definition.


#define COUGAR_INTERFACE_DESC_POS SEREMU_INTERFACE_DESC_POS+SEREMU_INTERFACE_DESC_SI ZE
#ifdef COUGAR_INTERFACE
#define COUGAR_INTERFACE_DESC_SIZE 9+9+7
#define COUGAR_HID_DESC_OFFSET COUGAR_INTERFACE_DESC_POS+9
#else
#define COUGAR_INTERFACE_DESC_SIZE 0
#endif


#define MTP_INTERFACE_DESC_POS JOYSTICK_INTERFACE_DESC_POS+JOYSTICK_INTERFACE_DES C_SIZE+COUGAR_INTERFACE_DESC_SIZE
#ifdef MTP_INTERFACE
#define MTP_INTERFACE_DESC_SIZE 9+7+7+7
#else
#define MTP_INTERFACE_DESC_SIZE 0
#endif



So I have a question: is it possible to have a simple USB_JOYSTICK_INTERFACE, with only the joystick? Or how can I drop keyboard, keymedia and mouse (I can live with Serial or SerialEmulation, as it is very handy)?

Thanks

greg_susie
09-21-2020, 03:55 PM
I have a Teensy 4.1 controller. Is there a version of the "extreme_joystick_test3.zip" that supports the 4.1? I tried coping the following files (usb_desc.h, usb_joystick.c, usb_joystick.h and usb_desc.c) into the Teensy 4 folder but this caused compile errors. When I compare the v3 to v4 there are significant changes to the files. Any support would be appreciated...

KurtE
09-21-2020, 05:03 PM
Did you try simply editing the one file/line I mentioned in the other thread? I believe that all of this stuff has been included in the main USB stuff when you set the JOYSTICK_SIZE to 64...

And I would expect these files to be reasonably different between T3.x and T4.x... Also the one in the zip file is a lot behind the one that currently installs for T3.x.

Barglab
10-30-2020, 01:30 AM
Hi everyone, newguy here.

It's been about a week since I started this lil project of mine on Teensy 4.0: a small panel that goes on top of my throttle with a total of about 42 inputs, 4 of which sliders.
Problem is I can't seem to go over that 32 inputs max that windows can detect with the controller properties.
I was looking into how to edit the .ino files to increase the max number of inputs, but (my bad move) I just copied over what was posted previously for the Teensy 3.6.
So now I'm getting those compile errors that someone else also got.

My question here is:
Where can I get the original .ino files to go back to normal and start editing them manually one by one?
Can I just reinstall the Teensyduino addon?

Cheers

Barg

giliep
11-01-2020, 08:55 PM
Hi,

I would love to get some help setting this up on Platform IO.
I don't understand what is the process to get the Mouse+keyboard+gamepad+joystick option like you choose in the arduino ? (are those the build flags? or are they a library?)
once this is installed, where can i find the files to change?
* usb_desc.c
* usb_desc.h
* boards.txt
* usb_inst.cpp

I would really like to use Teensy with PlatformIO but if i won't have a choice i'll revert to the arduino IDE...

Thanks.
P.S.
Would the many joystick axis work on the 3.5 teensy?

thebigg
11-02-2020, 12:35 AM
See this link (https://docs.platformio.org/en/latest/platforms/teensy.html#platform-teensy) for a list of all the Teensy specific entries you can put in your platformio.ini to configure the build output

giliep
11-02-2020, 08:19 PM
See this link (https://docs.platformio.org/en/latest/platforms/teensy.html#platform-teensy) for a list of all the Teensy specific entries you can put in your platformio.ini to configure the build output

Hi thebigg. thanks a lot for the help. I understood the problem with the this thread https://forum.pjrc.com/threads/64225-Newbie-on-PlatformIO-with-Teensy?p=258158#post258158

giliep
11-02-2020, 08:25 PM
I've updated the JOYSTICK SIZE from 12 to 64 but the arduino compiler yells this:


Complete:41: error: 'class usb_joystick_class' has no member named 'sliderLeft'
Joystick.sliderLeft(analogRead(4));


This is the example code... how's that possible?

any explanation for the reason?

giliep
11-02-2020, 11:15 PM
Tried to edited the Previous post But couldn't do it...

Pual - i'm trying different Vendor ID and Product ID, but i can't get the Joystick to show 128 buttons.

Do you have any suggestion about what's going on?
Could windows/Microsoft blocked the option?

PaulStoffregen
11-02-2020, 11:34 PM
i'm trying different Vendor ID and Product ID, but i can't get the Joystick to show 128 buttons.

Do you have any suggestion about what's going on?

USB descriptors and HID report descriptors and report data size are tricky to get correct.

Maybe try running the USB-IF command verifier program, which will read & check all your descriptor data. It's a free download from www.usb.org. But beware, it temporarily replaces the Windows USB host controller driver. If you have an extra "clean" Window system, best to run it there rather than on a "well used" Windows machine. If testing at 12 Mbit, it requires a real USB hub between your PC and the device you're testing. That fact is mentioned in the documentation but easy to overlook.




Tried to edited the Previous post But couldn't do it...

This forum allows 2 hours to edit your message. It's mostly an anti-spam policy. Some spammers (or their bots) will post short context-free messages which look like ordinary but somewhat confused conversation, then weeks or months later edit them to become spam. We've also had a couple cases years ago where a person got frustrated and edited all their messages after engaging in a conversation, leaving the whole thing a big mess. Spam is the much larger ongoing problem, but for both these reasons we set the policy at 2 hours years ago. If it's been longer than 2 hours, just post another message.

giliep
11-02-2020, 11:54 PM
USB descriptors and HID report descriptors and report data size are tricky to get correct.

Maybe try running the USB-IF command verifier program, which will read & check all your descriptor data. It's a free download from www.usb.org. But beware, it temporarily replaces the Windows USB host controller driver. If you have an extra "clean" Window system, best to run it there rather than on a "well used" Windows machine. If testing at 12 Mbit, it requires a real USB hub between your PC and the device you're testing. That fact is mentioned in the documentation but easy to overlook.

Hi Paul,

Thanks for the answer.
I've tested it with pointy software, which shows 128 buttons, 7 sliders and 4 hats.
So what's wrong with windows? why cant it show the correct joystick?

I've went from the 128 button to 32 button and pointy software showed the correct settings.

Is it something in windows that needs to be configured?


If testing at 12 Mbit, it requires a real USB hub between your PC and the device you're testing.

I'm not sure i fully understand...

i do have a virtual system to run it on... i'll try.

I also tried to run it on my wife windows laptop, but i didn't see it either there.

Do you think games will show the correct joystick configuration?

PaulStoffregen
11-02-2020, 11:59 PM
So what's wrong with windows? why cant it show the correct joystick?

Oh I can't even begin to tell you how many times I've asked this exact question. I'll create a USB thing and it works great in Linux and Macintosh, but Windows won't touch it.

These problems usually come in 2 varieties.

1: Something is wrong with your descriptors which Linux accepts, but Windows does not. The USB-IF verifier software really helps for this case.

2: Your device fully complies with USB standards, but Microsoft simply does not use it with built-in drivers.

giliep
11-03-2020, 12:14 AM
I'll try with the USB-IF program (i didn't see any download on the link you shared)

and i'll try on the Mac. What is the Mac's "Game controller"?

Ashamed to say i've never used it and i own a Mac for 10 years.

OK. I've downloaded a software called "Controller Lite" and it identifies the joystick as expected.

F#$#$%#$% you Windows... Almost sleepless night

PaulStoffregen
11-03-2020, 12:20 AM
Here is their downloads page.

https://www.usb.org/documents?search=&category%5B%5D=50&items_per_page=50

You want "USB20CV". Read the documentation. It works only on a narrow range of PC hardware.

giliep
11-03-2020, 12:23 AM
Here is their downloads page.

https://www.usb.org/documents?search=&category%5B%5D=50&items_per_page=50

You want "USB20CV". Read the documentation. It works only on a narrow range of PC hardware.

Thank you vary much!

I'll update back how that went.

Marco67
11-05-2020, 11:04 AM
I'm trying in every way to create a joystick with 8 axes and 8 buttons working, based on on the excellent Extreme Joystick (size 64).
I use a 16 channels SBUS receiver connected to the Teensy, I can make everything work but one of the two declared sliders it doesn't work, I correctly see two sliders in the Windows panel but it only interacts with channel 7 of the rx (mapped on analog 6), the second slider on channel 8 (analog 7) does not work.
All the other 15 of the 16 SBUS channels work, only that damn slider on rx channel 8 stays at half scale.

Portion of the .ino code:




{
sbus_data_t* c = &controllerState;
for(int i = 0; i < 8; i++)
Joystick.slider(i+1,millis());
Joystick.X(mapAnalog(c->analog[0]));
Joystick.Y(mapAnalog(c->analog[1]));
Joystick.Z(mapAnalog(c->analog[2]));
Joystick.Xrotate(mapAnalog(c->analog[3]));
Joystick.Yrotate(mapAnalog(c->analog[4]));
Joystick.Zrotate(mapAnalog(c->analog[5]));
Joystick.sliderLeft(mapAnalog(c->analog[6]));
Joystick.sliderRight(mapAnalog(c->analog[7]));

Joystick.button(1, c->analog[8] < 0);
Joystick.button(2, c->analog[9] < 0);
Joystick.button(3, c->analog[10] < 0);
Joystick.button(4, c->analog[11] < 0);
Joystick.button(5, c->analog[12] < 0);
Joystick.button(6, c->analog[13] < 0);
Joystick.button(7, c->analog[14] < 0);
Joystick.button(8, c->analog[15] < 0);
Joystick.send_now();
}



usb_joystick.h:




void X(unsigned int position) { analog16(0, position); }
void Y(unsigned int position) { analog16(1, position); }
void Z(unsigned int position) { analog16(2, position); }
void Xrotate(unsigned int position) { analog16(3, position); }
void Yrotate(unsigned int position) { analog16(4, position); }
void Zrotate(unsigned int position) { analog16(5, position); }
void sliderLeft(unsigned int position) { analog16(6, position); }
void sliderRight(unsigned int position) { analog16(7, position); }
void slider(unsigned int num, unsigned int position) {
if (--num >= 17) return;
analog16(num + 8, position);



usb_desc.c:




#elif JOYSTICK_SIZE == 64
// extreme joystick (to use this, edit JOYSTICK_SIZE to 64 in usb_desc.h)
// 128 buttons 16
// 6 axes 12
// 17 sliders 34
// 4 pov 2
static uint8_t joystick_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x80, // Report Count (128)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection ()
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 23, // Report Count (23)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
0x09, 0x35, // Usage (Rz)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0xC0 // End Collection



Where am I doing wrong?

Marco

Marco67
11-06-2020, 10:22 AM
I solved, both sliders are working now.

giliep
11-08-2020, 09:02 AM
I solved, both sliders are working now.

Can you share what was the problem and how did you solve it?

Marco67
11-08-2020, 05:10 PM
I appropriately modified the usb_desc.c.

giliep
01-17-2021, 09:41 PM
I'm trying to use 2 hat switches and i'm not sure i'm using the command correctly.

Should it be:

Joystick.hat (1,angle) for hat #1
Joystick.hat (2,angle) for hat #2

Am i doing it right?

in the usb_joystick the hat function is as follows:



inline void hat(unsigned int num, int angle) {
uint32_t val=15;
if (angle > 0 && angle < 23) val = 0;
else if (angle < 68) val = 1;
else if (angle < 113) val = 2;
else if (angle < 158) val = 3;
else if (angle < 203) val = 4;
else if (angle < 245) val = 5;
else if (angle < 293) val = 6;
else if (angle < 338) val = 7;
else if (angle < 360) val = 0;
uint32_t *p = usb_joystick_data;
switch(num) {
case 1:
p[15] = (p[15] & 0xFFF0FFFF) | (val << 16); break;
case 2:
p[15] = (p[15] & 0xFF0FFFFF) | (val << 20); break;
case 3:
p[15] = (p[15] & 0xF0FFFFFF) | (val << 24); break;
case 4:
p[15] = (p[15] & 0x0FFFFFFF) | (val << 28); break;
default:
return;
}