It depends on how you organize your code and what all you wish to do communicate...
Depending on what all I am doing and the frequency of query... I might do things different.
Soon I will be playing with my RPI (more likely up board or Odroid) to Teensy communications where I will have the teensy controlling motors and sensors...
Currently the code uses USART to do all of this. The Host sends a packet, which is of some known format, where the Teensy sees the data and either forwards the data to the servos or it
intercepts the command and generates it's own response again with a know packet format...
But I am thinking of doing some of this different using I2C. I will have the Teensy as the I2C slave to the host. I will have the slave Teensy act like a several different devices, where the
host can issue a write, request where the host specifies the starting logical register and the data, which I will simply save away into an array. I may also do some post processing of the command as some registers will interact with hardware (like turn on LED, maybe set IO pin state....). Or the Host may issue a read request where again they specify the starting register number and how many bytes to return...
I would then setup the logical registers something like:
<encoder 1 low>
<encoder 1 high>
<encoder 2 low>
<encoder 2 high>
...
<button 1>
<button 2>
<led 1>
<led 2>
...