user4396: I would like to use an inertial sensor to measure acceleration and send the results to an Android app using a serial communication with a bluetooth Mate Gold module. The sensor provides a data ready interrupt which notifies Arduino-Mega that a new value is stored in a register of the module. The output data rate can be modified during the configuration of the sensor.
I want the information to be sent at a 10 Hz rate to the bluetooth module.
Is an interrupt at 400Hz capable of compromising the integrity of a 50 bytes long message sent at 10 Hz with a baudrate of 9600? 
If yes, which approach would you recommend to correctly send the data?
Edit:
I'm using the following formula to compute the amount of time required to send N chars.
bytes x bits_per_character / bits_per_second
N x (8+2) / 9600 = N/960 secs

For N = 52:
52/960 = 0.054 secs = 54 ms

So theoretically, I can send a 54 char-long message at 18Hz with a baudrate of 9600. 
Edit2
I can use the hardware serial or the Software Serial interface.

user3742: What you are looking for is a way to safely interleave transmitting characters while at same time responding to the interrupts.  You can wrap the sending of bytes with
noInterrupts();
swSerial.write("somethinglongyaddayadda"); // takes 50-60 ms
interrupts();

That will protect the write() operation from being interrupted and ruined by you sensor interrupt handler.  But as you note, that will block the ability to process the the sensor every 2.5 ms.  During the noInterrupts() period you would miss readings.
To achieve the interleave of both operations, you should transmit the message one character at a time.  Implement a transmit queue to hold the outbound string.  When it has characters, send them 1 at a time, wrapping each interrupt protection:
...inside loop...
if(txQueue is not empty) {
  // do not need noInterrupts() or cli() as these are inside write();
  swSerial.write(one character from Q); // takes ~1 ms
  txPointerHead += 1;
}
// at this point the interrupts are enabled 
// and the sensor will be processed if available
// if the interrupt occurred in the middle of the above, 
// the level is still set and the interrupt handler will be invoked

The 1 ms is ideal and not accounting for overhead, but it is unlikely the 1 character write time could stretch out to 2.5 ms.  As long as the write time stays under 2.5 ms, you will never drop a sensor reading.
Note that this interleave means that the characters will have larger inter-character delay.  The serial ports will not care about that.  But if the processing of the sensor data takes too much time, you will not be able to keep up with your 10 messages per second goal.
Some options I see to improve:

Use a higher baud rate.  The baudrate of the serial port is not related to the bluetooth data rate, so you might as well use the 115.2k.  That will reduce the blocking time.  The baud rate doesn't even need to be the same on both ends.  The BT module isn't a simple modem; it is packetizing characters wrapping them in encryption and transmitting.  The receiver unbundles the packets and pushes out its serial port at the receivers baud rate.
Use hardware serial.  Using a hardware serial port greatly reduces the time because all write() does is put one character into a register.  The time for that is microsecond domain.  After the byte is put in the transmit register, the UART handles the clocking of the bits so the microcontroller is free to do other tasks.


user1186: You want to send a 50 byte (or 52 byte?) sequence every 100 ms (10 Hz).
For hardware serial, that will go into a buffer which is emptied via serial interrupts; it should be emptied well before the next 100 ms tic (as you have calculated).
You will get about 40 sensor interrupts during that 100 ms.  With hardware serial, that need not be a problem - so long as you don't send bytes from within a sensor interrupt.  If your sensor interrupt just accumulates results and the main loop (non-interrupt) uses those results to periodically send the 50 byte message, you should be good.
Suppose you were averaging each of the sensor readings.  In the sensor interrupt you might add 1 to the count and add the reading to a sum value.  In the main loop, test if it has it has been 100 msec since the last send, and if so turn off interrupts, divide the sum by the count and store that average in a new variable, zero the sum and count, turn on interrupts.  Then use the computed average to format and send the 50 byte package.
That's just an example.  The main thing is to make the sensor interrupt quick and simple; and to format and send the packet in the main loop (inhibiting interrupts temporarily while fetching and clearing the variables which get updated during the sensor interrupt).
Be sure to use "volatile" for the variables used by both the sensor interrupt and the main loop.
The serial should take care of itself if you use hardware serial, and might even be OK for software serial.  In the latter case, a sensor interrupt in the middle of sending the bits of a single character/byte would mess up the bit timing, but software serial should inhibit interrupts during that time - so your sensor interrupt might be delayed up to a millisecond.

