Jump to content

an Arduino USB HID controller, composite USB controller


overpro

Recommended Posts

hello overpro, thanks for your work :D

I followed everything, and the computer recognized the arduino as 2 game controller. I started to test with a button. I thought I just need to connect a collum and a row by a wire and the buttion should be on, I am right ? There no light on the game controller test

One more question: Is that true that we must use the 1N4148 diode ?

Thanks :)

12038391_767577396685384_8778688126682794205_n.jpg?oh=3ecb15d8c6a3d01c4e369aad09a20a29&oe=569FCDA9


Edited by dubalucu
insert the image
Link to comment
Share on other sites

hello overpro, thanks for your work :D

I followed everything, and the computer recognized the arduino as 2 game controller. I started to test with a button. I thought I just need to connect a collum and a row by a wire and the buttion should be on, I am right ? There no light on the game controller test

One more question: Is that true that we must use the 1N4148 diode ?

Thanks :)

12038391_767577396685384_8778688126682794205_n.jpg?oh=3ecb15d8c6a3d01c4e369aad09a20a29&oe=569FCDA9

 

i think you are right, but my 2560 havn't login in DFU mode, so i havnt test it yet.

 

i just pruchased USBISP for bootloader on my 2560.

Link to comment
Share on other sites

Hi dubalucu,

In reply to your post # 127:

Initially I thought you might have gone out of range on the Windows Game Controller window (which will show buttons for each CVP Joystick but only upto # 32). But when I connected your particular combination of pin #31 and pin # 39, I got a light on the second CVP Joystick, button # 18. This was visible in both Windows Game Controller and SVP Mapper.

Of course, I am using diodes, but I think you should be okay without it if you're testing just a single pair of pins (single button).

Please correct me if I am wrong.

CK.


Edited by tomahawk66
Link to comment
Share on other sites

For start , Thanks for your work overpro ;-)

 

I wanted to know if there are a simple possibility to include led control ?

The idea is to light on a led when you push a momentary switch and and light off when you push it a second time ( for know the state of the command you push).

 

for information, i start to make a front panel of my homemade play seat for Star citizen.

 

Thanks for your answer.

 

This might be a little bit complex, to achieve the effect you described the USB device firmware need to implement an OUTPUT endpoint so the device can receive data from an application running on the PC.

Write this application is not straight forward.

 

To control a single LED on or off there are 2 approaches, use a max7219 or use the scan matrix.


Edited by overpro

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

This is exactly what im looking for.

 

I was looking for an inputmodul, which gives me really much buttons as Joystick for the PC.

 

So without the timelimited pins i have calculated about 192 usable buttons.

I am building a Pad, which has 100 Buttons, needed for Star Citizen.

 

So my question:

Is there any way to use pin 2 - 21 and pin 54 - 69 for LEDs if Joystick button 32 upwards are toggled, to light those LEDs?

 

Just for visual information, to know Gear is down or Hatch is open or something like this.

Because the first buttons wont work as buttons, they are just for toggle-switches, which i dont need.

 

 

And Pins 54 - 69 are those Analog-Inputs, which can be used to digital outputs, too. I dont need any analogue axes.

 

 

http://forums.eagle.ru/showpost.php?p=2480775&postcount=130

 

 

some of the pin from Pin 2-21 can be used as digital output pins so they can be used as the LED scan matrix pin.

 

But if you want to use this board to control the LED there are more works to do: writing an application running on PC and extract and send StarCitizen's data to this USB device through USB protocal.

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

hello overpro, thanks for your work :D

I followed everything, and the computer recognized the arduino as 2 game controller. I started to test with a button. I thought I just need to connect a collum and a row by a wire and the buttion should be on, I am right ? There no light on the game controller test

One more question: Is that true that we must use the 1N4148 diode ?

Thanks :)

12038391_767577396685384_8778688126682794205_n.jpg?oh=3ecb15d8c6a3d01c4e369aad09a20a29&oe=569FCDA9

