user37429: I have tried getting my Arduino to communicate with another device, to no avail. The command A, when sent via serial to the device, triggers it to respond with 8 binary bytes with the first 4 representing a floating point number, and the final 4 representing a floating point number. The command only has to be sent once a second, and the aim is to store the 8 incoming bytes in an array, and convert them into their respective floats.
unsigned long previousMillis = 0;
const long interval = 1000;
char incomingByteA[8];

void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial1.begin(9600);
  while(!Serial1);
}

void loop() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis >= interval){
    //1 second timer
    previousMillis = currentMillis;
    Serial1.write('O');
    //Send command 'A' to device *noting Serial1 not Serial
    for(int n = 0; Serial1.available() < 8; n++) {
    incomingByteA[n] = Serial1.read();
    //Add each consecutive byte to an array until all 8 bytes have been added
  }
  float x;
  float y;
  ((byte*)&x)[3] = incomingByteA[0];
  //Convert first four bytes into a float
  ((byte*)&x)[2] = incomingByteA[1];
  ((byte*)&x)[1] = incomingByteA[2];
  ((byte*)&x)[0] = incomingByteA[3];
  ((byte*)&y)[3] = incomingByteA[4];
  //Convert final four bytes into a float
  ((byte*)&y)[2] = incomingByteA[5];
  ((byte*)&y)[1] = incomingByteA[6];
  ((byte*)&y)[0] = incomingByteA[7];
  Serial.println(x, 4);
}
} 

However, when I do Serial.println(x);, it returns "nan". And if I try to do Serial.println(incomingByteA[2]);, it returns "?".
The following is the floating point format as per the device protocol:
31: sign of mantissa, 1=negative.
30-23: exponent, biased by 128.
22-0: mantissa, 24 bits, MSB hidden and always=1.
The mantissa is normalized, 24 bits with the MSB hidden. The MSB is always
assumed to be 1, therefore only 23 bits are needed to store the mantissa. The exponent is biased by 128; i.e. a 128 value represents an exponent of zero. A 129 value is an exponent of 1. Example: if the exponent has a 131 value (+3), the number is 2^3 * (mantissa). The mantissa is always less than one, and greater than or equal to 1/2. The number zero is stored as four zero bytes.
I am confident that it is not a fault with the hardware and for what it's worth, I am using a Leonardo. I would like to get the code down pat before I stress about hardware issues. What is this code not doing properly, if at all? 
Thanks in advance.

user4143: Two things I see wrong:

Serial1.write('O');                                            //Send command 'A' to device *noting Serial1 not Serial

No, you send O not A... ???

for(int n = 0; Serial1.available() < 8; n++)                   

While there are less than 8 bytes available in the buffer read one. 
Erm...  The buffer starts off empty - empty is less than 8. It remains empty (always less than 8) until a byte finally arrives. Then it's still less than 8. I can't really see this ever working, and your array will overflow instantly and clobber the entirety of the rest of your RAM. I guess it finally finished when the serial object itself gets clobbered and available() returns some garbage number. In the meantime your array is just full of nothingness.
You need to completely rewrite that whole section. The simplest way is to wait until there are 8 bytes in the buffer (which will take some time - serial is slooooow):
while (Serial1.available() < 8);

You now have 8 bytes available to read, so you can go ahead and read them.
A better way is to look to see if there is at least one byte available, then read it into the right place in your array - and keep count of how many bytes you have read:
int n = 0;
while (n < 8) {
    if (Serial1.available()) {
        incomingByteA[n++] = Serial1.read();
    }
}

Of course, it's better to add some form of timeout in there too - so if nothing arrives soon enough your program doesn't lock up - or if you miss a byte it doesn't get completely out of sync. Also purging your read buffer before sending the command can help to prevent sync issues:
// Purge any old data
while (Serial1.available()) {
    Serial1.read();
}

Serial1.write('A');

int n = 0;
uint32_t start = millis();
while (n < 8) {
    // 1 second timeout
    if (millis() - start > 1000) {
        break;
    }
    if (Serial1.available()) {
        incomingByteA[n++] = Serial1.read();
    }
}

