My intention is to collect by SPI-Master (the UNO) binray32 formatted temperature signal from SPI-Slave (the NANO) by the hardware setup of Fig-1 and using SPI.transfer(buffer, sizeof buffer); type instruction; where, the buffer contents are replaced by the incoming data bytes from the Slave. Unfortunately, I could not make the said instruction working; rather, I have managed to make the system working using byte recByte = SPI.transfer(byte); type instruction.
I have posted working sketches (based on byte recByte = SPI.transfer(byte); tinstruction) of both Master and Slave so that someone may point out where to bring modifications/adjustments in order to make the SPI.transfer(buffer, sizeof buffer); instruction working.
Figure-1:
SPI-Master Sketch:
#include<SPI.h>
byte myData[] = {0x00, 0x00, 0x00, 0x00};
float myTemp;
unsigned long tempData; //edit
void setup()
{
Serial.begin(9600);
SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
delay(100);
digitalWrite(SS, LOW); //Slave is selected
}
void loop()
{
for (int i = 0; i < 4; i++)
{
myData[i] = SPI.transfer(myData[i]);
Serial.println(myData[i], HEX); //1M/0S; 2M/1S; 3M/2S; 0M/3S(MSB)
}
tempData = (unsigned long)myData[0] << 24 | (unsigned long)myData[3] << 16 |
(unsigned long)myData[2] << 8 | (unsigned long)myData[1]; //edit
toFloat(); //converting received binary32 bit to float
Serial.print("Temperature received from Slave = ");
Serial.print(myTemp, 1); Serial.println(" degC");//shows: Room Temp
Serial.println("======================================");
delay(3000); //test interval
}
/*void toFloat()
{
long *ptr;
ptr = (long*)&myTemp;
*ptr = tempData;
}*/ //edit
//As discussed many times before, this is not a valid cast. You should use memcpy:
void toFloat()
{
static_assert(sizeof(tempData) == sizeof(myTemp), "");
memcpy(&myTemp, &tempData, sizeof tempData);
}
SPI-Slave Sketch:
#include<SPI.h>
byte myData[4];
int i = 0;
float myTemp;
void setup()
{
Serial.begin(9600);
analogReference(INTERNAL);
pinMode(SS, INPUT_PULLUP); // ensure SS stays high for now
pinMode(MISO, OUTPUT);
bitSet(SPCR, SPE);
bitSet(SPCR,MSTR); //Arduino is Slave
SPI.attachInterrupt(); //interrupt logic is enabled
}
void loop()
{
myTemp = 100 * (1.1 / 1023.0) * analogRead(A3);
Serial.print("Room Temperature = ");
Serial.print(myTemp, 1); Serial.println(" degC");
toBytes(); //converting binary32 data to bytes
delay(2000);
}
ISR(SPI_STC_vect)
{
SPDR = myData[i];
i++;
if (i == 4) //4-byte data are sent
{
i = 0; //array pointer is reset
}
}
/*void toBytes()
{
byte *ptr;
ptr = (byte*)&myTemp;
for (int i = 0; i < sizeof myTemp; i++)
{
myData[i] = *ptr;
ptr++;
}
}*/ //edit
//Although this is fine, it's probably best to use:
void toBytes()
{
static_assert(sizeof(myData) == sizeof(myTemp), "");
memcpy(myData, &myTemp, sizeof myTemp);
}
Master's Serial Monitor Output
41 //byte-3 (MSByte) of binray32 coming from Slave
DA //byte-0 (LSbyte) of binray32 coming from Slave
65 // byte-1 of binary32 coming from Slave
E7 //byte-2 of binary32 coming from Slave
Temperature received from Slave = 28.9 degC
============================================