You can use the wire to test the button, but note that the first 4 rows (pin 22~25) are reserved for rotary encoders, so use pin 26 instead.

 

You have to use joysticktest: http://www.planetpointy.co.uk/download/5/

because windows default joystick tool only shows the first 32 buttons.

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

  • 3 weeks later...

I really appreciate this job, it works really good with my project! Thanks Overpro. I tested the Analogs and they worked, the buttons work ok too. Didn't tested the rotary encoders yet

 

But i had a crazy idea.. would it be possible to use an old mouse (the PS2 ball mouse) as a rotary encoder? The ball mouse works with an arduino, but i don't know if it would with this Project

 

Also, it's possible to use at the same time the axis and the rotary encoders?

 

Thanks

Link to comment
Share on other sites

Hi Overpro,

 

Thank you ever so much for your fantastic contribution. I have successfully tested your code with encoders and switches in FSX, and everything works as intended.

 

Now, if one uses FSUIPC LUA one can actually access upto 256 inputs per HID controller. This would be a better solution for FSX-FSUIPC (rather than the present 128 x 2) as then there would be no possibility of the software wrongly identifying the joystick involved (as might happen now with 2 joysticks labelled cvp joystick).

 

So my question is whether there is a simple way of modifying your code to achieve this? As I am not an expert programmer, would you or anyone else be willing to do this and offer this as an alternative?

 

Thank you once again!


Edited by tomahawk66
Link to comment
Share on other sites

@RightStuff,

 

I had the same question, so after some experimentation, was able to draw up the following scheme and 'formulae':

 

Mega2560 R3, digital pin 22 ~ 37 connected to row 1 ~ row 16

digital pin 38~53 connected to column 1 ~ column 16

(please note I use 1 ~ 16 rather than 0 ~ 15)

 

Scheme: rows (1 to 16) x cols (1 to 16) = 256 points

cvp1 = first cvp joystick in svp mapper / pointy joystick test

cvp2 = second cvp joystick in svp mapper / pointy joystick test

 

ENCODER: row used for common connection, column used for diode connection

BUTTON: row used for straight (= non-diode) connection, column used for diode connection

 

 

rows (1 to 4) x cols (1+2 to 15+16) reserved for encoder_buttons [1+2 to 63+64]

rows (5 to 16) x cols (1 to 16) reserved for button [65 to 256], or, button [65 to 128, 1 to 128]

 

_____________________________________________________

 

row 1 col 1+2: cvp1.encoder_buttons 1+2

row 1 col 3+4: cvp1.encoder_buttons 3+4

.

.

row 1 col 15+16: cvp1.encoder_buttons 15+16

row 2 col 1+2: cvp1.encoder_buttons 17+18

.

.

row 4 col 15+16; cvp1.encoder_buttons 63+64

 

formula is cvp1.encoder_buttons [16*(row-1) + col]

 

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

 

row 5 col 1: cvp1.button 65

row 5 col 2: cvp1.button 66

.

.

row 5 col 16: cvp1.button 80

row 6 col 1: cvp1.button 81

row 6 col 2: cvp1.button 82

.

.

row 8 col 16: cvp1.button 128

 

formula is cvp1.button [16*(row-1) + col]

 

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

 

row 9 col 1: cvp2.button 1

row 9 col 2: cvp2.button 2

.

.

row 9 col 16: cvp2.button 16

row 10 col 1: cvp2.button 17

row 10 col 2: cvp2.button 18

.

.

row 16 col 16: cvp2.button 128

 

formula is cvp2.button [16*(row-9) + col]

_____________________________________________________

 

Chakko Kovoor

9 Oct 2015

 

Yes, so all encoder pins are on cvp1.[1 to 64]


Edited by tomahawk66
  • Like 1
Link to comment
Share on other sites

I really appreciate this job, it works really good with my project! Thanks Overpro. I tested the Analogs and they worked, the buttons work ok too. Didn't tested the rotary encoders yet

 