if (n == 8) {
    // We got the data - do something with it
} else {
    // It timed out
}

Now when it comes to converting to a pair of floats there's better ways than your byte-wise manipulation.  For instance, you could use a union:
union FloatPair {
    struct {
        float a;
        float b;
    };
    char bytes[8];
} __attribute__((packed));

FloatPair data;

Now you can use:
data.bytes[n]

to access the memory directly, and
data.a;
data.b;

to access the float values.
You can also do something similar with casting:
struct FloatPair {
    float a;
    float b;
};

FloatPair data;

char *bytes = (char *)&data;

bytes is now a byte-wise view of the memory used by a pair of floats.
You can even work the other way around:
char data[8] __attribute__((aligned(4)));

The aligned attribute will force the address of the array to be on a 4-byte boundary. Not important for a little 8-bitter, but vital if you ever port to a 32-bit MCU since a float always has to be on a 4-byte boundary, so a good habit to get into.
Now you can map floats into that memory space:
float *a = (float *)(&data[0]);
float *b = (float *)(&data[4]);

and access the floats as *a and *b. The * dereferences the pointers back into real numbers.
One thing to note: these methods all depend on the endianness of your data matching the endianness of your MCU - if they differ then you will have no choice but to do it all with manual byte-wise mapping.

37429: <p>I have tried getting my Arduino to communicate with another device, to no avail. The command A, when sent via serial to the device, triggers it to respond with 8 binary bytes with the first 4 representing a floating point number, and the final 4 representing a floating point number. The command only has to be sent once a second, and the aim is to store the 8 incoming bytes in an array, and convert them into their respective floats.</p>

<pre><code>unsigned long previousMillis = 0;
const long interval = 1000;
char incomingByteA[8];

void setup() {
  Serial.begin(9600);
  while(!Serial);
  Serial1.begin(9600);
  while(!Serial1);
}

void loop() {
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis &gt;= interval){
    //1 second timer
    previousMillis = currentMillis;
    Serial1.write('O');
    //Send command 'A' to device *noting Serial1 not Serial
    for(int n = 0; Serial1.available() &lt; 8; n++) {
    incomingByteA[n] = Serial1.read();
    //Add each consecutive byte to an array until all 8 bytes have been added
  }
  float x;
  float y;
  ((byte*)&amp;x)[3] = incomingByteA[0];
  //Convert first four bytes into a float
  ((byte*)&amp;x)[2] = incomingByteA[1];
  ((byte*)&amp;x)[1] = incomingByteA[2];
  ((byte*)&amp;x)[0] = incomingByteA[3];
  ((byte*)&amp;y)[3] = incomingByteA[4];
  //Convert final four bytes into a float
  ((byte*)&amp;y)[2] = incomingByteA[5];
  ((byte*)&amp;y)[1] = incomingByteA[6];
  ((byte*)&amp;y)[0] = incomingByteA[7];
  Serial.println(x, 4);
}
} 
</code></pre>

<p>However, when I do <code>Serial.println(x);</code>, it returns "nan". And if I try to do <code>Serial.println(incomingByteA[2]);</code>, it returns "?".</p>

<p>The following is the floating point format as per the device protocol:</p>

<p>31: sign of mantissa, 1=negative.
30-23: exponent, biased by 128.
22-0: mantissa, 24 bits, MSB hidden and always=1.</p>

<p>The mantissa is normalized, 24 bits with the MSB hidden. The MSB is always
assumed to be 1, therefore only 23 bits are needed to store the mantissa. The exponent is biased by 128; i.e. a 128 value represents an exponent of zero. A 129 value is an exponent of 1. Example: if the exponent has a 131 value (+3), the number is 2^3 * (mantissa). The mantissa is always less than one, and greater than or equal to 1/2. The number zero is stored as four zero bytes.</p>

<p>I am confident that it is not a fault with the hardware and for what it's worth, I am using a Leonardo. I would like to get the code down pat before I stress about hardware issues. What is this code not doing properly, if at all? </p>

