2

I have two ESP32 cards. I want to set one of these cards as Master and the other as Slave and communicate via SPI. I have done this before on Arduino Uno, but I cannot do this on ESP32. Below are my Master and Slave codes that I have prepared simply. I can't get what I want in any way. Can anyone help?

Master Code:

#include <SPI.h>
#define CS_PIN 5 // Choose the appropriate pin for Chip Select (CS)
void setup() {
 Serial.begin(115200);
 SPI.begin();
}
void loop() {
 char dataToSend = 'A';
 
 digitalWrite(CS_PIN, LOW); // Start communication with the slave
 SPI.transfer(dataToSend); // Send data to the slave
 digitalWrite(CS_PIN, HIGH); // End communication with the slave
 
 delay(2000); // Delay for demonstration purposes
}

Slave Code:

#include <SPI.h>
#define CS_PIN 5 // Choose the appropriate pin for Chip Select (CS)
void setup() {
 Serial.begin(115200);
 SPI.begin();
}
void loop() {
 if (digitalRead(CS_PIN) == LOW) { // Check if CS (Chip Select) is LOW, meaning the device is selected
 char receivedData = SPI.transfer(0); // Read received data from the master
 
 // Display received data on the serial monitor
 Serial.println("Received Data: " + String(receivedData));
 
 delay(1000); // Optional delay for demonstration purposes
 }
}

New Code - New Problem:

I tried to adapt the codes at https://microcontrollerslab.com/esp32-spi-communication-tutorial-arduino/. From what I understand it uses the following pins for SPI: MISO-12; MOSI-13; SCLK-14; SS-15. I set my connections the same way, but I cannot get the output I expected from the Slave. It remains waiting at the slave.wait line.

Master Code:

#include <SPI.h>
// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus
 #define HSPI_MISO MISO
 #define HSPI_MOSI MOSI
 #define HSPI_SCLK SCK
 #define HSPI_SS SS
static const int spiClk = 1000000; // 1 MHz
//uninitalised pointers to SPI objects
SPIClass * hspi = NULL;
void setup() {
 //initialise instance of the SPIClass attached to HSPI
 hspi = new SPIClass(HSPI);
 //initialise hspi with default pins
 //SCLK = 14, MISO = 12, MOSI = 13, SS = 15
 hspi->begin();
 pinMode(HSPI_SS, OUTPUT); //HSPI SS
}
// the loop function runs over and over again until power down or reset
void loop() {
 hspi_send_command();
 delay(100);
}
void hspi_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
 
 hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
 digitalWrite(HSPI_SS, LOW);
 hspi->transfer(data_on);
 digitalWrite(HSPI_SS, HIGH);
 hspi->endTransaction();
 delay(1000);
 
 hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
 digitalWrite(HSPI_SS, LOW);
 hspi->transfer(data_off);
 digitalWrite(HSPI_SS, HIGH);
 hspi->endTransaction();
 delay(1000);
}
*/

Slave 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: 190
 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
 Serial.println("Initialize...");
 
 slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);
 Serial.println("*********************");
 // 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);
 }
 else if(data == 0 )
 {
 Serial.println("Setting LED active LOW ");
 digitalWrite(LED, LOW);
 }
}
Juraj
18.3k4 gold badges31 silver badges49 bronze badges
asked Nov 28, 2023 at 12:59
0

2 Answers 2

2

For ESP32, unless the exact board variant is specified, by default the macros for MISO, MOSI, SCK and SS are defined as follows and are used for VSPI(i.e. SPI0):

static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;

This can be seen in the source code and HSPI is automatically configured to use SCLK 14, MISO 12, MOSI 13 and SS 15 when SPI.begin() is called, see this part of the source code.

Since you defined HSPI_SS as #define HSPI_SS SS, when you do pinMode(HSPI_SS, OUTPUT);, you are actually setting pin 5 as output, not the pin 15 that you thought it was.

There are two ways to properly set up the HSPI port.

  1. What you can do is to define the macros as follows and call hspi->begin(); by passing your configuration:
#define HSPI_MISO 12
#define HSPI_MOSI 13
#define HSPI_SCLK 14
#define HSPI_SS 15
void setup() {
 hspi = new SPIClass(HSPI);
 hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, HSPI_SS);
 // rest of your setup code
}
  1. As you can see from the source code shown in the above link, if you don't explicitly pass the pins as parameters when calling SPI.begin(), the library will automatically assign the pins based on whether VSPI is used (SCLK 18, MISO 19, MOSI 23, SS 5), or HSPI is used (SCLK 14, MISO 12, MOSI 13 and SS 15). So all you need to define is your HSPI_SS pin:
#define HSPI_SS 15
void setup() {
 hspi = new SPIClass(HSPI);
 hspi->begin();
 // rest of your setup code
}
dda
1,5951 gold badge12 silver badges17 bronze badges
answered Nov 30, 2023 at 2:18
1
  • Thank you so much. I managed to send a string expression. Below you can see the Slave-Master codes that send messages from Master to Slave using the "Hello From Master" string. Commented Nov 30, 2023 at 9:36
1

You can see the Slave-Master codes that send messages from Master to Slave using the "Hello From Master" string.

Master Code:

#include <SPI.h>
#ifdef ALTERNATE_PINS
 #define VSPI_MISO 19
 #define VSPI_MOSI 23
 #define VSPI_SCLK 18
 #define VSPI_SS 5
#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
char input;
const int size_arr = 25;
char buf[size_arr];
String sendData = "Hello from Master";
//uninitalised pointers to SPI objects
SPIClass* vspi = NULL;
void setup() {
 Serial.begin(115200);
 
 vspi = new SPIClass(VSPI);
 
#ifndef ALTERNATE_PINS
 vspi->begin();
#else
 vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS);
#endif
 pinMode(VSPI_SS, OUTPUT); //HSPI SS
 vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
}
void loop() {
 input = Serial.read();
 
 if(input == 's'){
 sendData.toCharArray(buf, size_arr);
 spi_transmis(VSPI_SS, buf);
 }
 delay(50);
}
void send_spi(int selectPin, byte pram) {
 digitalWrite(selectPin, LOW);
 vspi->transfer(pram);
 digitalWrite(selectPin, HIGH); 
 vspi->endTransaction();
 delayMicroseconds(75);
}
void spi_transmis(int selectPin, char buf[]) {
 for (int i = 0; i < size_arr; i++) {
 send_spi(selectPin, buf[i]);
 }
 send_spi(selectPin, '\n');
}

Slave Code:

#include <ESP32SPISlave.h>
ESP32SPISlave slave;
static constexpr uint32_t BUFFER_SIZE { 1 };
uint8_t spi_slave_tx_buf[BUFFER_SIZE];
uint8_t spi_slave_rx_buf[BUFFER_SIZE];
const int size_arr = 151;
char buf[size_arr];
volatile int pos = 0;
volatile bool active;
volatile bool process;
String received;
void setup() {
 Serial.begin(115200);
 slave.setDataMode(SPI_MODE0);
 slave.begin(VSPI);
 memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
 memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
}
void loop() {
 recvHandle();
 spiHandler();
}
void spiHandler() {
 slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);
 
 while (slave.available()) {
 char c = spi_slave_rx_buf[0];
 if (c == '\n') {
 buf[pos] = '0円';
 process = true;
 } else {
 buf[pos++] = c;
 }
 slave.pop();
 }
}
void recvHandle() {
 if (process) {
 received = String(buf);
 process = false;
 pos = 0;
 Serial.println(received);
 delayMicroseconds(20);
 }
}
answered Nov 30, 2023 at 9:40
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.