Hi, I am trying to send a float from an arduino slave to an arduino master via an SPI interface. I am using a union on the slave to split the float into 4 bytes, and sending each byte over the SPI bus. I am using four bytes in another union on the master, so I can print the resulting float to the serial monitor. The output that I am getting is not correct. I have tried reading the data order as MSB and LSB and neither option yields the same float that is being sent from the slave. Please help? I am at a loss I can not seem to figure out what I am doing wrong.
Here is a copy of the code I am using:
Master Code:
#include <SPI.h>
void setup (void)
{
pinMode(MOSI, OUTPUT);
pinMode(MISO, INPUT);
pinMode(SCK, OUTPUT);
pinMode(SS, OUTPUT);
Serial.begin (115200);
Serial.println ();
digitalWrite(SS, HIGH);
SPI.begin ();
SPI.setBitOrder(MSBFIRST); // MSB first bit order
SPI.setClockDivider(SPI_CLOCK_DIV8);
}
byte transferAndWait (const byte what)
{
byte a = SPI.transfer (what);
delayMicroseconds (20);
return a;
}
union first_union{
float f;
byte b[4];}
data;
float float_number;
void loop (void)
{
digitalWrite(SS, LOW);
transferAndWait ('a');
data.b[0] = transferAndWait ('b');
data.b[1] = transferAndWait ('c');
data.b[2] = transferAndWait ('d');
data.b[3] = transferAndWait (0);
digitalWrite(SS, HIGH);
float_number = data.f;
Serial.print("data.f = ");Serial.println(data.f);
delay(1000);
Serial.print("data.b[0] = ");Serial.println(data.b[0]);
Serial.print("data.b[1] = ");Serial.println(data.b[1]);
Serial.print("data.b[2] = ");Serial.println(data.b[2]);
Serial.print("data.b[3] = ");Serial.println(data.b[3]);
delay(1000);
Slave Code:
byte command = 0;
void setup (void)
{
pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);
pinMode(SS, INPUT);
pinMode(MISO, OUTPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPCR |= _BV(SPIE);
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
union first_union{
float f;
byte b[4];}
data;
byte c = SPDR;
data.f = 3.14;
switch (command)
{
// no command? then this is the command
case 0:
command = c;
SPDR = 0;
break;
// incoming byte, return byte result
case 'a':
SPDR = data.b[0];
break;
// incoming byte, return byte result
case 'b':
SPDR = data.b[1];
break;
// incoming byte, return byte result
case 'c':
SPDR = data.b[2];
break;
// incoming byte, return byte result
case 'd':
SPDR = data.b[3];
break;
} // end of switch
} // end of interrupt service routine (ISR) SPI_STC_vect
void loop (void)
{
// if SPI not active, clear current command
if (digitalRead (SS) == HIGH)
command = 0;
}
Here is a sample of the output I am getting:
data.b[0] = 0
data.b[1] = 195
data.b[2] = 195
data.b[3] = 195
data.f = -391.52
The code I as showing here was adapted from code that I got from the following link: