Взаимная связь ESP32 SPI
У меня есть две карты ESP32. Я хочу установить одну из этих карт как главную, а другую как подчиненную и общаться через SPI. Я делал это раньше на Arduino Uno, но не могу сделать это на ESP32. Ниже приведены мои основные и подчиненные коды, которые я просто подготовил. Я никак не могу получить то, что хочу. Кто-нибудь может помочь?
Главный код:
#include <SPI.h>
#define CS_PIN 5 // Выберите соответствующий вывод для выбора чипа (CS)
void setup() {
Serial.begin(115200);
SPI.begin();
}
void loop() {
char dataToSend = 'A';
digitalWrite(CS_PIN, LOW); // Начинаем общение с слейвом
SPI.transfer(dataToSend); // Отправляем данные подчиненному устройству
digitalWrite(CS_PIN, HIGH); // Завершаем связь с ведомым
delay(2000); // Задержка для демонстрационных целей
}
Подчиненный код:
#include <SPI.h>
#define CS_PIN 5 // Выберите соответствующий вывод для выбора чипа (CS)
void setup() {
Serial.begin(115200);
SPI.begin();
}
void loop() {
if (digitalRead(CS_PIN) == LOW) { // Проверяем, что CS (выбор чипа) имеет низкий уровень, что означает, что устройство выбрано
char receivedData = SPI.transfer(0); // Читаем полученные данные от мастера
// Отображение полученных данных на последовательном мониторе
Serial.println("Received Data: " + String(receivedData));
delay(1000); // Необязательная задержка для демонстрационных целей
}
}
Новый код – новая проблема:
Я пытался адаптировать коды на странице https://microcontrollerslab.com/esp32-spi-communication-tutorial. -arduino/. Насколько я понимаю, для SPI используются следующие контакты: MISO-12; МОСИ-13; СКЛК-14; СС-15. Я настроил свои соединения таким же образом, но не могу получить ожидаемый результат от ведомого устройства. Он остается в ожидании на линии подчиненного устройства.
Главный код:
#include <SPI.h>
// Определите ALTERNATE_PINS для использования нестандартных контактов GPIO для шины SPI
#define HSPI_MISO MISO
#define HSPI_MOSI MOSI
#define HSPI_SCLK SCK
#define HSPI_SS SS
static const int spiClk = 1000000; // 1 МГц
//неинициализированные указатели на объекты SPI
SPIClass * hspi = NULL;
void setup() {
//инициализируем экземпляр SPIClass, прикрепленный к HSPI
hspi = new SPIClass(HSPI);
//инициализируем hspi с помощью контактов по умолчанию
//SCLK = 14, MISO = 12, MOSI = 13, SS = 15
hspi->begin();
pinMode(HSPI_SS, OUTPUT); //HSPI СС
}
// функция цикла выполняется снова и снова, пока не отключится питание или не будет выполнен сброс
void loop() {
hspi_send_command();
delay(100);
}
void hspi_send_command() {
byte data_on = 0b00000001; // данные 1 для включения светодиода ведомого устройства
byte data_off = 0b0000000; // данные 0, чтобы выключить светодиод подчиненного устройства
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);
}
*/
Подчиненный код:
#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);
// начало() после установки
// HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12 -> по умолчанию
// VSPI = CS: 5, CLK: 18, MOSI: 23, MISO: 190
slave.setDataMode(SPI_MODE0);
slave.begin();
// раб.begin(VSPI); // вы можете использовать VSPI вот так
// очищаем буферы
memset(spi_slave_tx_buf, 0, BUFFER_SIZE);
memset(spi_slave_rx_buf, 0, BUFFER_SIZE);
}
void loop() {
// блокируем до тех пор, пока транзакция не придет от мастера
Serial.println("Initialize...");
slave.wait(spi_slave_rx_buf, spi_slave_tx_buf, BUFFER_SIZE);
Serial.println("*********************");
// если транзакция завершилась с мастера,
// доступная() возвращает размер результатов транзакции,
// и буфер автоматически обновляется
char data;
while (slave.available()) {
// показываем полученные данные
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);
}
}
@Enes Orhan, 👍2
Обсуждение2 ответа
Для ESP32, если не указан точный вариант платы, по умолчанию используются макросы для MISO
, MOSI
, SCK
и SS
определяются следующим образом и используются для VSPI (т. е. 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;
Это можно увидеть в исходном коде и HSPI автоматически настраивается на использование SCLK 14, MISO 12, MOSI 13 и SS 15 при вызове SPI.begin()
, см. эту часть исходный код.
Поскольку вы определили HSPI_SS
как #define HSPI_SS SS
, когда вы выполняете pinMode(HSPI_SS, OUTPUT);
, вы фактически устанавливаете PIN-код 5 в качестве выхода, а не контакт 15, как вы думали.
Существует два способа правильной настройки порта HSPI.
- Что вы можете сделать, так это определить макросы следующим образом и вызвать
hspi->begin();
, передав вашу конфигурацию:
#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);
// остальная часть вашего кода установки
}
- Как видно из исходного кода, показанного в приведенной выше ссылке, если вы явно не передаете контакты в качестве параметров при вызове
SPI.begin()
, библиотека автоматически назначит контакты в зависимости от того, используется ли VSPI (SCLK 18, MISO 19, MOSI 23, SS 5) или HSPI (SCLK 14, MISO 12, MOSI 13 и SS 15). Итак, все, что вам нужно определить, это ваш PIN-кодHSPI_SS
:
#define HSPI_SS 15
void setup() {
hspi = new SPIClass(HSPI);
hspi->begin();
// остальная часть вашего кода установки
}
Большое спасибо. Мне удалось отправить строковое выражение. Ниже вы можете увидеть коды «Slave-Master», которые отправляют сообщения от «Master» к «Slave», используя строку «Hello From Master»., @Enes Orhan
Вы можете увидеть коды подчиненного-главного устройства, которые отправляют сообщения от главного устройства к подчиненному, используя команду «Привет от главного». строка.
Главный код:
#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 МГц
char input;
const int size_arr = 25;
char buf[size_arr];
String sendData = "Hello from Master";
//неинициализированные указатели на объекты SPI
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 СС
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');
}
Подчиненный код:
#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);
}
}
- Импульсы SCLK не видны при использовании SPI на ESP32
- FreeRTOS не решает мою проблему с параллельным выполнением задач
- Контакты RX и TX на esp32
- Связь Arduino master/slave с использованием RS485
- ESP32 в Arduino-IDE с FS.h и SPIFFS
- Программаторы для этой платы отсутствуют - Программирование ESP32 Cam с помощью Ardunio IDE
- Установка значения float до двух знаков после запятой
- ESP32-CAM первый: 0x8 TG1WDT_SYS_RESET загрузочный цикл
Здесь https://github.com/espressif/esp-idf/tree/master/examples/peripherals/spi_slave — это именно то, что вам нужно, примеры кода, предоставленные самим espressif., @M A K
Я раньше этого не пробовал, но мне нужен пример с расширением .ino, а не .c., @Enes Orhan
https://microcontrollerslab.com/esp32-spi-communication-tutorial-arduino/ вот полный пример!, @M A K
Это выглядит как хороший пример, но у меня он не работает. Я не понимаю, какие spi-соединения вы используете. Я попробовал оба подключения для ESP32, но результатов не получил., @Enes Orhan
Вам необходимо повысить уровень своих навыков программирования. Я дал вам точный ответ! с полным объяснением., @M A K
Я отредактировал свой вопрос, внес улучшения, как вы показали, но не получил никаких результатов. Вы можете помочь мне?, @Enes Orhan
Где в файлах кода определены номера контактов SPI? Соответствуют ли определения контактам gpio? Правильны ли физические соединения между микроконтроллерами?, @Erik