But i had a crazy idea.. would it be possible to use an old mouse (the PS2 ball mouse) as a rotary encoder? The ball mouse works with an arduino, but i don't know if it would with this Project

 

Also, it's possible to use at the same time the axis and the rotary encoders?

 

Thanks

 

Hi Stiff, I think you can have a try on the ball mouse, If the ball mouse works like an encoders it should works here as well, please let us know your test result.

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

Hi Overpro,

 

Thank you ever so much for your fantastic contribution. I have successfully tested your code with encoders and switches in FSX, and everything works as intended.

 

Now, if one uses FSUIPC LUA one can actually access upto 256 inputs per HID controller. This would be a better solution for FSX-FSUIPC (rather than the present 128 x 2) as then there would be no possibility of the software wrongly identifying the joystick involved (as might happen now with 2 joysticks labelled cvp joystick).

 

So my question is whether there is a simple way of modifying your code to achieve this? As I am not an expert programmer, would you or anyone else be willing to do this and offer this as an alternative?

 

Thank you once again!

 

 

Yes it's possible and actually my first implementation is a single joystick with 256 keys, BUT... there are some compatibility issues with other software, such as Team Speak, if a HID controller has more then 128 buttons the TS3 client will crash ( no exception ). So I changed it as a composite USB device with 128 buttons on each joystick.

 

Change it back to 1 joystick with 256 buttons are not complex for now, but still requires some work. I can provide a 1HID*256buttons version later.

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

Yes it's possible and actually my first implementation is a single joystick with 256 keys, .................I can provide a 1HID*256buttons version later.

 

Sir,

I look forward to your 1HID*256buttons version as and when you have the time for this.

Thank you again for your wonderful work!:thumbup:

Warm Regards....

Link to comment
Share on other sites

Your C.V.P joystick code is very cool!

I became interested in Arduino with your code.

I believe that there are endless possibilities in Arduino

So. It is thanks to you who always realize it.

But Your C.V.P joystick code is not easy to have to learn.

You said~

“ps. this firmware is inspired by Darran's project: Arduino UNO Big joystick HID firmware:

http://hunt.net.nz/users/darran/weblog/15f92/

with out Darran's code I will never make this work. Thanks Darran.“

If you help me, I would like to receive your inspiration.

Above all, I thank for giving an answer from your busy day.

I also want to do this to start.

1. I had been download the files to this website.

“Big Joystick Firmware”, “riclamer_big_joystik.ino”, “Arduino-big-joystick.c”, “Arduino-big-joystick.h”, “Descriptors.c”, “Descriptors.h”

2. I have Changed to “riclamer_big_joystik.ino”, as shown below

But I found some problems.

1) I dont know why starting from joystick button No 18, 19~~28.

: I want you to start from button No 6,7,8~~~

So I have Changed to riclamer_big_joystik.ino”, as shown below.

Please tell me about incorrect.

#undef DEBUG

#define NUM_BUTTONS 40 // you don't need to change this value

#define NUM_AXES 8 // 6 axes to UNO, and 8 to MEGA. If you are using UNO, don't need to change this value.

typedef struct joyReport_t {

int16_t axis[NUM_AXES];

uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte

} joyReport_t;

joyReport_t joyReport;

//uint8_t btn[12];

uint8_t btn[33]; //?

int fulloff = 0;

void setup(void);

void loop(void);

void setButton(joyReport_t *joy, uint8_t button);

void clearButton(joyReport_t *joy, uint8_t button);

void sendJoyReport(joyReport_t *report);

void setup()

{

//set pin to input Button MEGA2560R 2PIN~ 12PIN

// set pin to input Button MEGA2560R 14PIN~ 34PIN

for( int portId = 02; portId < 13; portId ++ ) //?

{

pinMode( portId, OUTPUT );

}

for( int portId = 14; portId < 34; portId ++ ) //?

{

pinMode( portId, INPUT_PULLUP );

}

Serial.begin(115200);

delay(200);

for (uint8_t ind=0; ind<8; ind++) {

joyReport.axis[ind] = ind*1000;

}

for (uint8_t ind=0; ind<sizeof(joyReport.button); ind++) {

joyReport.button[ind] = 0;

}

}

