What's new
Success! I sent the first few commands from the init log and the wheel slowly turned to the right, like it does when the game issues these commands.

I'm going to have to fill out the rest of the initialization commands because it's not responding to my positional commands after that.
 
I think the elements I'm missing in my testing are timing and wheel pot readings.

When I'm getting through all the commands for initialization, it seems to be establishing the center at either the extreme left or right, and sending the commands I thought were roll left/roll right aren't resulting in any movement. The center command does sometimes make it move, but I don't think I'm initializing the center correctly.

I have a feeling that the game is issuing commands while it's monitoring the steering pot via JVS and saying "move a little", "a little more", "ok, that's the center". The wheel can keep track of its own positions via an encoder disc, but I assume at some point what it centers to has to be synchronized with what the game is considering center (i.e. the center of the steering pot). OR2SP actually has a setting for establishing where the center is for the FFB. You can adjust a value left or right accordingly.

Now that I'm pretty confident I have the baud-rate correct, I can wire up for some more robust monitoring, including steering wheel pot values.
 
In my minimal observation of the FFB's replies, it appears to just give 1-byte status replies. Most of the time the reply is 0x0, even when it's moving.

The only other replies I'm seeing sometimes are 0x11 and 0x44 during initialization.

So this makes me think the FFB is not really ever reporting its position. It would be relying on the game to monitor that based on the wheel pot.
 
Wired up for 2-way communication, here's initialization with ACKs:
Code:
Started!
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FF 0 0 7F  
ACK:0
81 30 7F 4E  
ACK:11
81 30 7F 4E  
ACK:11
FC 0 20 5C  
FD 0 0 7D  
ACK:44
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:44
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
FA 0 1F 65  
83 ACK:0
60 4 67  
86 ACK:0
1 2 5  
ACK:0
ACK:0
88 0 4 C  
80 1 1 0  
ACK:0
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 14 11  
ACK:0
ACK:0
80 1 1 0  
84 1 1E 1B  
ACK:0
ACK:0
80 1 1 0  
84 1 20 25  
ACK:0
ACK:0
80 1 1 0  
84 1 20 25  
ACK:0
ACK:0
80 1 1 0  
84 1 20 25  
ACK:0
ACK:0
80 1 1 0  
84 1 20 25  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 14 11  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 14 11  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 14 11  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 14 11  
ACK:0
ACK:0
80 1 1 0  
84 1 1E 1B  
ACK:0
ACK:0
80 1 1 0  
84 1 20 25  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 A F  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
80 1 1 0  
84 1 0 5  
ACK:0
ACK:0
F0 0 0 70  
84 1 0 5  
ACK:0
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
FD 0 0 7D  
ACK:0
 
One more observation that may have been the issue with my previous tests: The FFB board likes to have a constant series of commands coming at it or it stops moving. I confirmed this by having the Chihiro wired up and in the test menu it was rolling one direction or the other and when I unplugged one of the signal wires, it immediately died.

So while there are very few unique commands in my logs, the FD 0 0 7D is spammed after most commands, and that's what kept the motor running. I think it's not really a status check command, but more of a command to sustain the previous command.

I think my next goal rather than more monitoring is just going to be to wire up the wheel pot to my Arduino, keep track of pot position and issue commands with position in mind to see if I can get the wheel the behave how I want it to.
 
Nice progress.

It might also be interesting to figure out what the game board needs as feedback to keep it happy.

It might complain if it run's the motor board selftest and doesn't see the wheel moving in the one and other direction.

I also wonder if they just run that test to check the force feedback hardware or if they also use it to figure out the readings they get back on both ends so that they can determine the center value. I should check it out, but I don't think that the OR2 steering still has another way to center the wheel. (Like a spring)

If they would use it to figure out it's center value, it wouldn't work on a standup cabinet that isn't having the force feedback hardware...
 
I'm not sure how it behaves in upright mode. Maybe in dedicated upright cabs, those wheels do have center springs?

For sure on my standard cab there are no springs.

I'm thinking the game would suspect something is wrong if the FFB keeps replying back, but there's no movement. Or maybe they didn't program a timeout and it will just sit forever issuing commands until it sees the behavior it expects. I've had it become unresponsive during initialization, requiring a hard reboot.
 
Some observations (could be wrong)

The first byte from gameboard to FFB always seems to be equal or bigger than 0x80h

If you xor the first 3 bytes and strip the most significant bit, you get the fourth byte (a sort of checksum?)

Stripping of that bit is probably done to ensure that it doesn't become equal or bigger than 0x80..

I assume you have more data to see if those assumptions are correct.
 
I'm not sure how it behaves in upright mode. Maybe in dedicated upright cabs, those wheels do have center springs?For sure on my standard cab there are no springs.
I have an original twin OR2 (sitdown) with the well known FFB wheel, and an original upright OR2 with a spring to center (and no FFB). When in upright mode, the game just don't use FFB commands.
 
