I am much more confident that I have things configured correctly now.
For the record:
-It is 2-way MIDI. I had originally doubted it, but it is now confirmed that communication happens both ways over opto isolators.
-It does not follow conventional MIDI packet standards with regards to MIDI instruments and communication that a PC expects when communicating with MIDI devices.
-The baudrate is standard MIDI at 31250 bps, 8N1.
-Commands are sent from the motherboard in 4-byte packets.
-Acknowledgements are received from the MIDI FFB board as 1-byte packs.
-Byte 4 of the Command is a checksum with XOR of the first 3 bytes and then AND 0x7F to strip the first bit. (Big thanks to
@obcd for noticing that! I don't think I would have seen that on my own. I might have guessed and tried XOR based on my card reader communication experience and stopped guessing when it didn't match up.)
-Making sure to keep communication alive is key to successfully command of the MIDI FFB. I don't know whether or not it affects anything, but I also have a 100 millisecond delay in my main loop to slow down communication a little. Without the constant commands being issued, the FFB will stop responding and go back into a state where it wants to be initilized again.
More info, not entirely confirmed:
At the moment, I have a pot wired up to the Arduino to generate replies within a specified range, and I have figured out some of the protocol, but some of it is still not quite clear.
With regards to ACKs, I think these are the translations.
0x00 - Ready for next command
0x11 - Not Initialized
0x44 - Busy - Not ready for next command
- I believe there is the potential for an error reply or 2 as I have had the PCB at the back of the motor unplugged and got some kind of communication error listed in the game and there's also the potential for a center error where the encoder PCB is not finding the "center" notch on the encoder disc. I'm not sure what these replies are at the moment, because I'll have to essentially "break" things to find out and don't want to right now.
I only see 0x44 as the reply during an initialization command that makes the wheel move in slow increments to the right about 90 degrees before it accepts more commands. Certainly during this time it doesn't react to any commands, and it will still go through the motions even if communication stops (per my earlier experiments when I wasn't keeping communication active).
For commands things are a little unclear based on logs at this point, mostly with regards to the first byte. I believe at least some part of the first byte is the general command type being issued (move, sustain, initialize), while bytes 2 and 3 are tied to direction and intensity.
After going through initialization commands and then sending commands that range from 84 00 50 to 84 01 30 I can get movement in either direction with different intensities.
Here's move left with almost no power up to higher power in increments:
84 1 16
84 1 28
84 1 30
Here's right with the same behavior:
84 0 76
84 0 68
84 0 58
The in-between values from left to right don't result in much happening at all. The wheel mostly dies with a little resistance building up as you work your way closer to either range where motion is noticeable.
So 84 seems to be the MOVE command, however in the log where I'm showing unique commands seen during in-game initialization, I see a lot starting with 9D and some 9E, so I'll try some tests to see if I can figure these out.
83, 86, 88, FA, FC and F0 all show up during initialization, with FC being the one that makes the wheel move on its own to the right 90 degrees as a kind of self-initialization command.
I see 80 as being some kind of timing or distance increment that the wheel should move and then stop. After my current initialization commands, I have it ending with 80 1 1 0 followed by 84 1 14 11 and it backs up to the left just a little and stops. I think if I padded it out with all the commands in the initialization log, it would end up relatively at the center if I kept using the 80 command along with the MOVE command. So I'm not sure what to call this one except maybe INCREMENT command. Note that 80 0 0 0 is the STOP command, so the 2nd and 3rd bytes being 0 seem to mean increment 0. I'll play around with this one more to confirm.
FD seems to be the GET STATUS command that just serves as a way to keep communication alive without affecting what's happening.
At the moment, I'm not seeing any way to mark a position for the wheel to constantly strive to attain and have it move on its own left or right accordingly. I'm not sure if that's even possible. My guess at the moment is that it's up to the game to monitor wheel pot movement and issue commands accordingly. So if it wants to center the wheel, it needs to move left or right accordingly and tell it to stop when it gets there.
I've still got some more tests to do without wiring up the wheel pot, but once I get a better feel for the commands, I will wire up the wheel pot and have the Arduino monitor it along the commands it issues, with the short term goal being to get the wheel to move to a given spot according to the 2nd pot I have wired up (i.e. have the wheel move automatically to match up to the pot I have on the breadboard).