// Send an HID report to the USB interface

void sendJoyReport(struct joyReport_t *report)

{

#ifndef DEBUG

Serial.write((uint8_t *)report, sizeof(joyReport_t));

#else

// dump human readable output for debugging

for (uint8_t ind=0; ind<NUM_AXES; ind++) {

Serial.print("axis[");

Serial.print(ind);

Serial.print("]= ");

Serial.print(report->axis[ind]);

Serial.print(" ");

}

Serial.println();

for (uint8_t ind=0; ind<NUM_BUTTONS/8; ind++) {

Serial.print("button[");

Serial.print(ind);

Serial.print("]= ");

Serial.print(report->button[ind], HEX);

Serial.print(" ");

}

Serial.println();

#endif

}

// turn a button on

void setButton(joyReport_t *joy, uint8_t button)

{

uint8_t index = button/8;

uint8_t bit = button - 8*index;

joy->button[index] |= 1 << bit;

}

// turn a button off

void clearButton(joyReport_t *joy, uint8_t button)

{

uint8_t index = button/8;

uint8_t bit = button - 8*index;

joy->button[index] &= ~(1 << bit);

}

/*

* Read Digital port for Button

* Read Analog port for axis

*/

void loop()

{

// Create Matriz with value off switch button

for(int bt = 1; bt < 34; bt ++) //?

{

btn[bt]= digitalRead(bt+1);

}

// Power ON button if it is press. buton 17 at 28

for(int on=01; on < 34; on++) //?

{

if (btn[on] == LOW)

{

setButton(&joyReport, on+16);

//It start button no 16~. how to start buttons no 6, 7, 8~

// Serial.println("botao ON");

// Serial.println(on+16); How is this calculated?

}else{

fulloff = fulloff++;

} //Power off all Button, if all button are not press

if(fulloff == 34)

{

for(uint8_t cont=0; cont<40; cont++)

{

clearButton(&joyReport, cont);

}

// Serial.println("Every buttons is off");

}

}

/* Move all of the Analogic axis */

/* Arduino UNO have only 6 port. Will be necessary set to 0; the not used port */

/* In this example, i will use just 3 axis. X, Y, Z */

/* if you will use all 6 analog ports, set axis < 3, to axis < 5 */

for (uint8_t axis = 0; axis < 4; axis++) {

joyReport.axis[axis] = map(analogRead(axis), 0, 1023, -32768,32767 );

}

//Set to 0; the not used analog port.

//if you will use all 6 analog ports, exclude the lines, axis[3] at axis [5] */

//joyReport.axis[3] = 0;

joyReport.axis[4] = 0;

joyReport.axis[5] = 0;

joyReport.axis[6] = 0;

joyReport.axis[7] = 0;

joyReport.axis[8] = 0;

//Send Data to HID

sendJoyReport(&joyReport);

delay(100);

fulloff = 0;

}

Hpappy sunday. From John

Link to comment
Share on other sites

Sir,

I look forward to your 1HID*256buttons version as and when you have the time for this.

Thank you again for your wonderful work!:thumbup:

Warm Regards....

 

Here is the firmware for 1HID interface with 256 buttons,

no changes on arduino code, only atmega16u2 firmware has changed.

Please have a try.

 

Note that some joystick testers will not work:

1) Pointy's Joystick Test can't detect any key press,

2) xplane can detect press if key ID <= 128

But I'm sure the HID report is correct.

cvpJoystick_1HID256Btns.hex.zip

cvpJoystick_1HID256Btns_NoSN.hex.zip


Edited by overpro

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

But I found some problems.

1) I dont know why starting from joystick button No 18, 19~~28.

: I want you to start from button No 6,7,8~~~

 

Hi John, I don't quite understand your question, could you please rephrase that? You might want to provide some more details on that.

