Ardwiino
Ardwiino copied to clipboard
[Request] Support I2C neck connection
Some guitar necks, like the GH5/RockBand guitar, use a neck connection that has a 4-pin I2C connection, instead of the typical 6 pin (ground + 5 buttons). In order to read the neck buttons for this neck, the arduino must communicate with the neck over I2C.
I reverse engineered the I2C communication and documented it in a blog post: https://marc.khouri.ca/posts/2022/GH5-neck-comms.html
The code itself is quite simple, but it does require using the hardware I2C on the arduino, and I'm not sure how many necks use this -- it might be particular to just the Guitar Hero 5 guitar.
So it might not be worth it for you to add support for this. At least, I hope you'll find the information interesting :) and please feel free to close the issue if it's not worth it
Yeah someone else gave me the reverse engineered protocol a while back. I didn't really see a point cause it seems like they cant be polled very fast, and that would limit the speed of everything else. what did the poll rate end up being when you implemented it? It is only the GH5 guitars that do it. Im fine with using hardware I2C - we use it for wii guitars already. I think wii guitars are polled at 0.5ms at the moment, and usb ticks every 1ms I may do this on the new firmware, but that is a good while away. You might have noticed that the entire repos codebase was swapped recently, one nice benefit of the newer firmware is that its a lot more hackable as its platform.io based, so even if i don't get around to it you probably could easily.
The original guitar polled the neck every 10ms, but I'm successfully polling at 2ms in my code. I didn't try to find the lower bound -- I'll check it out to see if it can go down as low as 0.5ms.
the newer firmware is that its a lot more hackable as its platform.io based, so even if i don't get around to it you probably could easily.
Cool! I have another small side project I want to wrap up first, but then I'll probably take a look at doing it
I was also told that if you poll it fast, it just starts reploying with duplicate data and doesn't actually poll faster but I have no confirmation of that
The original guitar polled the neck every 10ms, but I'm successfully polling at 2ms in my code. I didn't try to find the lower bound -- I'll check it out to see if it can go down as low as 0.5ms.
the newer firmware is that its a lot more hackable as its platform.io based, so even if i don't get around to it you probably could easily.
Cool! I have another small side project I want to wrap up first, but then I'll probably take a look at doing it
do note that the new firmware is ages away anyways so it probably won't be ready until your done anyways. let me know how low it can be polled with how the new firmware works it may end up being easier to implement that than it would have been with the old firmware, so i may implement i2c necks.
The other question is, do you actually need to do all those reads and writes? If it works anything like the wii, i wonder if a two-byte read at 0x12 would give us just the button byte and the first tap bar byte? something like
Wire.beginTransmission(0x0D); // Transmit to device
Wire.write(0x12); // Sends value byte
byte error = Wire.endTransmission(); // Stop transmitting
if (error != 0) {
if (SERIAL_EN) { diagnoseTransmissionError(error); }
return;
}
unsigned int expectedByteCount2 = 2;
uint8_t values2[expectedByteCount2];
unsigned int readCount2 = readFromSerial(values2, expectedByteCount2);
if (SERIAL_EN && VERBOSE) { printByteArray(values2, readCount2); }
if (readCount2 == expectedByteCount2) {
// Serial.println("Second read done");
} else {
if (SERIAL_EN) { Serial.println("Wrong byte count read"); }
return;
}
I was also told that if you poll it fast, it just starts reploying with duplicate data and doesn't actually poll faster but I have no confirmation of that
I updated the code to poll faster, but I'm not sure how I would experimentally verify that each button change is actually registered that quick. Any ideas? I used 0.5ms, 0.1ms, and even 0.01ms, and the neck doesn't lock-up or fail or anything -- all seems to be working at those polling speeds.
The other question is, do you actually need to do all those reads and writes? If it works anything like the wii, i wonder if a two-byte read at 0x12 would give us just the button byte and the first tap bar byte?
Nice suggestion!! I've updated the code to do exactly as you said, and it looks to be working great (line 331 in the updated gist). So the wii guitar works similarly? That's very interesting.
Easiest way to test the actual poll rate would be to have the pro mini control one of the frets (have the pro mini ground the pin on the neck pcb), and then time how long it takes for it to respond. Tbh though as long as the neck doesn't lock up than im happy to implement it either way.
Nice suggestion!! I've updated the code to do exactly as you said, and it looks to be working great (line 331 in the updated gist). So the wii guitar works similarly? That's very interesting.
As far as im aware, a lot of I2C devices work this way, where you write an address and then can just read as many bytes as you want from that address. With wii guitars, there's an initialization sequence (that also sets up encryption but you can disable it with the right initialization sequence) and then you just do a read from 0x00 to read the data. Though they lock up if you poll them too fast!
Good idea for the test, I'll try it out at some point -- I'm curious what the true response rate is
also, what does the neck do if you dont do the initial 0x00 write and read? does it work just fine?
and i guess the last question is what baudrate does it support, can one go all the way up to 400000hz or 250000hz? Id also be interested in if they go any higher than that but you'd need something like a pi pico to test that as the pro mini has an upper limit for speed of about 300000hz iirc.
Also, which console is this GH5 guitar for? i do also have to wonder if different GH5 guitars handle the tap bar differently, that would not surprise me much.
If that did end up being the case, i may just have to implement only the buttons and exclude the tap bar.
heh, implementing this actually put me over my max flash storage size on the arduino pro micro, and that was after converting the switch statements to a lookup. If you do ever figure out any ideas for how to process the tap bindings without that switch case let me know.
If i try hard i can probably skim away bytes here and there.
Oh noo, I hadn't considered the size. I bet there's an algorithmic way to decode the touch pads, I'll let you know if I ever find it but I haven't spotted it yet...
This was a PS3 gh5 guitar, but I'd guess all the necks are the same because I think the necks are interchangeable among consoles.
About the max baud rate and skipping the initial handshake: I'll try this next week and report back (and maybe also the test you suggested to find the true response rate).
Thanks for trying out an implementation!
I sat there and stared at the necks data for ages, and while there definitely appears to be something vaguely binary related there, I could never come up with something that made perfect sense It sounds like wt necks are also compatible with each other I now have an implementation of that too hanging around, I just need to put a gui over it
On Sat, 4 Jun 2022, 3:18 am Marc Khouri, @.***> wrote:
Oh noo, I hadn't considered the size. I bet there's an algorithmic way to decode the touch pads, I'll let you know if I ever find it but I haven't spotted it yet...
This was a PS3 gh5 guitar, but I'd guess all the necks are the same because I think the necks are interchangeable among consoles.
About the max baud rate and skipping the initial handshake: I'll try this next week and report back (and maybe also the test you suggested to find the true response rate).
Thanks for trying out an implementation!
— Reply to this email directly, view it on GitHub https://github.com/sanjay900/Ardwiino/issues/6#issuecomment-1146068163, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOGYQA2UTJJUEIR3B7NBD3VNIO4HANCNFSM5W3SJTNA . You are receiving this because you commented.Message ID: @.***>
feel free to try out the preview build and see if it does anything
I'm out of town this weekend but looking forward to trying this next week!
Hi @sanjay900 , I haven't had a good chunk of time to test this and am leaving town for a month -- I'll be sure to try it once I'm settled back in thought!
Im tempted to assume this works, as the DJ hero turntables work in the same way and i can confirm those work
Awesome! Thanks for your work on this. I'll be sure to comment when I get back to my guitar
I should be getting a guitar with one of these necks today too, so ill be sure to test this all and get back to you
Can confirm it is all working now with the latest build.
I've been reading all @mnkhouri blog posts and this conversation.. first of all I want to thank you both for the work you've put on this! It's awesome!
Now! I'm in a similar but different spot as Marc was: I have a brandless chinese guitar (which is wireless and pretty much unusable in my place because it keeps disconnecting due to the WiFi interference), so I decided to convert it to "wired". I have pretty much all nailed down (Arduino Pro Micro 5v, wires almost all mapped and ready to solder).
Problem is that the neck uses I2C too, similar to what you've been discussing here. It's using this Capacitive TouchPad Chip to map the touchpad and frets. I'm no electrical/electronics engineer so my electronics knowledge is very limited. I already implemented the base code to read from it, even the initial handshake the datasheet specifies. Again, thank you very much Mark! your blog is what encouraged me to pursue the reverse engineering path.
Based on the datasheet I have already mapped the frets bits. I still need to map the touchpad, but I just got the code working last night after three long days of analysis and trial and error.
I know Mark used two microcontrollers (one for the I2C communication and the other for the controller) but I wanted to challenge myself to integrate all in one single microcontroller, so, for that I will need to modify this firmware in order to support this new feature.
I would love to know what changed since your last reply @sanjay900 ... It's been a year and you probably finished the new firmware (or maybe not! that's fine too) but I'm wondering if your integration is with two microcontrollers too and if you could provide any insights for me.
I'll attach a couple photos:
WIP
Neck debugging:
Original Box
Original board+POGO pins for the I2C neck.
I've been reading all @mnkhouri blog posts and this conversation.. first of all I want to thank you both for the work you've put on this! It's awesome!
Now! I'm in a similar but different spot as Marc was: I have a brandless chinese guitar (which is wireless and pretty much unusable in my place because it keeps disconnecting due to the WiFi interference), so I decided to convert it to "wired". I have pretty much all nailed down (Arduino Pro Micro 5v, wires almost all mapped and ready to solder).
Problem is that the neck uses I2C too, similar to what you've been discussing here. It's using this Capacitive TouchPad Chip to map the touchpad and frets. I'm no electrical/electronics engineer so my electronics knowledge is very limited. I already implemented the base code to read from it, even the initial handshake the datasheet specifies. Again, thank you very much Mark! your blog is what encouraged me to pursue the reverse engineering path.
Based on the datasheet I have already mapped the frets bits. I still need to map the touchpad, but I just got the code working last night after three long days of analysis and trial and error.
I know Mark used two microcontrollers (one for the I2C communication and the other for the controller) but I wanted to challenge myself to integrate all in one single microcontroller, so, for that I will need to modify this firmware in order to support this new feature.
I would love to know what changed since your last reply @sanjay900 ... It's been a year and you probably finished the new firmware (or maybe not! that's fine too) but I'm wondering if your integration is with two microcontrollers too and if you could provide any insights for me.
I'll attach a couple photos:
WIP
![]()
Neck debugging:
![]()
Original Box
Original board+POGO pins for the I2C neck.
New firmware isn't done yet. Got a link to your repo?
Just uploaded it! I been working on the buttons mapping.. I think this is almost ready to go and rock the stage 🤣
https://github.com/knifesk/guitar-hero-neck
@knifesk Have you got a discord by any chance? im sanjay900 on there. I could probably implement this maybe, but it would involve a lot of questions which is easier to deal with over discord.
Just uploaded it! I been working on the buttons mapping.. I think this is almost ready to go and rock the stage 🤣
https://github.com/knifesk/guitar-hero-neck
alright ive probably implemented this, but we will need to test it, its in an unreleased firmware. If you add me on discord or something, i can probably send a copy your way for testing.
Hi Sanjay, that's awesome!! And yes I do have discord! Currently I'm on a work trip, but I'll be back on wednesday and I'll be able to try it out! I'll add you to my discord as soon as I'm home! Thank you so much!
I was also told that if you poll it fast, it just starts reploying with duplicate data and doesn't actually poll faster but I have no confirmation of that
I updated the code to poll faster, but I'm not sure how I would experimentally verify that each button change is actually registered that quick. Any ideas? I used 0.5ms, 0.1ms, and even 0.01ms, and the neck doesn't lock-up or fail or anything -- all seems to be working at those polling speeds.
The other question is, do you actually need to do all those reads and writes? If it works anything like the wii, i wonder if a two-byte read at 0x12 would give us just the button byte and the first tap bar byte?
Nice suggestion!! I've updated the code to do exactly as you said, and it looks to be working great (line 331 in the updated gist). So the wii guitar works similarly? That's very interesting.
FYI if you ever wondered
Heres the actual numbers for the poll rate of the gh5 i2c neck frets.