SPI Data Transfer ESP32-H2 to ESP32-H2, Arduino IDE. Can't get Slave to receive data - Stack Overflow

admin2025-04-17  4

I'm an old guy (70) developing a complex instrument, and I have almost everything else working. The only thing left is SPI communication between two ESP32-H2 chips hardwired on the same board. This is my first post to any forum, so please inform me about how to use it effectively and not waste your time. I've tried three days of AI bots, Espressif documentation, reading forum posts, etc., without luck.

I can get the master to work, as verified with an o-scope, but I never get received data in the slave. It's always zero.

Here is an example of the many things I've been trying:

#include <SPI.h>

const int MOSI_PIN = 25;
const int MISO_PIN = 26;
const int SCLK_PIN = 27;
const int CS_PIN = 22;

volatile byte receivedData = 0;
volatile bool dataReceived = false;

// Interrupt Service Routine (ISR)
void IRAM_ATTR handleSPInterrupt() {
  receivedData = SPI.transfer(0); // Receive data while sending dummy byte
  dataReceived = true;
}

void setup() {
  Serial.begin(115200);

  // Initialize SPI with custom pins
  SPI.begin(SCLK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
  SPI.setClockDivider(SPI_CLOCK_DIV16); // Adjust clock divider if needed

  // Configure CS pin as input with pullup
  pinMode(CS_PIN, INPUT_PULLUP);

  // Attach interrupt handler
  attachInterrupt(digitalPinToInterrupt(CS_PIN), handleSPInterrupt, FALLING); 

  Serial.println("SPI Slave Initialized.");
}

void loop() {
  if (dataReceived) {
    Serial.print("Received: ");
    Serial.println(receivedData, HEX);
    dataReceived = false; 
  }
}

This produces a clear bus conflict. SCLK and MOSI are half amplitude with overlapping data interspersed. If I use pinMode() to set MOSI and SCLK as inputs the signals from the master are normal, but the received data is still always zero. I've tried many other things not documented here. Thanks for any help you can provide!

I'm an old guy (70) developing a complex instrument, and I have almost everything else working. The only thing left is SPI communication between two ESP32-H2 chips hardwired on the same board. This is my first post to any forum, so please inform me about how to use it effectively and not waste your time. I've tried three days of AI bots, Espressif documentation, reading forum posts, etc., without luck.

I can get the master to work, as verified with an o-scope, but I never get received data in the slave. It's always zero.

Here is an example of the many things I've been trying:

#include <SPI.h>

const int MOSI_PIN = 25;
const int MISO_PIN = 26;
const int SCLK_PIN = 27;
const int CS_PIN = 22;

volatile byte receivedData = 0;
volatile bool dataReceived = false;

// Interrupt Service Routine (ISR)
void IRAM_ATTR handleSPInterrupt() {
  receivedData = SPI.transfer(0); // Receive data while sending dummy byte
  dataReceived = true;
}

void setup() {
  Serial.begin(115200);

  // Initialize SPI with custom pins
  SPI.begin(SCLK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);
  SPI.setClockDivider(SPI_CLOCK_DIV16); // Adjust clock divider if needed

  // Configure CS pin as input with pullup
  pinMode(CS_PIN, INPUT_PULLUP);

  // Attach interrupt handler
  attachInterrupt(digitalPinToInterrupt(CS_PIN), handleSPInterrupt, FALLING); 

  Serial.println("SPI Slave Initialized.");
}

void loop() {
  if (dataReceived) {
    Serial.print("Received: ");
    Serial.println(receivedData, HEX);
    dataReceived = false; 
  }
}

This produces a clear bus conflict. SCLK and MOSI are half amplitude with overlapping data interspersed. If I use pinMode() to set MOSI and SCLK as inputs the signals from the master are normal, but the received data is still always zero. I've tried many other things not documented here. Thanks for any help you can provide!

Share Improve this question asked Jan 30 at 17:47 OrophiliaOrophilia 1 3
  • First off, welcome and thank you for the "first post" context -- that's pretty cool, and it helps us a lot. From "SCLK and MOSI are half amplitude" I'm nearly positive that both devices are configured as SPI "master" or "controller" devices; the snippet you've posted must configure that device as a "slave" or "peripheral." Now some questions for you: 1. Can you link to the Espressif docs for SPI.h you are using? Will help me point you to the right function. 2. Can you post a screenshot of the o-scope trace showing the scope conflict? – GandhiGandhi Commented Jan 30 at 19:03
  • This tutorial provides a SPI master/slave communication example between two ESP32s and the required SPI slave library. – hcheung Commented Jan 31 at 6:39
  • I've come to the conclusion that there is no SPI slave support for the ESP32-H2 in the Arduino IDE. I don't want to learn ESP-IDF. I think I'm stuck so I've decided to try the RP2040 so that I can stay in the Arduino IDE. I've wanted to try it anyway. Thanks so much for the response! Cheers, Dave – Orophilia Commented Feb 1 at 1:31
Add a comment  | 

1 Answer 1

Reset to default 0

You know you need one master and one (or more) slaves, right?

From the Arduino docs, SPI.begin() can only ever set up an SPI master. Setting up an SPI master and then turning the pins to input will prevent the hardware bus conflict, but won't make it work. Your master will still think it is driving the clock, even though though the pins aren't outputting anything. It will read the data line synchronously with the clock it thinks it is outputting. You want it to read the data line synchronously with the clock it receives.

Making an SPI slave is more complicated. Here is one tutorial and another code sample.

转载请注明原文地址:http://anycun.com/QandA/1744901044a89220.html