user86: If you are on the ardruino platform, and are using the hardware serial port, you basically don't have to do anything.
The Serial library interface already uses a outgoing data-buffer (it's varies between versions, 1.5.5 has it set to 64 bytes. The arduino people keep changing it's size for no reason), where the call to Serial.print() or Serial.write() only places the bytes in question into the outgoing buffer, and the buffer is then emptied asynchronously in the background by the TX-ready (UDRE) interrupt (which is then disabled when the buffer is emptied).
Basically, all you have to do is ensure that you're not placing data into the transmit buffer from both an interrupt and the main loop(), because it's then possible for the message from the interrupt to be inserted into the middle of the message from the main loop thread.
This can be easily enough done by either guarding the call to Serial.print() with cli() sei() interrupt guards in the main loop() section (or the useless arduino analog: noInterrupts() and interrupts(), which are just named proxies for cli() sei(), which exists for no good reason), or simply not printing from an interrupt (which is a good idea anyways, string formatting can be slow).

4396: <p>I would like to use an inertial sensor to measure acceleration and send the results to an Android app using a serial communication with a <strong>bluetooth Mate Gold</strong> module. The sensor provides a data ready interrupt which notifies <strong>Arduino-Mega</strong> that a new value is stored in a register of the module. The output data rate can be modified during the configuration of the sensor.
I want the information to be sent at a 10 Hz rate to the bluetooth module.</p>

<p>Is an interrupt at 400Hz capable of compromising the integrity of a 50 bytes long message sent at 10 Hz with a baudrate of 9600? 
If yes, which approach would you recommend to correctly send the data?</p>

<p><strong>Edit</strong>:
I'm using the following formula to compute the amount of time required to send N chars.</p>

<pre><code>bytes x bits_per_character / bits_per_second
N x (8+2) / 9600 = N/960 secs
</code></pre>

<p>For N = 52:</p>

<pre><code>52/960 = 0.054 secs = 54 ms
</code></pre>

<p>So theoretically, I can send a 54 char-long message at 18Hz with a baudrate of 9600. </p>

<p><strong>Edit2</strong>
I can use the hardware serial or the Software Serial interface.</p>
 3742: <p>What you are looking for is a way to safely interleave transmitting characters while at same time responding to the interrupts.  You can wrap the sending of bytes with</p>

<pre><code>noInterrupts();
swSerial.write("somethinglongyaddayadda"); // takes 50-60 ms
interrupts();
</code></pre>

<p>That will protect the write() operation from being interrupted and ruined by you sensor interrupt handler.  But as you note, that will block the ability to process the the sensor every 2.5 ms.  During the noInterrupts() period you would miss readings.</p>

<p>To achieve the interleave of both operations, you should transmit the message one character at a time.  Implement a transmit queue to hold the outbound string.  When it has characters, send them 1 at a time, wrapping each interrupt protection:</p>

<pre><code>...inside loop...
if(txQueue is not empty) {
  // do not need noInterrupts() or cli() as these are inside write();
  swSerial.write(one character from Q); // takes ~1 ms
  txPointerHead += 1;
}
// at this point the interrupts are enabled 
// and the sensor will be processed if available
// if the interrupt occurred in the middle of the above, 
// the level is still set and the interrupt handler will be invoked
</code></pre>

<p>The 1 ms is ideal and not accounting for overhead, but it is unlikely the 1 character write time could stretch out to 2.5 ms.  As long as the write time stays under 2.5 ms, you will never drop a sensor reading.</p>

