Sending and Receiving Commands Between Arduino/ESP32 and Other Microcontrollers: A Comprehensive Guide

Introduction

Microcontrollers like Arduino and ESP32 have become staples in the DIY electronics world due to their versatility and ease of use. Whether you are building a home automation system or a robotics project, the ability to send and receive commands between these microcontrollers can significantly enhance your project’s functionality. In this blog post, we will explore various methods to achieve communication between an Arduino/ESP32 and other microcontrollers, showcasing code examples for clearer understanding.

Understanding Communication Protocols

Before diving into code, it’s important to understand the different types of communication protocols commonly used to connect microcontrollers. Here are a few:

  • UART (Universal Asynchronous Receiver-Transmitter): A simple serial communication protocol that uses two wires (TX and RX) for data transmission.
  • I2C (Inter-Integrated Circuit): A synchronous, multi-master protocol commonly used for connecting low-speed devices.
  • SPI (Serial Peripheral Interface): An interface that allows multiple devices to communicate with a master device in a synchronous manner.

Using UART to Send and Receive Commands

The UART protocol is a great starting point due to its simplicity. Below is an example of how to establish communication between an Arduino and an ESP32 using UART.

Arduino Code
void setup() {
    Serial.begin(115200); // Start serial communication at 115200 baud rate
}

void loop() {
    Serial.println("Hello from Arduino!");
    delay(1000); // Send message every second
}
ESP32 Code
void setup() {
    Serial.begin(115200); // Start serial communication at 115200 baud rate
}

void loop() {
    if (Serial.available()) { // Check if data is available to read
        String message = Serial.readStringUntil('\n');
        Serial.print("Received: ");
        Serial.println(message);
    }
}

Using I2C for Multi-Device Communication

If you need to communicate with multiple microcontrollers, I2C is the better choice as it allows multiple devices to share the same bus.

Arduino Code as I2C Master
#include 

void setup() {
    Wire.begin(); // Join the I2C bus as a master
}

void loop() {
    Wire.beginTransmission(8); // Address of the slave device
    Wire.write("Hello from Arduino!");
    Wire.endTransmission();
    delay(1000);
}
ESP32 Code as I2C Slave
#include 

void setup() {
    Wire.begin(8); // Join the I2C bus as a slave with address 8
    Wire.onReceive(receiveEvent);
}

void loop() {
    // Nothing needed here for this example
}

void receiveEvent(int howMany) {
    String message;
    while (Wire.available()) {
        char c = Wire.read(); // Receive byte as character
        message += c;
    }
    Serial.print("Received: ");
    Serial.println(message);
}

Using SPI for Speed

If your project requires higher speeds, SPI is the way to go. Below is a simple example of using SPI to communicate between an Arduino and ESP32.

Arduino Code as SPI Master
#include 

void setup() {
    SPI.begin(); // Initialize SPI bus as master
    pinMode(10, OUTPUT); // Select your slave device (chip select pin)
}

void loop() {
    digitalWrite(10, LOW); // Select slave device
    SPI.transfer("Hello from Arduino!");
    digitalWrite(10, HIGH); // Deselect slave device
    delay(1000);
}
ESP32 Code as SPI Slave
#include 

volatile bool received;
char incomingData[50];

void setup() {
    SPI.begin(); // Initialize SPI bus as slave
    pinMode(MISO, OUTPUT); // Set MISO as an output to send data
    SPI.onReceive(receiveData);
}

void loop() {
    // Periodically check if data was received
    if(received) {
        received = false;
        Serial.println(incomingData);
    }
}

void receiveData(int bytes) {
    for(int i = 0; i < bytes; i++) {
        incomingData[i] = SPI.transfer(0); // Receive data
    }
    received = true;
}

Conclusion

In this blog post, we've discussed three popular communication protocols—UART, I2C, and SPI—and provided examples demonstrating how to implement them between an Arduino and an ESP32. Each communication method has its advantages and is suitable for different project requirements. Depending on your needs, choose the appropriate protocol and take your microcontroller projects to new heights!