Reputation: 1
I am currently trying to implement an SPI communication between 2 ESP32 using arduino IDE but i am facing a problem.
I set 1 as a master using the normal SPI library and the second one as slave using ESP32SPISlave.
Master SW is basically writing 0 or 1 to slave device and wait for a response
if the master send a 0 the slave will send back 2 in the next communication,
if the master send 1 the slave will send back 1 in the next communication.
the problem that sometimes even if the master send 1 i receive the number 2 instead of 1 so it seems that it doesn't override the previous value.
I am not sure exactly what's the problem. could you please support me?
I will paste both SW
You can find the picture of the issue in the link below
https://drive.google.com/file/d/1K08ntvOcR7fH9SyWb-RZu7XXCOKP2msH/view?usp=sharing
Master SW
#include <SPI.h>
// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus
#ifdef ALTERNATE_PINS
#define VSPI_MISO 26
#define VSPI_MOSI 27
#define VSPI_SCLK 25
#define VSPI_SS 32
#else
#define VSPI_MISO MISO
#define VSPI_MOSI MOSI
#define VSPI_SCLK SCK
#define VSPI_SS SS
#endif
static const int spiClk = 1000000; // 1 MHz
int data1;
//uninitalised pointers to SPI objects
SPIClass * vspi = NULL;
void setup() {
Serial.begin(115200);
delay(2000);
//initialise instance of the SPIClass attached to HSPI
vspi = new SPIClass(VSPI);
//clock miso mosi ss
#ifndef ALTERNATE_PINS
//initialise hspi with default pins
//SCLK = 14, MISO = 12, MOSI = 13, SS = 15
vspi->begin();
#else
//alternatively route through GPIO pins
vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS); //SCLK, MISO, MOSI, SS
#endif
//set up slave select pins as outputs as the Arduino API
//doesn't handle automatically pulling SS low
pinMode(VSPI_SS, OUTPUT); //HSPI SS
}
// the loop function runs over and over again until power down or reset
void loop() {
vspi_send_command();
delay(1000);
}
void vspi_send_command() {
byte data_on = 0b00000001; // data 1 to turn on LED of slave
byte data_off = 0b0000000; // data 0 to turn off LED of slave
vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(VSPI_SS, LOW);
data1 = vspi->transfer(data_on);
digitalWrite(VSPI_SS, HIGH);
vspi->endTransaction();
Serial.print("data sent is 1 and data received is ");
Serial.println(data1);
delay(1000);
vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(VSPI_SS, LOW);
data1 = vspi->transfer(data_off);
digitalWrite(VSPI_SS, HIGH);
vspi->endTransaction();
Serial.print("data sent is 0 and data received is ");
Serial.println(data1);
delay(1000);
}
Slave SW
#include <ESP32SPISlave.h>
ESP32SPISlave slave;
static constexpr uint32_t BUFFER_SIZE {32};
uint8_t spi_slave_tx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_buf[BUFFER_SIZE];
#define LED 2
void setup() {
Serial.begin(115200);
delay(2000);
pinMode(LED, OUTPUT);
// begin() after setting
// HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12 -> default
// VSPI = CS: 5, CLK: 18, MOSI: 23, MISO: 19
slave.setDataMode(SPI_MODE0);
//slave.begin();
slave.begin(VSPI); // you can use VSPI like this
// clear buffers
memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
}
void loop() {
// block until the transaction comes from master
slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);
// if transaction has completed from master,
// available() returns size of results of transaction,
// and buffer is automatically updated
char data;
while (slave.available()) {
// show received data
Serial.print("Command Received: ");
Serial.println(spi_slave_rx_buf[0]);
data = spi_slave_rx_buf[0];
slave.pop();
}
if(data == 1 )
{
Serial.println("Setting LED active HIGH ");
digitalWrite(LED, HIGH);
memset(spi_slave_tx_buf, 1, BUFFER_SIZE);
}
else if(data == 0 )
{
Serial.println("Setting LED active LOW ");
digitalWrite(LED, LOW);
memset(spi_slave_tx_buf, 2, BUFFER_SIZE);
}
Serial.println("");
}
Thank you again for your cooperation.
Upvotes: 0
Views: 1005
Reputation: 4034
SPI is a very specific interface and slave can only transmit if the master transmits.
If your slave starts to send a data based on what has been received from the master, then you only get the data from the slave on the 2nd transmission of your master transmission. That is, you need to send two bytes of data from the master, the first byte is the data you want the slave to receive, the second byte is a dummy in order to clock-in the received data.
Upvotes: 1