<p>Note that this interleave means that the characters will have larger inter-character delay.  The serial ports will not care about that.  But if the processing of the sensor data takes too much time, you will not be able to keep up with your 10 messages per second goal.</p>

<p>Some options I see to improve:</p>

<ol>
<li><p>Use a higher baud rate.  The baudrate of the serial port is not related to the bluetooth data rate, so you might as well use the 115.2k.  That will reduce the blocking time.  The baud rate doesn't even need to be the same on both ends.  The BT module isn't a simple modem; it is packetizing characters wrapping them in encryption and transmitting.  The receiver unbundles the packets and pushes out its serial port at the receivers baud rate.</p></li>
<li><p>Use hardware serial.  Using a hardware serial port greatly reduces the time because all write() does is put one character into a register.  The time for that is microsecond domain.  After the byte is put in the transmit register, the UART handles the clocking of the bits so the microcontroller is free to do other tasks.</p></li>
</ol>
 1186: <p>You want to send a 50 byte (or 52 byte?) sequence every 100 ms (10 Hz).</p>

<p>For hardware serial, that will go into a buffer which is emptied via serial interrupts; it should be emptied well before the next 100 ms tic (as you have calculated).</p>

<p>You will get about 40 sensor interrupts during that 100 ms.  With hardware serial, that need not be a problem - <strong>so long as you don't send bytes from within a sensor interrupt</strong>.  If your sensor interrupt just accumulates results and the main loop (non-interrupt) uses those results to periodically send the 50 byte message, you should be good.</p>

<p>Suppose you were averaging each of the sensor readings.  In the sensor interrupt you might add 1 to the count and add the reading to a sum value.  In the main loop, test if it has it has been 100 msec since the last send, and if so turn off interrupts, divide the sum by the count and store that average in a new variable, zero the sum and count, turn on interrupts.  Then use the computed average to format and send the 50 byte package.</p>

<p>That's just an example.  The main thing is to make the sensor interrupt quick and simple; and to format and send the packet in the main loop (inhibiting interrupts temporarily while fetching and clearing the variables which get updated during the sensor interrupt).</p>

<p>Be sure to use "volatile" for the variables used by both the sensor interrupt and the main loop.</p>

<p>The serial should take care of itself if you use hardware serial, and might even be OK for software serial.  In the latter case, a sensor interrupt in the middle of sending the bits of a single character/byte would mess up the bit timing, but software serial should inhibit interrupts during that time - so your sensor interrupt might be delayed up to a millisecond.</p>
 86: <p>If you are on the ardruino platform, and are using the hardware serial port, you basically don't have to do anything.</p>

<p>The <code>Serial</code> library interface already uses a outgoing data-buffer (it's varies between versions, 1.5.5 has it set to 64 bytes. The arduino people keep changing it's size for no reason), where the call to <code>Serial.print()</code> or <code>Serial.write()</code> only places the bytes in question into the outgoing buffer, and the buffer is then emptied asynchronously in the background by the TX-ready (<code>UDRE</code>) interrupt (which is then disabled when the buffer is emptied).</p>

<p>Basically, all you have to do is ensure that you're not placing data into the transmit buffer from both an interrupt and the main <code>loop()</code>, because it's then possible for the message from the interrupt to be inserted into the middle of the message from the main loop thread.</p>

<p>This can be easily enough done by either guarding the call to <code>Serial.print()</code> with <code>cli()</code> <code>sei()</code> <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html" rel="nofollow noreferrer">interrupt guards</a> in the main <code>loop()</code> section (or the useless arduino analog: <code>noInterrupts()</code> and <code>interrupts()</code>, which are just named proxies for <code>cli()</code> <code>sei()</code>, which exists for no good reason), or simply not printing from an interrupt (which is a good idea anyways, string formatting can be slow).</p>