Some observations (could be wrong)

The first byte from gameboard to FFB always seems to be equal or bigger than 0x80h

If you xor the first 3 bytes and strip the most significant bit, you get the fourth byte (a sort of checksum?)

Stripping of that bit is probably done to ensure that it doesn't become equal or bigger than 0x80..

I assume you have more data to see if those assumptions are correct.
I think you're right! I recorded a log during actual startup initialization into attract mode. The stream of commands is constant throughout attract mode, even though there's no movement. The boot up initialization is slightly different than the test menu version. It slowly turns to the right about 90 degrees and then creeps back to the middle slowly and stops.

Below are 289 unique commands from that log. I spot checked a few and the checksum theory holds true. This is great because now I can ignore the last byte when trying to decipher what the commands are.
Code:
80 0 0 0  
80 1 1 0  
81 30 7F 4E  
81 40 7F 3E  
83 40 4 47  
84 0 60 64  
84 0 62 66  
84 0 6C 68  
84 0 76 72  
84 1 0 5
84 1 14 11  
84 1 1E 1B  
84 1 20 25  
84 1 A F  
86 1 2 5
88 0 4 C
9D 0 0 1D  
9D 0 1 1C  
9D 0 2 1F  
9D 0 3 1E  
9D 0 4 19  
9D 0 5 18  
9D 0 6 1B  
9D 0 7 1A  
9D 0 8 15  
9D 0 9 14  
9D 0 A 17  
9D 0 B 16  
9D 0 C 11  
9D 0 D 10  
9D 0 E 13  
9D 0 F 12  
9D 1 0 1C  
9D 1 1 1D  
9D 1 2 1E  
9D 1 3 1F  
9D 1 4 18  
9D 1 5 19  
9D 1 6 1A  
9D 1 7 1B  
9D 1 8 14  
9D 1 9 15  
9D 1 A 16  
9D 1 B 17  
9D 1 C 10  
9D 1 D 11  
9D 1 E 12  
9D 1 F 13  
9D 2 0 1F  
9D 2 1 1E  
9D 2 2 1D  
9D 2 3 1C  
9D 2 4 1B  
9D 2 5 1A  
9D 2 6 19  
9D 2 7 18  
9D 2 8 17  
9D 2 9 16  
9D 2 A 15  
9D 2 B 14  
9D 2 C 13  
9D 2 D 12  
9D 2 E 11  
9D 2 F 10  
9D 3 0 1E  
9D 3 1 1F  
9D 3 2 1C  
9D 3 3 1D  
9D 3 4 1A  
9D 3 5 1B  
9D 3 6 18  
9D 3 7 19  
9D 3 8 16  
9D 3 9 17  
9D 3 A 14  
9D 3 B 15  
9D 3 C 12  
9D 3 D 13  
9D 3 E 10  
9D 3 F 11  
9D 4 0 19  
9D 4 1 18  
9D 4 2 1B  
9D 4 3 1A  
9D 4 4 1D  
9D 4 5 1C  
9D 4 6 1F  
9D 4 7 1E  
9D 4 8 11  
9D 4 9 10  
9D 4 A 13  
9D 4 B 12  
9D 4 C 15  
9D 4 D 14  
9D 4 E 17  
9D 4 F 16  
9D 5 0 18  
9D 5 1 19  
9D 5 2 1A  
9D 5 3 1B  
9D 5 4 1C  
9D 5 5 1D  
9D 5 6 1E  
9D 5 7 1F  
9D 5 8 10  
9D 5 9 11  
9D 5 A 12  
9D 5 B 13  
9D 5 C 14  
9D 5 D 15  
9D 5 E 16  
9D 5 F 17  
9D 6 0 1B  
9D 6 1 1A  
9D 6 2 19  
9D 6 3 18  
9D 6 4 1F  
9D 6 5 1E  
9D 6 6 1D  
9D 6 7 1C  
9D 6 8 13  
9D 6 9 12  
9D 6 A 11  
9D 6 B 10  
9D 6 C 17  
9D 6 D 16  
9D 6 E 15  
9D 6 F 14  
9D 7 0 1A  
9D 7 1 1B  
9D 7 2 18  
9D 7 3 19  
9D 7 4 1E  
9D 7 5 1F  
9D 7 6 1C  
9D 7 7 1D  
9D 7 8 12  
9D 7 9 13  
9D 7 A 10  
9D 7 B 11  
9D 7 C 16  
9D 7 D 17  
9D 7 E 14  
9D 7 F 15  
9D 8 0 15  
9D 8 1 14  
9D 8 2 17  
9D 8 3 16  
9D 8 4 11  
9D 8 5 10  
9D 8 6 13  
9D 8 7 12  
9D 8 8 1D  
9D 8 9 1C  
9D 8 A 1F  
9D 8 B 1E  
9D 8 C 19  
9D 8 D 18  
9D 8 E 1B  
9D 8 F 1A  
9D 9 0 14  
9D 9 1 15  
9D 9 2 16  
9D 9 3 17  
9D 9 4 10  
9D 9 5 11  
9D 9 6 12  
9D 9 7 13  
9D 9 8 1C  
9D 9 9 1D  
9D 9 A 1E  
9D 9 B 1F  
9D 9 C 18  
9D 9 D 19  
9D 9 E 1A  
9D 9 F 1B  
9D A 0 17  
9D A 1 16  
9D A 2 15  
9D A 3 14  
9D A 4 13  
9D A 5 12  
9D A 6 11  
9D A 7 10  
9D A 8 1F  
9D A 9 1E  
9D A A 1D  
9D A B 1C  
9D A C 1B  
9D A D 1A  
9D A E 19  
9D A F 18  
9D B 0 16  
9D B 1 17  
9D B 2 14  
9D B 3 15  
9D B 4 12  
9D B 5 13  
9D B 6 10  
9D B 7 11  
9D B 8 1E  
9D B 9 1F  
9D B A 1C  
9D B B 1D  
9D B C 1A  
9D B D 1B  
9D B E 18  
9D B F 19  
9D C 0 11  
9D C 1 10  
9D C 2 13  
9D C 3 12  
9D C 4 15  
9D C 5 14  
9D C 6 17  
9D C 7 16  
9D C 8 19  
9D C 9 18  
9D C A 1B  
9D C B 1A  
9D C C 1D  
9D C D 1C  
9D C E 1F  
9D C F 1E  
9D D 0 10  
9D D 1 11  
9D D 2 12  
9D D 3 13  
9D D 4 14  
9D D 5 15  
9D D 6 16  
9D D 7 17  
9D D 8 18  
9D D 9 19  
9D D A 1A  
9D D B 1B  
9D D C 1C  
9D D D 1D  
9D D E 1E  
9D D F 1F  
9D E 0 13  
9D E 1 12  
9D E 2 11  
9D E 3 10  
9D E 4 17  
9D E 5 16  
9D E 6 15  
9D E 7 14  
9D E 8 1B  
9D E 9 1A  
9D E A 19  
9D E B 18  
9D E C 1F  
9D E D 1E  
9D E E 1D  
9D E F 1C  
9D F 0 12  
9D F 1 13  
9D F 2 10  
9D F 3 11  
9D F 4 16  
9D F 5 17  
9D F 6 14  
9D F 7 15  
9D F 8 1A  
9D F 9 1B  
9D F A 18  
9D F B 19  
9D F C 1E  
9D F D 1F  
9D F E 1C  
9D F F 1D  
9E 0 1 1F  
9E 0 10 E  
9E 0 40 5E  
9E 0 50 4E  
9E 0 68 76  
9E 0 72 6C  
9E 1 0 1F  
9E 1 18 7  
9E 1 30 2F  
9E 1 40 5F  
9E 1 7F 60  
9E 1 C 13  
F0 0 0 70  
FA 0 1F 65  
FC 0 20 5C  
FD 0 0 7D  
FF 0 0 7F
 
