Mini proiect (53) - Trimiterea semnalului de la un senzor hall conectat la ESP32 către RaspberryPi 4 pe SPI
Trimiterea semnalului de la un senzor hall conectat la ESP32 către RaspberryPi 4 pe SPI
În acest mic proiect urmăresc transmiterea semnalului de la un senzor Hall către un Raspberry Pi 4, utilizând o conexiune SPI cu un microcontroler ESP32. Descoperiți tehnologia din spatele senzorului Hall și modul în care acesta poate detecta câmpurile magnetice, apoi învățați cum să implementați o conexiune Serial Peripheral Interface (SPI) între ESP32 și Raspberry Pi 4 pentru a transfera eficient datele măsurate. Acest ghid practic vă oferă informații esențiale și pași detaliați pentru a realiza o integrare robustă și precisă între dispozitivele dumneavoastră, deschizând astfel poarta către aplicații diverse, de la monitorizarea mediului înconjurător la proiecte IoT inovatoare.
Comunicația SPI - Serial Peripheral Interface
Comunicarea prin SPI (Serial Peripheral Interface) între un ESP32 și un Raspberry Pi 4 implică utilizarea a trei linii principale: MISO (Master In Slave Out), MOSI (Master Out Slave In), și SCK (Serial Clock). În plus, este posibil să fie nevoie de o linie suplimentară numită SS (Slave Select) sau CS (Chip Select), care indică la dispozitivul slave că trebuie să asculte datele transmise de master.
Despre comunicația SPI am mai discutat și în următoarele articole:
- https://blog.automatic-house.ro/2023/09/16/mini-proiect-51-comunicatia-pe-spi-dintre-arduino-uno-si-groundstudio-jade-nano/
- https://blog.automatic-house.ro/2023/09/26/mini-proiect-52-comunicatia-spi-intre-doua-placi-esp32-trimiterea-valorii-de-la-potentiometru/
Conectarea Hardware între RaspberryPi4 și ESP32
Iată pașii generali pentru a realiza comunicarea SPI între un ESP32 și un Raspberry Pi 4:
- Asigurați-vă că ambele dispozitive au SPI activat. Pe Raspberry Pi, acest lucru se poate face din
raspi-config
.
- Conectați MISO la MISO, MOSI la MOSI, SCK la SCK, și, dacă este necesar, SS/CS la linia corespunzătoare pe ambele dispozitive.
- Asigurați-vă că ambele dispozitive au aceeași referință de tensiune (de exemplu în acest caz avem 3.3V pentru fiecare dispozitiv, pentru că ambele dispozitive operează la această tensiune).
- Placa ESP32 am conectat-o pe unul din USB-urile de la RaspberryPi4 care asigura aceeasi tensiune de referinta si același GND
Senzorul Hall
Componente
- Placa Raspberry Pi 4 Model B - 2GB
- Carcasa Neximus® pentru Raspberry Pi 4 model B din aluminiu, racire pasiva, RPI 4B
- ESP32 Wireless WiFi Bluetooth Dual Core CP2104 - 38 pini
- ESP32 WiFi Bluetooth Development Board, Micro USB, Dual Core, 30 pini
- ESP32 ESP32 Development Board Wireless WiFi Bluetooth Dual Core CP2104 Filters Power Module 2.4GHz RF For Arduino Nodemcu
- ESP32 Development Board Dual Core WiFi+Bluetooth Module Low Power Consumption WiFi NodeMCU Processor ESP-WROOM-32 CH9102 38 Pin
- Senzor magnetic Linear Hall
- KY-024 Linear Magnetic Hall Switches Speed Counting Sensor Module
- Kit Start Componente Electronice
Configurarea și compilarea pentru RaspberryPi
Pentru instalarea librăriei ncurse, care se utilizează în aplicație se utilizează următoarea comandă:Fisierul make care ne ajută să compilăm mai ușor conține următoarele configurări: După lansarea compilării se vor genera fișierele obiect "*.o", iar apoi se vor link edita și va rezulta un executabil spi_test.
Pentru rularea aplicației se execută comanda:
Configurarea și compilarea pentru ESP32
Cod de test pentru RaspberryPi4
/* | |
Florin Simedru | |
Complete project details at https://blog.automatic-house.ro | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files. | |
The above copyright notice and this permission notice shall be included in all | |
copies or substantial portions of the Software. | |
*/ | |
#include <wiringPiSPI.h> | |
#include <wiringPi.h> | |
#include <iostream> | |
#include <ncurses.h> | |
#include <cstdlib> | |
// Funcție pentru tratarea semnalului de întrerupere | |
void handleInterrupt(int signal) { | |
endwin(); // Termină modul curses înainte de închiderea programului | |
std::cout << "Program întrerupt de la semnalul " << signal << ". Închidere..." << std::endl; | |
exit(0); | |
} | |
int main() { | |
// Deschide conexiunea SPI | |
int channel = 0; // Poate fi 0 sau 1, în funcție de canalul SPI folosit | |
int speed = 1000000; // Viteza de transfer în Hz | |
int spi = wiringPiSPISetup(channel, speed); | |
if (spi == -1) { | |
std::cerr << "Eroare la deschiderea conexiunii SPI. Verificați conexiunile hardware." << std::endl; | |
return 1; | |
} | |
// Buffer pentru date | |
unsigned char data[2]; | |
// Inițializare mod curses | |
initscr(); | |
timeout(0); // Timpul maxim de așteptare pentru citirea unei taste | |
// Configurare pentru tratarea semnalelor de întrerupere | |
//signal(SIGINT, handleInterrupt); | |
while (true) { | |
// Citeste datele de pe SPI | |
wiringPiSPIDataRW(channel, data, 2); | |
// Procesează datele aici | |
// data[0] conține primul byte, data[1] conține al doilea byte | |
// Modificați această parte în funcție de formatul datelor primite | |
// Exemplu de afișare a datelor citite | |
if((data[0] != 0) && (data[0]!=0)) | |
{ | |
//std::cout << "Date citite: " << static_cast<int>(data[0]) << " " << static_cast<int>(data[1]) << std::endl; | |
// Exemplu de afișare a datelor citite | |
printw("Date citite: %d %d\n", static_cast<int>(data[0]), static_cast<int>(data[1])); | |
refresh(); // Actualizează ecranul | |
} | |
// Citește o tastă de la tastatură | |
int ch = getch(); | |
//std::cout << "Tasta citita: " << static_cast<int>(ch) << " " << std::endl; | |
// Verifică dacă tasta 'q' a fost apăsată | |
if (ch == 'q') { | |
//std::cout << "Tasta citita: " << static_cast<int>(ch) << "Întrerupere program. " << std::endl; | |
printw("Tasta 'q' apăsată. Întrerupere program.\n"); | |
refresh(); | |
break; | |
} | |
delay(100); | |
} | |
// Termină modul curses înainte de închiderea programului | |
endwin(); | |
return 0; | |
} |
Codul de test pentru ESP32
/*; PlatformIO Project Configuration File | |
; | |
; Build options: build flags, source filter | |
; Upload options: custom upload port, speed and extra flags | |
; Library options: dependencies, extra library storages | |
; Advanced options: extra scripting | |
; | |
; Please visit documentation for the other options and examples | |
; https://docs.platformio.org/page/projectconf.html | |
[env:esp32doit-devkit-v1] | |
platform = espressif32 | |
board = esp32doit-devkit-v1 | |
framework = arduino | |
upload_port = COM9 | |
monitor_port = COM9 | |
monitor_speed = 115200 | |
lib_deps = hideakitai/ESP32DMASPI@^0.3.0 | |
*/ | |
#include <Arduino.h> | |
#include <ESP32DMASPISlave.h> | |
ESP32DMASPI::Slave slave; | |
// HallSensor Analog value is connected to GPIO 35 (Analog ADC1_CH7) | |
const int hallSensorPin = 35; | |
const int hallSensorDPin = 13; | |
int i = 0; | |
static const uint32_t BUFFER_SIZE = 8; | |
uint8_t *spi_slave_tx_buf; | |
uint8_t *spi_slave_rx_buf; | |
void set_buffer() | |
{ | |
for (uint32_t i = 0; i < BUFFER_SIZE; i++) | |
{ | |
spi_slave_tx_buf[i] = i+ 0x31; | |
} | |
//memset(spi_slave_rx_buf, 0, BUFFER_SIZE); | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
// to use DMA buffer, use these methods to allocate buffer | |
spi_slave_tx_buf = slave.allocDMABuffer(BUFFER_SIZE); | |
spi_slave_rx_buf = slave.allocDMABuffer(BUFFER_SIZE); | |
set_buffer(); | |
delay(5000); | |
// slave device configuration | |
slave.setDataMode(SPI_MODE0); | |
slave.setMaxTransferSize(BUFFER_SIZE); | |
// begin() after setting | |
slave.begin(VSPI); // HSPI = CS: 15, CLK: 14, MOSI: 13, MISO: 12 -> default | |
// VSPI (CS: 5, CLK: 18, MOSI: 23, MISO: 19) | |
pinMode(hallSensorDPin, INPUT); | |
Serial.println("Boot finalized!"); | |
} | |
void loop() | |
{ | |
i=i+4; | |
uint8_t hallSensorDValue = digitalRead(hallSensorDPin); | |
uint16_t HallSensorValue = analogRead(hallSensorPin); | |
Serial.print("Analog Data: "); | |
Serial.println(HallSensorValue); | |
uint8_t val_hall = map(HallSensorValue, 0,4095, 0, 255); | |
if(i==7) | |
i = 0; | |
spi_slave_tx_buf[0] = val_hall; | |
spi_slave_tx_buf[1] = 0xff; | |
// if there is no transaction in queue, add transaction | |
if (slave.remained() == 0) | |
{ | |
slave.queue(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 | |
while (slave.available()) | |
{ | |
//Serial.printf("Slave received: %s\n\r", spi_slave_rx_buf); | |
//Serial.printf("Slave Transmitted: %s\n\r", spi_slave_tx_buf); | |
slave.pop(); | |
} | |
delay(50); | |
} |
Documentație proiect
- https://medium.com/codex/how-to-install-a-fan-onto-a-raspberry-pi-and-make-it-run-dynamically-4ff0e59985fc
- https://randomnerdtutorials.com/raspberry-pi-pinout-gpios/
- https://www.theengineeringprojects.com/2021/03/what-is-raspberry-pi-4-pinout-specs-projects-datasheet.html
- https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
Afiliere eMag
Linkurile de la secțiunea "Componente" conțin adresa mea de afiliere la eMag.ro, iar dacă cumperi folosind aceste linkuri vei susține blogul meu. Mulțumesc!eMag Genius:
Hai și tu în Genius! Abonează-te la Genius 12 luni și primești beneficii premium și 20 lei card cadou eMAG. Profită acum! eMag Genius
Mulțumesc pentru atenție!
Pentru întrebări și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro. O zi plăcută tuturor !