Thanks

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

Here is the firmware for 1HID interface with 256 buttons,

no changes on arduino code, only atmega16u2 firmware has changed.

Please have a try.

 

Note that some joystick testers will not work:

1) Pointy's Joystick Test can't detect any key press,

2) xplane can detect press if key ID <= 128

But I'm sure the HID report is correct.

 

Hi overpro,

 

Thank you so much for this .... quite fantastic! :thumbup:

 

I loaded the new hex file (needed to short the pins before Flip could open the USB port) ..... and yes, pointy's joystick test does not work ..... but, SV Mapper duly showed a single C.V.P Joystick with 256 buttons. .......

 

svmapper1.jpg.e5d5c5a9be6940b771e47af2eb566915.jpg

 

However, from the image, you will notice that many buttons from 225 to 255 seem to be permanently on, even with nothing connected to the Mega pins.

 

On testing the pins with encoders and switches connected, I found normal responses from Mega pins (22, 38+39) = encoder buttons [1+2] all the way to pins (29, 53) = button [128]. But there was no response to Mega pins [30, 38] onwards.

 

So it seems that the present firmware/code will recognise a joystick with 256 buttons but will not respond to button presses beyond # 128 (or beyond Mega pins (29,53)).

 

Thank you for your attention, and with Warm Regards!:)

 

Chakko.


Edited by tomahawk66
Link to comment
Share on other sites

Hi OverPro,

 

I tried to make the ball mouse work but i can't, i think i should buy a RotaryEncoder.

 

But, is it possible to use the Rotarys and the Analogs at the same time? It would be really useful because I am doing a Steering Wheel (like a Logitech g25) and I need the Rotarys and the Analogs to work at the same time, because the Potentiometer in the Steering is 270º only and it sucks for some games...

 

Salute!

Link to comment
Share on other sites

Hi OverPro,

 

I tried to make the ball mouse work but i can't, i think i should buy a RotaryEncoder.

 

But, is it possible to use the Rotarys and the Analogs at the same time? It would be really useful because I am doing a Steering Wheel (like a Logitech g25) and I need the Rotarys and the Analogs to work at the same time, because the Potentiometer in the Steering is 270º only and it sucks for some games...

 

Salute!

 

We can't use rotary encoder on the analog input pins. So if you want to do a wheel and steering like 720º then you need to put some geers between your wheel and the poentiometers. The geer should transform the 0~720º motion to 0~270º

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

Hi overpro,

 

Thank you so much for this .... quite fantastic! :thumbup:

 

I loaded the new hex file (needed to short the pins before Flip could open the USB port) ..... and yes, pointy's joystick test does not work ..... but, SV Mapper duly showed a single C.V.P Joystick with 256 buttons. .......

 

[ATTACH]125036[/ATTACH]

 

However, from the image, you will notice that many buttons from 225 to 255 seem to be permanently on, even with nothing connected to the Mega pins.

 

On testing the pins with encoders and switches connected, I found normal responses from Mega pins (22, 38+39) = encoder buttons [1+2] all the way to pins (29, 53) = button [128]. But there was no response to Mega pins [30, 38] onwards.

 

So it seems that the present firmware/code will recognise a joystick with 256 buttons but will not respond to button presses beyond # 128 (or beyond Mega pins (29,53)).

 

Thank you for your attention, and with Warm Regards!:)

 

Chakko.

 

 

Hi Chakko,

 

I suspect SV Mapper doesn't recognize the button press correctly, I used Microsoft Message Analyzer - MMA to capture the USb device HID packages and I can see the HID report is correct.

 

Attached is the screen capture, the lower right window is the HID Input report, as you can see we have 48 bytes, the first 16 bytes are the 8 axis, the 17~32 bytes are the button value for Pin 22~29,

the 33~48 bytes are the button value for Pin 30~37.

 

I shortcut the pin30 and pin38, so byte 33's value is 0x01. And all else are 0 which means no button were pressed.