http://superusr.free.fr/model3.htm

Not sure if this information could be of any use?

It might be interesting to monitor the Lindbergh commands.
Some might be identical which could make interfacing that a bit easier.

And before you ask, no, I don't have a Lindbergh.
I just saw cases of people who upgraded from chihiro to lindbergh and had to buy the serial FFB board.
Always wondered if another solution was possible.
 
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

  1. 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.
:P

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).
 
Last edited:
At initialisation, if it replies with 0x44, does the gameboard keep sending alive commands until the status changes from 0x44 to 0x00 , or is the FFB board sending a status 0x00 on it's own once the init cycle has finished?

The second case would mean you have to stop sending commands if you receive a non zero status back.

The first case would mean you have to send alive commands till you get a zero status back.

Command 9D seems to come with 2 parameters that can change between 0x00 and 0x0f.

The first parameter of the 9E command seems to be either 0 or 1. Do you see any other values with that command?

Command 84 seems to be like that as well. In it's case, it looks like the parameter is the direction.

(Just thinking loud...)
 
Last edited:
The first case would mean you have to send alive commands till you get a zero status back.
It is the first case, and yes a command must be sent during this time to receive the 44 reply back. My current test code does just that where it monitors for 00 before continuing with other initialization steps afterwards.
 
I have some rudimentary centering in place in my test code with wheel pot monitoring!

How this would need to get integrated into a final solution would be that the Arduino monitors the pot directly and passes analog through to the JVS I/O similar to how the Namco FFB does (probably the simplest and most compatible), it sniffs JVS I/O for wheel position (a little more complicated, requiring the use of a RS485 adapter and constant JVS I/O reading and deciphering), or it interfaces with the JVS I/O board (i.e. my custom JVS I/O solution) and gets the values sent to it, maybe over TTL.
 
