So far, I'm able to send one byte from the master RPi which initiates the ISR on the arduino UNO. The arduino UNO takes the received byte from RPi adds a number to it and assign it back to SPDR which is sent back to the RPi.
Now I'm trying to transmit more bytes - let's say an integer - instead of one byte but I'm not sure how to do it. your inputs are highly appreciated.
Arduio UNO code
#include <SPI.h>
int data;
byte c;
int x_val;
void setup() {
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
pinMode(A5, INPUT);
Serial.begin(9600);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPI.attachInterrupt();
}
// SPI interrupt routine
ISR (SPI_STC_vect)
{
c = SPDR;//Storing the SPI incoming byte
SPDR = c+5; //Changing SPDR byte to a variable to be sent back to master
} // end of interrupt service routine (ISR) for SPI
void loop () {
x_val = analogRead(A5);//Reading the analog value and assigning it to a variable
Serial.println(x_val);//Printing this value to serial just to verify
}
Thank you @Idahowalker for your response.
Yes, theoretically I should be sending these bytes one by one and re-assemble them. Any idea how to do that using SPDR on the arduino side?
On Raspberry Pi side, I can change the buffer array to contain 4 bytes
unsigned char buf[4] = {entered_value, 0, 0, 0};
Then, the last input in the function " wiringPiSPIDataRW" can be changed to 4 as well to receive the 4 bytes.
wiringPiSPIDataRW(SPI_CHANNEL, buf, 4);" function
However, I'm not sure how the code will look like on the Arduino UNO side. I'm not sure how I can send a different byte to the RPi during a 4 bytes single transmission session.
I use the ESP32's API when I do SPI thingies.
I have some code here where I write 32 bits to the SPI bus, I doubt it will be of help but I post it just in case.
void fReadSPIdata16bits( spi_device_handle_t &h, int _address )
{
uint8_t address = _address;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 3); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 8 * 2 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = rxData;
txData[0] = address | 0x80;
intError = spi_device_transmit( h, &trans_desc);
low = rxData[0]; high = rxData[1];
// if ( intError != 0 )
// {
// Serial.print( " WHO I am LSM9DS1. Transmitting error = ");
// Serial.println ( esp_err_to_name(intError) );
// }
} // void fSendSPI( uint8_t count, uint8_t address, uint8_t DataToSend)
////
int fWriteSPIdata8bits( spi_device_handle_t &h, int _address, int _sendData )
{
uint8_t address = _address;
uint8_t sendData = _sendData;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 2); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 0 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = NULL;
txData[0] = address & 0x7F;
txData[1] = sendData;
intError = spi_device_transmit( h, &trans_desc);
// // if ( intError != 0 )
// // {
// // Serial.print( " LSM9DS1_REGISTER_CTRL_REG6_XL. Transmitting error = ");
// // Serial.println ( esp_err_to_name(intError) );
// // }
return intError;
} // void fWriteSPIdata8bits( spi_device_handle_t &h, uint8_t address, uint8_t sendData )
//
int fWriteSPIdata8bits2( spi_device_handle_t &h, int _sendData )
{
rxData[0] = 0x00;
// uint8_t address = _address;
uint8_t sendData = _sendData;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 2); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 8 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = rxData;
txData[0] = sendData;
// txData[0] = address;
// txData[1] = sendData;
intError = spi_device_transmit( h, &trans_desc);
if ( intError == 0 )
{
return rxData[0];
}
else
{
return intError;
}
} // void fWriteSPIdata8bits( spi_device_handle_t &h, uint8_t address, uint8_t sendData )
////
int fWriteSPIdata32bits( spi_device_handle_t &h, int _sendData0, int _sendData1, int _sendData2, int _sendData3 )
{
// uint8_t address = _address;
// uint8_t sendData = _sendData;
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = (8 * 4); // total data bits
trans_desc.tx_buffer = txData;
trans_desc.rxlength = 0 ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = NULL;
txData[0] = (uint8_t)_sendData0; // command bits
txData[1] = (uint8_t)_sendData1; // lower bits
txData[2] = (uint8_t)_sendData2; // higher bits
txData[3] = (uint8_t)_sendData3; // address
intError = spi_device_transmit( h, &trans_desc);
return intError;
} // void fWriteSPIdata8bits( spi_device_handle_t &h, uint8_t address, uint8_t sendData )
////
int fReadSPIdataXbits( spi_device_handle_t &h, int _readaddress, int *rxbuf, int rxlen )
{
uint8_t address = _readaddress;
int8_t rxBuf[rxlen] = {0};
esp_err_t intError;
spi_transaction_t trans_desc;
trans_desc = { };
trans_desc.addr = 0;
trans_desc.cmd = 0;
trans_desc.flags = 0;
trans_desc.length = ( (8 * 1) + (8 * rxlen)); // total data bits
trans_desc.tx_buffer = txData ;
trans_desc.rxlength = 8 * rxlen ; // Number of bits NOT number of bytes
trans_desc.rx_buffer = rxBuf;
txData[0] = address;
// txData[1] = 0x00;
intError = spi_device_transmit( h, &trans_desc);
for (int i = 0; i < rxlen; i++)
{
rxbuf[i] = rxBuf[i];
}
return intError;
} // int fReadSPIdataXbits( spi_device_handle_t &h, int _readaddress, int *rxbuf, int rxlen )
I've managed to send 4 bytes from arduino slave to RPi master. I've changed the code in the RPi by adding a for loop.
RPi Code
#include <iostream>
#include <wiringPiSPI.h>
#include <unistd.h> //for sleep function
#define SPI_CHANNEL 0
#define SPI_CLOCK_SPEED 1000000
unsigned char received_val[4];
int constructed_buffer;
int main(int argc, char **argv)
{
int entered_value = 132; //this is just for testing it could be any value
int fd = wiringPiSPISetupMode(SPI_CHANNEL, SPI_CLOCK_SPEED, 0);
if (fd == -1) {
std::cout << "Failed to init SPI communication.\n";
return -1;
}
std::cout << "SPI communication successfully setup.\n";
while(1) //while loop so I dont need to run the app everytime /just for testing
{
unsigned char buf[1] = {entered_value}; //this buffer will be sent over SPI
for(int i=0; i<=3; i++) //This foor loop is used to send 4 bytes
{
wiringPiSPIDataRW(SPI_CHANNEL, buf, 1);
received_val[i]=buf[0]; //the received byte is stored in the char array
std::cout << "Buf returned "<< i << ": " << int(received_val[i]) << " - "; //will print each received byte just for testing
}
//Re-constructing the 4 bytes into one integer
constructed_buffer = received_val[0] << 24 | received_val[1]<< 16| received_val[2] << 8 | received_val[3];
std::cout << "constructed_buffer = " << constructed_buffer << "\n";
std::cout << "\n";
sleep(1); //delay just to keep things under control
}
return 0;
}
Arduino Code
#include <SPI.h>
byte c;
int x_val;
int counter = 0;
byte buf[6]={9,9,9,9,9,9}; //Just for testing
byte sent_buf[4]={255,0,255,0}; //the four bytes that will be sent to the RPi
void setup() {
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
pinMode(A5, INPUT);
Serial.begin(9600);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPI.attachInterrupt();
}
// SPI interrupt routine
ISR (SPI_STC_vect)
{
c = SPDR;//Storing the SPI incoming byte
if (c == 132 && counter == 0) //132 is the number we set in the RPi just so we know this is the first byte
{
buf[0] = SPDR;
SPDR = sent_buf[1]; //this will be second byte on the RPi
counter =1;
}
else if (counter == 1)
{
buf[1] = SPDR;
SPDR = sent_buf[2]; //this will be third byte on the RPi
counter =2;
}
else if (counter == 2)
{
buf[2] = SPDR;
SPDR = sent_buf[3]; //this will be fourth byte on the RPi
counter =3;
}
else if (counter == 3)
{
buf[3] = SPDR;
SPDR = sent_buf[0]; //this will be First byte on the RPi
counter =0;
}
} // end of interrupt service routine (ISR) for SPI
void loop () {
x_val = analogRead(A5);//Reading the analog value and assigning it to a variable
delay(300);
}