Electronics > Microcontrollers

SPI communication problem with two ESP32

(1/3) > >>

fedimakni:
Hello,

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


--- Code: ---
#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);

}


--- End code ---

Slave SW


--- Code: ---
#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("");
}


--- End code ---

Thank you again for your cooperation.

ledtester:
In your slave code try replacing:


--- Code: ---    char data;

--- End code ---

with:


--- Code: ---    char data = 3;

--- End code ---

The point is that you are potentially using an uninitialized value. Suppose that slave.wait() returns but there aren't any transactions to process. Then the variable data will contain an uninitialized value which could possibly screw things up.

You could also add a final else clause to the if-else block that checks the value of data to see if this ever happens:


--- Code: ---    else { // data is not 0 or 1
        Serial.println("*** data is not 0 or 1 ***")
    }

--- End code ---

fedimakni:
Thank you very much for the response.
but i think the problem comes from the master because the data received back in the master is what contain the error
initializing "data" will just fix the first iteration but the problem happened during the execution of the SW as you can see in the picture (link attached in the main post)
I was really thinking that it's a timing issue but i couldn't figure it out  :-//

fedimakni:
I checked something right now,
I actually found that i receive the number 2 in the slave when i only send 0 or 1 something weird but i don't know how to fix it.
Do you have an idea?

DavidAlfa:
Or use static char data, so it holds the value.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version