Hello,
I am new to building Arduino projects and wanted to learn a bit about SPI using an Arduino. I have been trying to establish a connection between two Arduino Nano ESP32 devices. The Master device seems to be working right, and sends an array of numbers every 2 seconds. However, the Slave device doesn't seem to be working properly.
I've been following this demo from an ESP32SPISlave library. The master and slave both are supposed to send the numbers 1-8 and verifies that they each correctly received the data. The master pulls the SS line every 2 seconds to initiate the transfer, however when I set it up on my devices the returned buffer's only have 0's in them.
As well, the slave device doesn't seem to be waiting for the SS line, as it prints unexpected difference found between master/slave data nonstop. I have been trying to figure out if I wired things wrong or simply don't have a good understanding on how SPI is meant to work on the Nano ESP32. Below is the code I've been using (which is from the example code on the aforementioned library), as well as my current wiring.
Any help is appreciated as I want to better understand how to work with SPI.
helper.h
#pragma once
#include <Arduino.h>
#include <cstdint>
#include <cstddef>
void dumpBuffers(const char *title, const uint8_t *buf, size_t start, size_t len) {
// show title and range
if (len == 1)
Serial.printf("%s [%d]: ", title, start);
else
Serial.printf("%s [%d-%d]: ", title, start, start + len - 1);
// show data in the range
for (size_t i = 0; i < len; i++) {
Serial.printf("%02X ", buf[start + i]);
}
Serial.printf("\n");
}
bool verifyAndDumpDifference(const char *a_title, const uint8_t *a_buf, size_t a_size, const char *b_title, const uint8_t *b_buf, size_t b_size) {
bool verified = true;
if (a_size != b_size) {
Serial.printf("received data size does not match: expected = %d / actual = %d\n", a_size, b_size);
return false;
}
for (size_t i = 0; i < a_size; i++) {
// if a_buf and b_buf is same, continue
if (a_buf[i] == b_buf[i]) {
continue;
}
verified = false;
// if a_buf[i] and b_buf[i] is not same, check the range that has difference
size_t j = 1;
while (a_buf[i + j] != b_buf[i + j]) {
j++;
}
// dump different data range
dumpBuffers(a_title, a_buf, i, j);
dumpBuffers(b_title, b_buf, i, j);
// restart from next same index (-1 considers i++ in for())
i += j - 1;
}
return verified;
}
void initializeBuffers(uint8_t *tx, uint8_t *rx, size_t size, size_t offset = 0) {
if (tx) {
for (size_t i = 0; i < size; i++) {
tx[i] = (i + offset) & 0xFF;
}
}
if (rx) {
memset(rx, 0, size);
}
}
master code:
#include <SPI.h>
#include "helper.h"
SPIClass master(HSPI);
static constexpr size_t BUFFER_SIZE = 8;
uint8_t tx_buf[BUFFER_SIZE]{ 1, 2, 3, 4, 5, 6, 7, 8 };
uint8_t rx_buf[BUFFER_SIZE]{ 0, 0, 0, 0, 0, 0, 0, 0 };
void setup() {
Serial.begin(9600);
delay(2000);
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
master.begin(SCK, MISO, MOSI, SS);
delay(2000);
Serial.println("start spi master");
}
void loop() {
// initialize tx/rx buffers
initializeBuffers(tx_buf, rx_buf, BUFFER_SIZE);
master.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(SS, LOW);
master.transferBytes(tx_buf, rx_buf, BUFFER_SIZE);
digitalWrite(SS, HIGH);
master.endTransaction();
// verify and dump difference with received data
if (verifyAndDumpDifference("master", tx_buf, BUFFER_SIZE, "slave", rx_buf, BUFFER_SIZE)) {
Serial.println("successfully received expected data from slave");
} else {
Serial.println("unexpected difference found between master/slave data");
}
delay(2000);
}
Slave Code:
#include <ESP32SPISlave.h>
#include "helper.h"
ESP32SPISlave slave;
static constexpr size_t BUFFER_SIZE = 8;
static constexpr size_t QUEUE_SIZE = 1;
uint8_t tx_buf[BUFFER_SIZE]{ 1, 2, 3, 4, 5, 6, 7, 8 };
uint8_t rx_buf[BUFFER_SIZE]{ 0, 0, 0, 0, 0, 0, 0, 0 };
void setup() {
Serial.begin(9600);
delay(2000);
slave.setDataMode(SPI_MODE0); // default: SPI_MODE0
slave.setQueueSize(QUEUE_SIZE); // default: 1
// begin() after setting
slave.begin(HSPI, SCK, MISO, MOSI, SS); // default: HSPI (please refer README for pin assignments)
Serial.println("start spi slave");
}
void loop() {
// initialize tx/rx buffers
initializeBuffers(tx_buf, rx_buf, BUFFER_SIZE);
// start and wait to complete one BIG transaction (same data will be received from slave)
const size_t received_bytes = slave.transfer(tx_buf, rx_buf, BUFFER_SIZE);
// verify and dump difference with received data
if (verifyAndDumpDifference("slave", tx_buf, BUFFER_SIZE, "master", rx_buf, received_bytes)) {
Serial.println("successfully received expected data from master");
} else {
Serial.println("unexpected difference found between master/slave data");
}
}
Wiring