Command 9D seems to come with 2 parameters that can change between 0x00 and 0x0f.

The first parameter of the 9E command seems to be either 0 or 1. Do you see any other values with that command?
I'm honestly having a hard time figuring out 9E and 9D. I have tried sending both commands different ways, dialing up or down the reported values and don't notice anything happening. I'm going to have to get some more extensive logs and see if these are generally coupled with something else that I'm missing.
 
I started monitoring F-ZERO AX during test menu init. An observation for this is that in spite of my previous believe that communication needs to be fairly constant, it appears that there can be indefinite breaks and then it can resume without initializing. F-ZERO does this from the time initialization finishes until you select one of the 3 choices (CENTER, LEFT, RIGHT). It might be contingent on sending the 80 0 0 0 command to halt movement.

Here's a log that's significantly longer than OR2SP's:
Code:
Started!
FF FF 0 0  
7F  
F0 0 0 70  
FF 0 0 7F  
F0 0 0 70  
FF 0 0 7F  
F0 0 0 70  
80 0 1 1  
FA 0 10 6A  
81 7F 7F 1  
82 C 54 5A  
86 0 0 6  
89 0 8 1  
FC 0 20 5C  
F0 0 0 70  
FC 0 30 4C  
F0 0 0 70  
FC 0 40 3C  
F0 0 0 70  
FA 0 14 6E  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
80 0 1 1  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
80 0 1 1  
84 1 20 25  
FA 0 14 6E  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
80 0 1 1  
84 0 60 64  
FA 0 10 6A  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 8 D  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 9 C  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 A F  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 B E  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 C 9  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 D 8  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 E B  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 F A  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 10 15  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 11 14  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 12 17  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 13 16  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 14 11  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
84 1 15 10  
F0 0 0 70  
83 5F 0 5C  
86 2 A E  
89 3 40 4A  
8A 10 58 42  
8B 1B 0 10  
84 1 0 5  
87 1 0 6  
80 0 0 0
Edit: It appears to start with an errant FF that throws off the first line in my log by shifting the end of the packet for FF 00 00 7F to the next line.

Edit2: It seems to throw in a couple new commands from OR2SP: 8A, 8B and 87
 
Last edited:
Here's a log from during gameplay in F-ZERO AX. My experience so far with this game and my OR2SP wheel is that it just self-centers. I don't seem to get any FFB effects from hitting walls.

One key command stands out to me. During menu selection the wheel self centers very well with a lot of resistance in either direction. The only command I'm seeing during that time is:
84 1 0 5

A couple of 83 commands show up, too, but mostly 84 and 80. Note that 80 shows up here as 80 0 1 1 instead of the 80 1 1 0 seen in OR2SP.

The full log looks to be too long a for a post, so I'll just show the unique values:
Code:
80 0 0 0  
80 0 1 1  
83 50 0 53  
83 5F 0 5C  
84 0 6B 6F  
84 0 6C 68  
84 0 6D 69  
84 0 6E 6A  
84 0 70 74  
84 0 72 76  
84 0 73 77  
84 0 74 70  
84 0 76 72  
84 0 77 73  
84 0 78 7C  
84 0 79 7D  
84 0 7A 7E  
84 0 7B 7F  
84 0 7C 78  
84 0 7D 79  
84 0 7E 7A  
84 0 7F 7B  
84 1 0 5  
84 1 1 4  
84 1 13 16  
84 1 15 10  
84 1 16 13  
84 1 2 7  
84 1 3 6  
84 1 4 1  
84 1 5 0  
84 1 6 3  
84 1 7 2  
84 1 8 D  
84 1 9 C  
84 1 A F  
84 1 B E  
84 1 C 9  
84 1 D 8  
84 1 E B  
84 1 F A
 
Another interesting discovery!

84 1 0 5 was the last command sent to my FFB board before I pushed the service button to get into the service menu, and the wheel is still self-centering without any ongoing communication. I even unplugged the communication wires!

So apparently this particular command can somehow make the FFB aware of a point that it needs to attain on its own. This may be the point where the center tab on the encoder disc is sensed by the PCB on the back of the FFB motor... or that PCB uses the encoder to keep track of position and somehow you can issue a command to stay at any point. I haven't figured that one out yet.

Edit: I happen to have the encoder disc PCB exposed in my cab for some adjustments after a repair and I can confirm that the center tab is NOT currently at the opto that senses it, so the PCB is keeping track of position with the disc.

Edit2: I recall one time booting up Crazy Taxi High Roller (no FFB in this game) after OR2SP and thinking the wheel was centering. Now I know I wasn't crazy! :P
 
Back
Top