user1063: I will be using an Arduino as a bridge between a computer high-level Java client and some low-level hardware computing units (e.g. other Arduinos). I need to find a solution to periodically communicate in both ways. It should be possible to send digital, analog inputs to the PC and receive digital, analog outputs from the PC via serial.
I have very specific requirements for my project to work: 

Lowest possible latency in both ways. High latency would cause
instability of controlled systems.
Extremely constant, possibly user-defined update period. Varying
sample rate would cause inaccuracies in the control.

I need a very fast solution possible for update frequency of 100 Hz and higher.
So far I have tried to send data via Firmata to my java client using time interrupt.
ISR(TIMER1_COMPA_vect) {
  Firmata.sendAnalog(analog, analogRead(analog));
}

The messages however don't come at a very constant rate and are sometimes held up for twice the sample period or more which is unnaceptable. For higher frequencies this happens even more often. I suspect some kind of a buffer. Do you have any idea where should I look for bottlenecks? Would it be benefiting to design my own communication protocol and ditch Firmata?
EDIT: Look at the attached diagram . Blue lines are "inputs", green lines "outputs". Right now I am trying to design the "Arduino (Bridge)"


user643: 
Lowest possible latency in both ways. High latency would cause instability of controlled systems.

the fact that you are using a not-real-time OS introduce a lot of unpredictable latency, the use of a visrtual machine over that os then add a bit more.
Fast communication can be obtained increasing the baudrate, that will decrease the latency between the sample and the elaboration. 
Also sending RAW data instead of string will be faster (no convertion AND less byte send), and finally decreasing the overhead caused by the protocol.
For example Firmata by default use a low baudrate AND will add a lot of overhead to send WHAT kind of operation is doing. Writing your own communication protocol is better.
For example: analogRead use 10bit, so you may send a raw int, 2 byte, 16bit, so 6 bit are lost.. or you can "compress" with a bit of bitwise operation 4 read (40 bit) into 5 byte (40bit, no bit loss) instead of 8(int size * 4)!
AnalogRead is a really slow operation by default on arduino (~200us), but can be faster if you set up a lower prescaler (attention, lower prescaler means less ADC precision. at prescaler 16 guaranteed precision is 8bit, if my memory is good)

Extremely constant, possibly user-defined update period. Varying sample rate would cause inaccuracies in the control.

On the PC side, if you need micro/nano second precision you need a real time os, newest linux kernel add a new special schedule but i think is still hard to find documentation. If less precision is ok, just use a timer.
On the arduino side, using a hardware timer is the best way, see LeOS for a nice scheduler on arduino
Please note HardwareSerial on the arduino side use interrupt to send data, so using it inside an ISR (like you are doing now or with LeOS) is really usafe and deadlock prone.
Also ISR will "slow down" each others, as they cannnot be executed parallel; and analogRead is a realtivly slow operation..
I would use timer to set up a flag, and in the loop if i see the flag, start the analogread, Serial.write and finally Serial.flush (to be sure to not fill Serial buffer, causing a lot of trouble on the arduino reprogrammation reset)

user1117: could you be more specific with your question ?
From what I understood:

you have a client java program acting as the "brain" of your system
your control is time sensitive. You have a PID or other regulation loop running on the pc
you have or plan to have multiple arguing boards on your system and you need to communicate with them.
you are dealing with analog IOs

bridging
If you want to stick to serial port,you have to use RS485 or RS422. Those can work as a bus. Protocol on top of that can be Modbus.
Note that this has a higher latency and you need at least 2 serial ports on your bridge
I2C. Lower latency 2 wires bus. Command oriented,runs at 400 kHz. So you have plenty of time to send/receive data
SPI even lower latency as bytes are sent as stream .arduino mega has 5 pins for it. Note that you have to deal with the addressing yourself in this case.
Arduino like many micro controllers is bad as doing many tasks at the same time like for the bridging case. I would avoid using an arduino in this case
latency
As already answered, ADC conversion takes time and you cannot nest interrupt.
Your minimum latency can be computed from the specifications of the arduino.
The maximum latency is a value you fix yourself.
Knowing the amount of time to send one byte on the communication port,
You can decide between options like

run the AD conversion in a loop outside interrupt, put the value inside a variable and do the communication a synchronously inside an interrupt
run the AD conversion interrupt based and the communication in the main loop of operation

conclusions
Don't do hardware in the loop using a PC. The latency and lack of strict timing possibilities worsened by the use of java make it a dead end with your current setup.
Use a stronger micro controller like an AVR32 with USB running the brain of your system.
You can also use a raspberries pi or a beaglebone. Those runs "standard" Linux distributions and so you can use a PC like approach.
In any case guidelines are :

try to stay as close to the micro controller as possible and avoid abstraction libraries and OSes
don't use a pc for hardware in the loop
try to make your task run a synchronously as much as possible
keep your interrupt routines as small as possible


1063: <p>I will be using an Arduino as a bridge between a computer high-level Java client and some low-level hardware computing units (e.g. other Arduinos). I need to find a solution to <strong>periodically</strong> communicate in <strong>both</strong> ways. It should be possible to send digital, analog inputs to the PC and receive digital, analog outputs from the PC via serial.</p>

<p>I have very specific requirements for my project to work: </p>

<ol>
<li><p>Lowest possible latency in both ways. High latency would cause
instability of controlled systems.</p></li>
<li><p>Extremely constant, possibly user-defined update period. Varying
sample rate would cause inaccuracies in the control.</p></li>
</ol>