<p>Thanks in advance.</p>
 4143: <p>Two things I see wrong:</p>

<blockquote>
  <p>Serial1.write('O');                                            //Send command 'A' to device *noting Serial1 not Serial</p>
</blockquote>

<p>No, you send <code>O</code> not <code>A</code>... ???</p>

<blockquote>
  <p>for(int n = 0; Serial1.available() &lt; 8; n++)                   </p>
</blockquote>

<p>While there are less than 8 bytes available in the buffer read one. </p>

<p>Erm...  The buffer starts off empty - empty is less than 8. It remains empty (always less than 8) until a byte <em>finally</em> arrives. Then it's still less than 8. I can't really see this ever working, and your array will overflow instantly and clobber the entirety of the rest of your RAM. I guess it finally finished when the serial object itself gets clobbered and <code>available()</code> returns some garbage number. In the meantime your array is just full of nothingness.</p>

<p>You need to completely rewrite that whole section. The simplest way is to wait <em>until</em> there are 8 bytes in the buffer (which will take some time - serial is <em>slooooow</em>):</p>

<pre><code>while (Serial1.available() &lt; 8);
</code></pre>

<p>You now have 8 bytes available to read, so you can go ahead and read them.</p>

<p>A better way is to look to see if there is <em>at least</em> one byte available, then read it into the right place in your array - and keep count of how many bytes you have read:</p>

<pre><code>int n = 0;
while (n &lt; 8) {
    if (Serial1.available()) {
        incomingByteA[n++] = Serial1.read();
    }
}
</code></pre>

<p>Of course, it's better to add some form of timeout in there too - so if nothing arrives soon enough your program doesn't lock up - or if you miss a byte it doesn't get completely out of sync. Also purging your read buffer before sending the command can help to prevent sync issues:</p>

<pre><code>// Purge any old data
while (Serial1.available()) {
    Serial1.read();
}

Serial1.write('A');

int n = 0;
uint32_t start = millis();
while (n &lt; 8) {
    // 1 second timeout
    if (millis() - start &gt; 1000) {
        break;
    }
    if (Serial1.available()) {
        incomingByteA[n++] = Serial1.read();
    }
}

if (n == 8) {
    // We got the data - do something with it
} else {
    // It timed out
}
</code></pre>

<p>Now when it comes to converting to a pair of floats there's better ways than your byte-wise manipulation.  For instance, you could use a union:</p>

<pre><code>union FloatPair {
    struct {
        float a;
        float b;
    };
    char bytes[8];
} __attribute__((packed));

FloatPair data;
</code></pre>

<p>Now you can use:</p>

<pre><code>data.bytes[n]
</code></pre>

<p>to access the memory directly, and</p>

<pre><code>data.a;
data.b;
</code></pre>

<p>to access the float values.</p>

<p>You can also do something similar with casting:</p>

<pre><code>struct FloatPair {
    float a;
    float b;
};

FloatPair data;

char *bytes = (char *)&amp;data;
</code></pre>

<p><code>bytes</code> is now a byte-wise view of the memory used by a pair of floats.</p>

<p>You can even work the other way around:</p>

<pre><code>char data[8] __attribute__((aligned(4)));
</code></pre>

<p>The aligned attribute will force the address of the array to be on a 4-byte boundary. Not important for a little 8-bitter, but vital if you ever port to a 32-bit MCU since a float always has to be on a 4-byte boundary, so a good habit to get into.</p>

<p>Now you can map floats into that memory space:</p>

<pre><code>float *a = (float *)(&amp;data[0]);
float *b = (float *)(&amp;data[4]);
</code></pre>

<p>and access the floats as <code>*a</code> and <code>*b</code>. The <code>*</code> dereferences the pointers back into real numbers.</p>

<p>One thing to note: these methods all depend on the endianness of your data matching the endianness of your MCU - if they differ then you will have no choice but to do it all with manual byte-wise mapping.</p>
