fedi makni
fedi makni

Reputation: 1

Slave ESP32 send back wrong data to master esp32

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

Answers (1)

hcheung
hcheung

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

Related Questions