-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HD-rumble data #11
Comments
When the Bluetooth stack of the joycon and your computer desync (or whatever that is), just do a physical pair with your Switch, long press the sync button, and connect again from your computer. |
@lyra833 could you post what you sent to the JoyCons / their responses? I haven't been able to get any rumble events to trigger |
I've been testing vibration a bit today by keeping the baudrate lower over USB HID so that I can race fast enough to keep vibration enabled when transitioning from Bluetooth to UART in the grip and found a few things at least: For a USB HID packet The right Joy-Con is only affected by the ZZ bytes when incrementing each byte one at a time from 0 to FF, and the left Joy-Con is only affected by the YY bytes when doing the same. In this test, XX are both sent to 01. When leaving YY or ZZ at 0x80 and incrementing the first XX or the second XX respectively, only the first YY or ZZ respond and the frequency of the vibration increases. Leaving YY or ZZ at 0x01 has all of the bytes respond. The first XX seems to control frequency on the left Joy-Con only, and the second the right. This test is demonstrated here and the code here |
The HD-Rumble is well known now. Can we close this? |
I've started trying to decode the amplitude algorithm (for high amplitude first), and I've got something that partially works (only for EDIT: BTW, the correct values are given if you |
Alright, so I've found the algorithm(s) for original amplitude to high amplitude, and they are (unsimplified): if (amp < 0.117) return (((log2(amp * 1000) * 32) - 0x60) / (5 - (2 ** amp)) - 1);
if (amp >= 0.117 && amp < 0.23) return ((log2(amp * 1000) * 32) - 0x60) - 0x5c;
if (amp >= 0.23) return (((log2(amp * 1000) * 32) - 0x60) * 2) - 0xf6; Each range ( These equations should obviously be simplified and cleaned up, but I literally just now found them so... I'll leave that to someone else. 😄 |
Well, finding the algorithm for low amplitude was a lot easier having known the algorithms for high amplitude: uint8_t encoded = round(highAmplitudeAlgorithm(amp)) / 2;
uint8_t evenOrOdd = encoded % 2;
uint8_t bytes[2];
if (evenOrOdd > 0) {
// odd
bytes[0] = 0x80;
encoded = encoded - 1;
}
encoded = encoded / 2;
bytes[1] = 0x40 + encoded;
// if you wanted to combine them:
uint16_t byte = (bytes[0] << 8) | bytes[1]; |
where does |
Sorry, |
Also, @CTCaer, I figured I might as well mention this here because I wasn't sure where to put it, but I'm having trouble applying the equations on this page to return the default rumble data [00 01 40 40] from input value of f=320 Hz, amp=0. My low frequency value ends up as |
Hmm the equation is correct. Default LF is 160Hz. That's the Low end resonant frequency. EDIT: If these are working we can optimize them later. |
OK, so those two default frequency band values don't correspond to any real initial frequency value? |
Ofcourse. You should get different values for encoded_hex_freq and for encoded LF/HF freq. OK, let's decode the default vibration [00 01 40 40]: HF_freq = (HF_u16 >> 8) & 0xFF | HF_u16 & 0x01; //we need LSB Another way we can work with HF_amp is (HF_u16 >> 1) & 0xFF and then we get a range of 0-7f with +1 increments. LF_u16 = 0x4040; HF_freq = (LF_u16 >> 8) & 0x7F // we mask out x80 which is the intermediate for LF_amp Then for LF_amp we can work by splitting the 2 bytes. And if LF_amp >> 8 == 0x80 then we know it's intermediate amplitude and bigger than LF_amp & 0xFF. I may sound a bit confusing, but that's the math. Please also read here, to understand which byte is which and how they are encoded. Lastly, don't take my code as the de facto. There are countless ways to smartly optimize, bit mask, bit shift, convert and work on data. This way you can have easier calculations and also less expensive. The above also means, that we can find better algorithms with new numbers that increment by +1 and then bit shift them to have what JC understands. Bit manipulation is a funny thing.. |
OK, I've read your comment again. If understood correctly, you want to work with only one algorithm for both LF/HF. As you probably saw by now: |
OK - it seems like the first code sample on this document converts a single frequency float into |
Ok I understand now. The code is a RFC to understand how to encode a freq to LF OR HF. To work correctly you need sth like this:
|
I may be extremely late on this, but the default values of 320 / 160 Hz and the setting of low and high vibration frequencies seems to all but confirm that the HD Rumble vibration motors are ALPS Electric Haptic Reactors, was this known? |
Nope, had no clue. BTW, I remembered to state something that I always forgot. EDIT: |
Looks like the actual part in the Joy-Cons isn't visible on that page - the ....06 has no center push button. It's probably the ...05 or ...04 or something like that. |
True, but the other characteristics probably are the same. |
Analysing the four unused bit(first byte lowest 2 bit and last byte highest 2bit), basically, the JoyCon HD rumble is a mix of below three elements:
the rumble data is the combination pattern of these three elements in special manner. TYPE X0: "single wave with resonance"
TYPE 01-00: "dual wave"
TYPE 01-01: "silent"
TYPE 01-01: "dual resonance with 3 pulse"
TYPE 11: "dual resonance with 4 pulse"
Amplitude:
Pulse Shape:
|
@rei-github Is it possible to also record the real frequencies produced so we can update the freq table? Lastly, I will take a closer look at your findings next Monday and if you want I can do the pull request to include your info. |
hi, I've made one mistake and forgot one information. the pulse shape is difficult to describe, so I took some pictures. |
Hm, maybe I'm messing something up, but when I try to use pulses, I get a regular vibration, except its frequency shifts down with every (identical) message I send? I can't make sense of it :/ |
@ThibG make sure you're incrementing the rumble frame timer in the packets you send! |
The first byte of the HID output report, referenced as |
What about the packet frequency and hid output report id? |
I've been wrangling around with the Joy-Con and think I've figured out how the rumble data is sent over, starting from byte 13 in the packet sent from the Switch. (It doesn't look like standard HID...)
Byte 13 is a constant,
0x10
. It's probably an identifier, as it's always0xf
for all pings not containing rumble data. Byte 14 looks like some sort of timekeeper in the event of the packets colliding; it starts at0xa
, increments with every ping sent until0xf
, then loops back around to0x0
,0x1
, etc. Changing either of these bits doesn't trigger any rumble at all. There are then 8 bits, 6 of which seem to correspond to the 6 faces of the Joy-Con; but my drivers started crapping out before I could dope out the last 2. The first of the 8 (Byte 15) seems to be some sort of global intensity modifier; as changing it seemed to jolt the whole thing more or less, so that leaves 6 faces, one global modifier, and ?????.I've managed to trigger some rumble events, but my laptop drivers are suddenly refusing to play nice with the Joy-Cons. I'm not sure if it's hardware failure or something to do with manipulating this data, but I'd love to have some fresh eyes verify it. I verified it against @dekuNukem's BotW data and it seems to check out with respects to which bits change when during the bomb rumble. (I would love to try it with this, because it would let us isolate which bits correspond to which edge of the Joy-Con.)
Once someone else verifies, we can add it to the README?
Oh, and as a clarification because my Bluetooth has been hell, they're sending the same data over BT as they are over serial, right? The only thing that's different is the clock speed?
The text was updated successfully, but these errors were encountered: