Skip to content

Networking and communications

  • Send a message between two projects

PROJECT IDEA

Using the SPI protocol with two boards: the ESP32 and the Arduino Nano, I want to send a message. On the ESP32, I’ve connected a HC-SR05 sensor. The sensor reads the distance and sends a message to the Arduino Nano, which displays the distance value. On the Nano, I’ve connected an I2C LCD screen and a LED. The message sent should be displayed on the LCD and, if the distance is less than 50 cm, the LED will flash as a warning.

Hardware configuration

ESP32

  • Connect the HC-SR05 sensor to the GPIO pins of the ESP32.
  • Connect the SPI pins of the ESP32 to the corresponding pins of the Arduino Nano :
  • MISO (Master In Slave Out)
  • MOSI (Master Out Slave In)
  • SCK (Serial Clock)
  • SS (Slave Select)

Arduino Nano

  • Connect an I2C LCD display to the Arduino Nano’s SDA and SCL pins.

  • Connect an LED to a digital pin on the Arduino Nano (e.g. pin 13).

Code for ESP32

#include <SPI.h>

const int trigPin = 26; // Définissez les broches du capteur HC-SR05
const int echoPin = 25;
const int ssPin = 5; // Choisissez une broche pour SS
float distance;

void setup() {
  Serial.begin(115200);
  SPI.begin();
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ssPin, OUTPUT);
  digitalWrite(ssPin, HIGH); // Désactive l'esclave au départ
}

void loop() {
  distance = getDistance();
  Serial.println(distance);
  sendDistanceSPI(distance);
  delay(1000); // Delay d'une seconde entre chaque mesure
}

float getDistance() {
  // Envoi d'un pulse ultrason
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Lire la durée du retour de l'écho
  long duration = pulseIn(echoPin, HIGH);

  // Calculer la distance en cm
  float distance = duration * 0.034 / 2;
  return distance;
}

void sendDistanceSPI(float distance) {
  byte *distanceBytes = (byte *) &distance;
  SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
  digitalWrite(ssPin, LOW); // Active l'esclave
  for (int i = 0; i < sizeof(float); i++) {
    SPI.transfer(distanceBytes[i]);
  }
  digitalWrite(ssPin, HIGH); // Désactive l'esclave
  SPI.endTransaction();
}

Code for Arduino Nano

#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

const int ledPin = 5;
float distance;
LiquidCrystal_I2C lcd(0x27, 16, 2);

volatile boolean spiReceived = false;

void setup() {
  Serial.begin(115200);
  SPI.begin();
  pinMode(SS, INPUT);
  pinMode(ledPin, OUTPUT);
  lcd.init();
  lcd.backlight();
  SPI.setDataMode(SPI_MODE0);
  SPI.attachInterrupt(); // Activer les interruptions SPI
}

ISR(SPI_STC_vect) {
  static byte dataBuffer[4];
  static int byteIndex = 0;

  dataBuffer[byteIndex] = SPDR;
  byteIndex++;

  if (byteIndex == 4) {
    memcpy(&distance, dataBuffer, sizeof(float));
    byteIndex = 0;
    spiReceived = true;
  }
}

void loop() {
  if (spiReceived) {
    spiReceived = false;

    // Affichage de la distance dans le moniteur série
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");

    // Affichage de la distance sur l'écran LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Distance: ");
    lcd.setCursor(0, 1);
    lcd.print(distance);
    lcd.print(" cm");

    // Clignotement de la LED si la distance est inférieure à 50 cm
    if (distance < 50) {
      blinkLED();
    }
  }
}

void blinkLED() {
  for (int i = 0; i < 5; i++) {
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  }
}

For wiring, use the travial of Koffi Sylvain

Code

code