<p>I need a very fast solution possible for update frequency of 100 Hz and higher.</p>

<p>So far I have tried to send data via Firmata to my java client using time interrupt.</p>

<pre><code>ISR(TIMER1_COMPA_vect) {
  Firmata.sendAnalog(analog, analogRead(analog));
}
</code></pre>

<p>The messages however don't come at a very constant rate and are sometimes held up for twice the sample period or more which is unnaceptable. For higher frequencies this happens even more often. I suspect some kind of a buffer. Do you have any idea where should I look for bottlenecks? Would it be benefiting to design my own communication protocol and ditch Firmata?</p>

<p>EDIT: Look at the attached <a href="https://i.imgur.com/8dHjU8A.png" rel="nofollow noreferrer">diagram </a>. Blue lines are "inputs", green lines "outputs". Right now I am trying to design the "Arduino (Bridge)"
<img src="https://i.stack.imgur.com/fAmud.png" alt="enter image description here"></p>
 643: <blockquote>
  <p>Lowest possible latency in both ways. High latency would cause instability of controlled systems.</p>
</blockquote>

<p>the fact that you are using a not-real-time OS introduce a lot of unpredictable latency, the use of a visrtual machine over that os then add a bit more.
Fast communication can be obtained increasing the baudrate, that will decrease the latency between the sample and the elaboration. 
Also sending RAW data instead of string will be faster (no convertion AND less byte send), and finally decreasing the overhead caused by the protocol.</p>

<p>For example Firmata by default use a low baudrate AND will add a lot of overhead to send WHAT kind of operation is doing. Writing your own communication protocol is better.</p>

<p>For example: analogRead use 10bit, so you may send a raw int, 2 byte, 16bit, so 6 bit are lost.. or you can "compress" with a bit of bitwise operation 4 read (40 bit) into 5 byte (40bit, no bit loss) instead of 8(int size * 4)!</p>

<p>AnalogRead is a really slow operation by default on arduino (~200us), but can be faster if you set up a lower prescaler (attention, lower prescaler means less ADC precision. at prescaler 16 guaranteed precision is 8bit, if my memory is good)</p>

<blockquote>
  <p>Extremely constant, possibly user-defined update period. Varying sample rate would cause inaccuracies in the control.</p>
</blockquote>

<p>On the PC side, if you need micro/nano second precision you need a <code>real time os</code>, newest linux kernel add a new special schedule but i think is still hard to find documentation. If less precision is ok, just use a timer.</p>

<p>On the arduino side, using a hardware timer is the best way, see <a href="http://www.leonardomiliani.com/2012/leos-un-semplice-so-per-arduino/?lang=en" rel="nofollow">LeOS</a> for a nice scheduler on arduino</p>

<p>Please note HardwareSerial on the arduino side use interrupt to send data, so using it inside an ISR (like you are doing now or with LeOS) is really usafe and deadlock prone.
Also ISR will "slow down" each others, as they cannnot be executed parallel; and analogRead is a realtivly slow operation..
I would use timer to set up a flag, and in the loop if i see the flag, start the analogread, Serial.write and finally Serial.flush (to be sure to not fill Serial buffer, causing a lot of trouble on the arduino reprogrammation reset)</p>
 1117: <p>could you be more specific with your question ?
From what I understood:</p>
<ul>
<li>you have a client java program acting as the &quot;brain&quot; of your system</li>
<li>your control is time sensitive. You have a PID or other regulation loop running on the pc</li>
<li>you have or plan to have multiple arguing boards on your system and you need to communicate with them.</li>
<li>you are dealing with analog IOs</li>
</ul>
<h2>bridging</h2>
<p>If you want to stick to serial port,you have to use RS485 or RS422. Those can work as a bus. Protocol on top of that can be Modbus.
Note that this has a higher latency and you need at least 2 serial ports on your bridge</p>
<p>I2C. Lower latency 2 wires bus. Command oriented,runs at 400 kHz. So you have plenty of time to send/receive data</p>
<p>SPI even lower latency as bytes are sent as stream .arduino mega has 5 pins for it. Note that you have to deal with the addressing yourself in this case.</p>
<p>Arduino like many micro controllers is bad as doing many tasks at the same time like for the bridging case. I would avoid using an arduino in this case</p>
<h2>latency</h2>
<p>As already answered, ADC conversion takes time and you cannot nest interrupt.
Your minimum latency can be computed from the specifications of the arduino.
The maximum latency is a value you fix yourself.
Knowing the amount of time to send one byte on the communication port,
You can decide between options like</p>
<ul>
<li>run the AD conversion in a loop outside interrupt, put the value inside a variable and do the communication a synchronously inside an interrupt</li>
<li>run the AD conversion interrupt based and the communication in the main loop of operation</li>
</ul>
<h2>conclusions</h2>
<p>Don't do hardware in the loop using a PC. The latency and lack of strict timing possibilities worsened by the use of java make it a dead end with your current setup.</p>
<p>Use a stronger micro controller like an AVR32 with USB running the brain of your system.
You can also use a raspberries pi or a beaglebone. Those runs &quot;standard&quot; Linux distributions and so you can use a PC like approach.</p>
<p>In any case guidelines are :</p>
<ul>
<li>try to stay as close to the micro controller as possible and avoid abstraction libraries and OSes</li>
<li>don't use a pc for hardware in the loop</li>
<li>try to make your task run a synchronously as much as possible</li>
<li>keep your interrupt routines as small as possible</li>
</ul>