attachment.php?attachmentid=125114&stc=1&d=1445224116

 

I'm thinking it might be better to test it under FSUIPC directly.

Or you can use MMA to test your button directly. Please watch the 2 video tutorial first, the MMA GUI is not that straightforward as I expected.

https://msdn.microsoft.com/en-us/library/windows/hardware/dn741264%28v=vs.85%29.aspx

57377853_2015-10-1911_00_35-Clipboard.thumb.jpg.c76c618e54023204745ea90ad6807c10.jpg

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

I suspect SV Mapper doesn't recognize the button press correctly, I used Microsoft Message Analyzer - MMA to capture the USb device HID packages and I can see the HID report is correct.

.........................

I'm thinking it might be better to test it under FSUIPC directly.

 

Hi overpro,

 

Thanks for this ..... I will test the pins under FSUIPC-LUA (this will involve writing some lua plugins) and get back to you in a few days. In the meantime, I ran Pete Dowson's HID device scanner (HID Scanner.exe) and the log shows an Arduino with 256 buttons:

 

********* HidScanner, Version 2.00 by Pete Dowson *********

 

Device at "\\?\hid#vid_03eb&pid_2043&mi_00#8&392dae83&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"

Vendor=03EB, Product=2043 (Version 0.3)

Manufacturer= Arduino

Product= 001

Serial Number= C2

Usage Page: 1

Input Report Byte Length: 49

Output Report Byte Length: 0

Feature Report Byte Length: 0

Number of Link Collection Nodes: 2

Number of Input Button Caps: 1

Number of InputValue Caps: 8

Number of InputData Indices: 264

Number of Output Button Caps: 0

Number of Output Value Caps: 0

Number of Output Data Indices: 0

Number of Feature Button Caps: 0

Number of Feature Value Caps: 0

Number of Feature Data Indices: 0

Buttons range 1 -> 256 at indices 8 -> 263

Value Dial at index 0, range 0 -> 65535, using 16 bits

Value Sldr at index 1, range 0 -> 65535, using 16 bits

Value R/RZ at index 2, range 0 -> 65535, using 16 bits

Value V/RY at index 3, range 0 -> 65535, using 16 bits

Value U/RX at index 4, range 0 -> 65535, using 16 bits

Value Z at index 5, range 0 -> 65535, using 16 bits

Value Y at index 6, range 0 -> 65535, using 16 bits

Value X at index 7, range 0 -> 65535, using 16 bits

**************************************************************************

 

So everything actually looks good, so far. :thumbup:

 

Chakko.

Link to comment
Share on other sites

1. How are the progress of row 4, 5 used to support 16 On - off - On toggle switches ?

 

Actually I have finished this part but I haven't push the arduino/firmware code to github yet, because this change might affect some people's cockpit.

 

It's not using row 4,5 but row 15 instead ( pin 37 ) as the OnOffOn toggle switch, so you can connect 8 toggle switches. Connect the middle pin on the switch to row15 ( pin37 ) and 2 other pins to col0/1 col2/3 ... col14/15.

The 8 OnOffOn switch will occupy 24 button bits in the HID report ( 8 switches * 3 bit per switch ).

As 16 pins are used and 24bit data generated, it must borrow one byte from the normal buttons, so col 8~ 15 on row 14 will be used for the OnOffOn button. Don't connect any switches to this section.

 

Now the normal button count is 16 * 10 + 8 = 168, which used 168 bits

8 OnOffOn switches used 24 bits,

32 rotary encoders used 64 bits.

 

If you want to have some test I can provide a dedicated arduino/firmware here.

 

http://forums.eagle.ru/attachment.php?attachmentid=125192&stc=1&d=1445303177

 

2. Could you make for us a sketch for 6x6 Arduino Uno ?

 

This is definitely possible, let me get a uno board first.

CVP_JoystickController.ino.zip


Edited by overpro

overpro = I'm not good at Nintendo Mario and always get "Game over" pretty fast, so over~~pro

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...