
Week 11: Networking & Communications
Assignments
Individual Assignment
Design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s)
Group Assignment
Send a message between two projects
Reflections
I have separated the following week into theory and practice below it.
Using my laptop and the Barduino I was able to use serial communication to control an RGB. Then I use UART protocol on laptop to barduino for asynchronous communication to control the light on the barduino by typing colours into the serial monitor from the laptop. Next, I added a step. I connect two boards through Serial UART. I upload a master code to one and a slave code to the other using serial and serial1 for each. Board A instructs Board B what colour RGB to output. Just worth commenting here that one must always remember to select the right board and COM port, USB enabled and it is worthwhile pressing the boot button while doing the upload. Finally at the end I was able to get 2 ESP32 boards to connect via LAN.
Unfortunately I couldn't complete the coup de grace and get my SAMD11c to communicate with an ESP32 but it failed. I was really enjoying trying out new things with the ESP32 so I'm quite peeved that my own chip is not up and running.
Theory
Defining Terms
A network is a group of computers connected among themselves through communication lines. A protocol is the set of rules that specify message formats and procedures that allow machines and programs exchange information.
Implementation
ESP32 Communication Example
Here's a practical example of implementing communication between two ESP32 boards using UART:
// ESP32 Sender Code
void setup() {
Serial.begin(115200); // Start Serial Monitor
Serial2.begin(115200); // Start UART2
}
void loop() {
if (Serial.available()) {
String message = Serial.readStringUntil('\n');
Serial2.println(message); // Send via UART
Serial.println("Sent: " + message);
}
}
// ESP32 Receiver Code
void setup() {
Serial.begin(115200); // Start Serial Monitor
Serial2.begin(115200); // Start UART2
}
void loop() {
if (Serial2.available()) {
String message = Serial2.readStringUntil('\n');
Serial.println("Received: " + message);
}
}
Hardware Setup
For UART communication between two ESP32s:
- Connect TX2 (GPIO17) of first ESP32 to RX2 (GPIO16) of second ESP32
- Connect RX2 (GPIO16) of first ESP32 to TX2 (GPIO17) of second ESP32
- Connect GND of both ESP32s together

Testing Communication
To test the communication:
- Upload the sender code to the first ESP32
- Upload the receiver code to the second ESP32
- Open Serial Monitor for both boards
- Type a message in the sender's Serial Monitor
- The message should appear in the receiver's Serial Monitor
Common Issues and Solutions
- No communication: Check physical connections and ensure GND is connected
- Garbled messages: Verify both boards are using the same baud rate
- One-way communication: Verify TX/RX connections are correct and not reversed
- Random characters: Check if voltage levels match between boards
Wired Communication
Various wired protocols for MCUs to communicate.
Characteristics
Parellel interfaces transfer multiple bits simultaneously. They usually need buses of data transmitting 8,16, or more wires. This means that waves of data can be sent at high speed but with a lot of wires.

Serial interfaces stream data with a reference signal, one bit at a time. These can operate on 1-4 wires.

Synchronous vs. Asynchronous Communication
"Asynchronous" means that data is transferred without support from an external clock signal. This minimises the required wires and I/O pins. To reliably transfer and receive data the communication is framed by a start bit and one or more stop bits. Also, there should be a baud rate agreement and the receiver samples bits at precise intervals. Furthermore, there is a form of error detection and buffering or flow control with protocols such as XON/XOFF (software flow control) or RTS/CTS (hardware flow control).

Image source: Sparkfun, Fablab BCN Documentation
"Synchronous" data interface always pairs its data line(s) with a clock signal, and all devices on a synchronous bus share a common clock. This makes for a more straightforward, often faster transfer, but it also requires at least one extra wire between communicating devices.

Image source: Sparkfun, Fablab BCN Documentation
Asynchronous Communication
Asynchronous communication allows data transfer without strict timing constraints, typically at lower speeds but with fewer connections — usually just one wire for transmission and one for reception, plus a shared ground. The most common form is Serial communication, also known as RX/TX or UART, all referring to the same concept.
RX/TX (Serial Communication)
Serial (RX/TX) uses two lines — one for receiving (RX) and one for transmitting (TX). It's supported by the Arduino Serial library and handled by the UART peripheral. Since it's asynchronous, both devices must agree on parameters like baud rate (speed), data length, and optional parity.

A typical data frame includes:
- 1 START bit
- 8 data bits
- 1 STOP bit
Optionally, there can be a second STOP bit or a PARITY bit. This forms a basic 10-bit frame.

UART
UART stands for Universal Asynchronous Receiver/Transmitter and is the piece of hardware in charge of managing the data. Microcontrollers might have one, many or none UARTs.
Chips without UART still can implementing by bit-banging. Bit-banging is a technique where software manually controls the timing and logic level of the I/O pins to simulate a communication protocol like UART, SPI, or I²C.
Instead of relying on UART hardware, your code:
- Manually sets a pin HIGH or LOW
- Waits precise time intervals (based on baud rate)
- Repeats for each bit in a byte
This allows you to "fake" a UART signal.
Synchronous communication
Synchronous communication is used when timing and speed are critical, and extra wiring is acceptable. It relies on a clock line to regulate data transfer rates and is the standard method for most inter-chip communication.
I2C (Inter-Integrated Circuit) is a protocol designed for short-distance communication between chips on the same device. One or more master chips communicate with multiple slave chips over just two wires—regardless of how many devices are connected. It supports multiple masters and slaves, uses two wires (clock and data and only masters can drive the data line high, preventing slaves from blocking communication.
SPI (Serial Peripheral Interface) is a fast, synchronous serial communication protocol used over short distances, primarily in embedded systems.
It follows a master-slave architecture, with one master (usually the microcontroller) generating the clock (SCK). Data is sent from the master via MOSI (Master Out, Slave In), and responses come back on MISO (Master In, Slave Out).
Slave devices are selected individually using SS (Slave Select) lines — only the selected slave activates its MISO line and responds; others ignore the clock signal.
SPI is commonly used for flashing microcontroller firmware due to its high speed. For example, the ATtiny microcontroller uses SPI on pins PA6 (MOSI), PA5 (MISO), and PA4 (SCK) for programming, as outlined in its datasheet.
While multiple slaves can be connected, only one communicates at a time by asserting its SS line (set LOW).
Practical
Until 05/02/25 I had been procrastinating as my chip was not made and there were various other course works to keep me busy.
I decided to start making code works and doing simple challenges using the Barduino which I then intend to execute with my development board.
I created a block of code for serial communication to control the RGB on the Barduino with the help of chatgpt.
#include <Adafruit_NeoPixel.h>
#define LED_PIN 38
#define NUM_LEDS 1
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
Serial1.begin(9600);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
Serial1.print(input);
}
delay(50);
}

Using UART laptop to barduino – asynchronous communication
When I type red, green, blue the RGB LED on pin 38 changes colour and when I give a non-programmed command it switches off
The next goal for me is to use one board to instruct another. I believe this is called Master and Slave. MOSI/MISO. Sometimes a more recent nomenclature can be heard called Controller and Peripheral (POCI/PICO).
I had a lot of help from chatgpt where there was back and forth on how to do different things (See Addendum 1).
Now I am connecting two boards through Serial UART. The communication is for two boards where A instructs B what colour RGB to output
BOARD A and BOARD B code is in downloads
First I upload code to board A
#include <Adafruit_NeoPixel.h>
#define LED_PIN 38
#define NUM_LEDS 1
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
Serial1.begin(9600);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
Serial1.print(input);
}
delay(50);
}
So I made sure before pressing upload to connect the board, USB enabled, and port COM so that it can compile properly
I get "failed uploading exit status 2" so I just closed and reopened Arduino and ran it again to be sure - now it's all working
Now I change to a second Barduino and upload the code for board B, 'the Slave'.
#include <Adafruit_NeoPixel.h>
#define LED_PIN 38
#define NUM_LEDS 1
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial1.begin(9600);
pixels.begin();
pixels.show();
}
void loop() {
if (Serial1.available()) {
String input = Serial1.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
}
delay(50);
}
The code compiled and the following video shows the successful operation entering Red Blue and Green and the light changing colour, then a different entry and the RGB switching off.
Now I loaded the Board A and Board B program onto the respective boards, made what I thought were the right connections, GND Board A to GND Board B, then the same for USB VCC and then connected TX Board A to RX Board B and RX Board A to TX Board B.
Both showed power, but when I ran commands like Red,Blue, Green into the Board A serial monitor, only Board A lit up.
I need to explore this in greater detail as after I have made things work with the two ESP32s then I will swap one for my SAMD11c development board – I am doing it this way since I want to increase chances that it will work first time.
I checked the code again and I changed a few things. Firstly, I realised with the help of chatgpt that my code was for the Arduino Mega not for ESP32 so I changed it. Then I also made sure that the code worked both ways so that Board A could control itself and Board B and vice versa. This was more efficient.
I managed to load the code onto one of my ESP32s but not the other. It was very frustrating and then chatgpt recommended that I press reset and hold the boot button down while executing compile code again. This time it loaded without issue.
One of the boards was working well, and the other still didn't execute the code. It turned out to be a wronly made wire connection. Once all this was sorted out. It worked beautifully.
The code block is:
#include <Adafruit_NeoPixel.h>
#define LED_PIN 38
#define NUM_LEDS 1
#define RX_PIN 43
#define TX_PIN 44
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// RX, TX (connect TX of other Board to RX of this Board, and vice versa)
HardwareSerial mySerial(1); // Use UART1
void setup() {
Serial.begin(115200);
mySerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
mySerial.print(input);
}
if (mySerial.available()) {
String input = mySerial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
Serial.print(input);
}
delay(50);
}
Remember when choosing a board as master remember to select the correct COM port before sending the command.
05/03/25
The following day i connected my SAMD11c to the usb port with the intention of communicating between it and ESP32.
Firstly I put the following code block into Arduino IDE
#define LED_PIN 5 // Replace with actual pin connected to the LED
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // Start off
Serial.begin(9600); // USB
Serial1.begin(9600); // UART (connected to ESP32)
Serial.println("SAMD11C Ready. Waiting for commands...");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim();
handleCommand(input);
Serial1.println(input); // Echo to ESP32
}
if (Serial1.available()) {
String input = Serial1.readStringUntil('\n');
input.trim();
handleCommand(input);
Serial.println(input); // Echo to USB
}
delay(20);
}
void handleCommand(String input) {
if (input == "red") {
digitalWrite(LED_PIN, HIGH);
} else if (input == "flashred") {
flashLED(30, 200); // Flash 3 times, 200ms interval
} else {
digitalWrite(LED_PIN, LOW);
}
}
void flashLED(int times, int interval) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH);
delay(interval);
digitalWrite(LED_PIN, LOW);
delay(interval);
}
}
I put the original ESP32 two way board com code into chatgpt and asked for it to adapt it to SAMD11c so we could have communication. It gave me the code above. I compiled it and tried the Code by typing red and the board flashed a red light on. Then I typed flash red and it gave me 30 flashes before switching off. That is a serial communication between the SAMD11C board and the USB. This is good as I am trying to establish that it will work in steps.
Next I will try and create UART serial communicate between the esp32 and Sam D11C

I have been having so much trouble connecting via UART which is my bootloader pins so I will try and use I2c communication
I have asked chatgpt to modify the ESP32 code for i2c and will do the same for the SAMD11c. I have copied the information below but the result was that it did not work. I have decided to leave it and come back to it.
After a break I am deciding to keep marching forward and try other things with the Barduino and then if and when this chip works I will l replicate the exercise.

The following is a fragment of my conversation with chatgpt enabling me to get the code:
Great — if your ESP32-S3 is the I2C master, the setup is simpler, as it initiates communication and sends commands to an I2C slave (e.g., an Arduino or another ESP32).
Below is your modified code assuming:
- The ESP32-S3 sends color commands over I2C to a slave device.
- The NeoPixel is still connected to the ESP32-S3, so it also lights up the LED based on the command.
- The I2C slave address is set to 0x08.
Here are the code blocks for each
Assuming ESP32 is master
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#define LED_PIN 38
#define NUM_LEDS 1
#define I2C_SLAVE_ADDRESS 0x08 // Address of the other device
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
Wire.begin(); // Start I2C as master
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove newline/extra spaces
// Send command to I2C slave
Wire.beginTransmission(I2C_SLAVE_ADDRESS);
Wire.write(input.c_str());
Wire.write('\n'); // use newline to indicate end of command
Wire.endTransmission();
// Light up local NeoPixel
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off
}
pixels.show();
}
delay(50);
}
05/05/25
Today I will take two ESP32 and connect the Master via C cable to my laptop and then the Slave via wires to the Master. The idea is to get them communicating through a local area network, and then later through wireless.
Code compiling while holding down boot button

ESP32 server code:
#include <WiFi.h>
#include <WebServer.h>
#define LED_PIN 48
const char* ssid = "ESP32_S3_AP";
const char* password = "12345678";
WebServer server(80);
void handleOn() {
digitalWrite(LED_PIN, HIGH);
server.send(200, "text/plain", "LED ON");
}
void handleOff() {
digitalWrite(LED_PIN, LOW);
server.send(200, "text/plain", "LED OFF");
}
void handleRoot() {
String html = "ESP32 LED Control
"
"Turn ON
"
"Turn OFF";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
WiFi.softAP(ssid, password);
Serial.print("Access Point started. IP: ");
Serial.println(WiFi.softAPIP());
server.on("/", handleRoot);
server.on("/on", handleOn);
server.on("/off", handleOff);
server.begin();
}
void loop() {
server.handleClient();
}
ESP32 Client code:
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "ESP32_S3_AP";
const char* password = "12345678";
#define BUTTON_PIN 0 // Push button input (active LOW)
bool lastButtonState = HIGH;
const char* serverIP = "192.168.4.1";
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to AP. IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
bool buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW && lastButtonState == HIGH) {
sendLEDCommand(true);
delay(500); // Simple debounce
} else if (buttonState == HIGH && lastButtonState == LOW) {
sendLEDCommand(false);
delay(500);
}
lastButtonState = buttonState;
}
void sendLEDCommand(bool turnOn) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String("http://") + serverIP + (turnOn ? "/on" : "/off");
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("Sent %s, Response: %d\n", turnOn ? "ON" : "OFF", httpCode);
} else {
Serial.printf("Failed to send request: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.println("WiFi not connected");
}
}
This image shows the ESP32 successfully connecting as a client (STA) to a Wi-Fi network named "ESP32_S3_AP" (the access point - AP), getting an IP address, and then successfully sending "ON" and "OFF" commands with a "200 OK" response.

The AP is the Access Point. It creates and broadcasts a Wi-Fi network that other devices can connect to like a hotspot.
The STA (Station/Client) is the device that connects to an existing network.
Essentially, the AP is the network creator, and the STA is the device that joins the network.
To make this relatable, this coding simulates a situation where we have a server which might control a remote fan, toaster, curtains or another peripheral. We can pick up the client device which might be like a mobile phone or remote control of some kind with wifi capability. We push the button the client it messages the server to activate the output device such as a light or toaster or other output.
On this ESP32 because I did not use a button, I connected a male wire to pin 01 which is in the code, and then to simulate pushing the button, I put the other male pin into the GND socket and that acts as a button push.
Eventhough I am happy this all worked, I was unhappy that I could not get my SAMD11c working.
On 05/06/25 I checked with Dani what the issue could be and we used the SWD programmer to re-burn the chip. It seems there is no issue SAMD11c.
I decided to try again and now put in the code to the Arduino IDE for ESP32 and SAMD11c for serial communication for Master I2C communication on COM9.
#include <Wire.h>
void setup() {
Wire.begin(); // SDA and SCL default pins (can be customized with Wire.begin(sda, scl))
Serial.begin(115200);
}
void loop() {
Wire.beginTransmission(0x10); // Address of the SAMD11C slave
Wire.write("Hello");
Wire.endTransmission();
delay(1000);
}
and for the SAMD11c use the following block of code:
#include <Wire.h>
void receiveEvent(int bytes) {
while (Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
Serial.println();
}
void setup() {
Wire.begin(0x10); // I2C slave address
Wire.onReceive(receiveEvent);
Serial.begin(115200);
}
void loop() {
// Nothing needed here for receive
}
See Addendum 2 for an extended discussion with Chatgpt
Here when I tried to re-burn the bootloader I got the following result. I realised I had to disconnect 5v from SAMD11c and only have 5v going to the ESP32. I tried it again and it didn't work either.
Failed to erase and so I want to re do the chip design to incorporate the ESP32 with its wifi and Bluetooth capabilities. I have already moved on from the SAMD11C and want to make a chip that won't have issues.

As of now (05/09/25), I have agreed with Dani to come up with a new schematic incorporating the ESP32 design – I will present what I have done on Monday (05/12/25). The goal is to finish the design and start cutting a new board on Monday, and finish soldering by Tuesday.
ADDENDUMS
ADDENDUM 1
This is a simplified version that allows you to control the NeoPixel LED via the Serial Monitor. You can type in color commands like red, green, or blue and the LED will change accordingly.
#include <Adafruit_NeoPixel.h>
#define LED_PIN 48
#define NUM_LEDS 1
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
}
}
How to use:
- Upload the sketch.
- Open the Serial Monitor (set to 9600 baud).
- Type red, green, or blue and press Enter.
- The LED will change to that color.
ADDENDUM 2
ChatGPT Conversation about I2C Communication:
I have an esp32 s3 and a samd11c and i want to make i2c serial communication between them.
Great — you can absolutely set up I²C communication between your ESP32-S3 and the SAMD11C, with one acting as master and the other as slave. Typically, the ESP32-S3 will be the I²C master, and the SAMD11C will be the I²C slave, especially since the ESP32 is more capable in terms of controlling communication flow.
Steps to Set Up I²C Communication
1. Connect the Hardware
- SDA (Data line)
- SCL (Clock line)
- GND (Common ground)
- 3.3V (or appropriate power)
💡 Add 4.7kΩ pull-up resistors to both SDA and SCL (to 3.3V) if not already on your dev boards.
2. ESP32-S3 as I²C Master
Use the Wire library in Arduino IDE or ESP-IDF.
3. SAMD11C as I²C Slave
For Arduino-based frameworks, use the Wire library with onReceive or onRequest handlers.
Notes
- I²C Address: Choose one (e.g., 0x10 for the SAMD11C).
- Make sure I²C speed (clock rate) is within what the SAMD11C supports — standard 100kHz is safe to start with.
- If using ESP-IDF or ASF/SAMD framework directly (not Arduino), let me know — examples differ.
Practical Results
ESP32 to ESP32 Communication
I successfully implemented communication between two ESP32 boards. Here's the setup and results:
RGB Control via Serial Communication
Using the Barduino board, I implemented RGB LED control through serial communication. The setup allows typing colors into the serial monitor to change the LED color:
// RGB Control Code
#include
#define LED_PIN 6
#define LED_COUNT 1
Adafruit_NeoPixel pixels(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
pixels.begin();
pixels.show();
}
void loop() {
if (Serial.available()) {
String color = Serial.readStringUntil('\n');
color.toLowerCase();
if (color == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (color == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (color == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
}
pixels.show();
}
}
SAMD11C Communication Challenges
While attempting to establish communication between the SAMD11C and ESP32, I encountered several challenges:
- Voltage level mismatches between the boards
- Different communication protocols requiring additional configuration
- Limited debugging capabilities on the SAMD11C
Future Improvements
For future networking projects, I plan to:
- Implement WiFi communication between ESP32 boards
- Explore Bluetooth connectivity options
- Create a more robust error handling system
- Design a custom PCB with proper level shifting for mixed-voltage systems
Communication Using my new-hip, hot, happening development board with ESP32 S3 W1
Final working Arduino Files for wired networking
Now that I have my new dev board I am going to test it to see that it works before completing the assignment of communicating between two devices including my Dev board

I go to my schematic to see that my LEDpin is on pin 21.
I test the following blink program:
/*
Blink
https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/
#define BUILTIN_LED 21 //defining the LED as a variable
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(BUILTIN_LED, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(BUILTIN_LED, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(BUILTIN_LED, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
The board was not working as expected – I couldn't detect any sound being made when it was plugged in and no light, but then randomly it would have a sound or light from when I blinked it initially in class after soldering it.
So I took a multi-meter and tested voltages around the board. The blue line points to the places I was testing the voltage around the board, and the red probe was always on the VCC of the ESP32.

I found that in a certain area there was a drop in voltage which was not expected. For example, I expect there to be 5v coming into the board and dropping to 3.3v between ground of USB and VCC pin of ESP32….So I tested this by leaving a red probe in the VCC pin of the ESP32 and then using the black probe to test the GND pin of the USB Mini port (1). It measured 3.3v, then I moved it further along the circuit and put the Black probe into the J3 24v IN GND screw connector (2) and it also measured 3.3v.
Then I continued by moving it to the GND pin of the I2C connector (3) and it also measured 3.3v.
Now when I measure the voltage across the VCC pin of the ESP32 on the left and then GND pin on the ESP32 on the right side (4) I find there is a voltage drop to 2.6v. This implies that there might be a poor connection somewhere between the GND pin of the I2c connector and the GND pin of the ESP32 connector. This is the area where the voltage seems to drop.
So then it could be that it is poorly soldered. I tried using a male to male wire in a makeshift fashion to connect the ESP32 GND to the I2C GND. Suddenly the blink that I did when I first soldered the board started flashing, and the chip made a noise as if it is connected and I was able to detect the Port as long as I held down the wire at the same time.

With the sticky tape it seems to be working, so I will solder the board in the morning and hope to be able to complete the task quickly.
All in all a difficult day as hardly any of my goals were achieved in terms of working electronics, doing assignments, or printing out anything.
This board is a main lynch pin for me to get two assignments done but with each of these issues my knowledge is taking a step up which is good.
On Wednesday morning I just looked at my development board under a video microscope with Adai and confirmed that the trace between the I2C GND and then ESP32 GND was indeed broken accounting for the drop in Voltage. I soldered it, heard the noise as the port connects, saw the port, and blinked it successfully.
Board Communication Setup
To fulfil the assignment I will communicate between my development board and the Barduino. I will use wire UART communication where one of the boards is the master and the second board can also respond, i.e. 2 way communication.
So we will refer to them as Board A and Board B.
Development Board Code (Board A)
#include
#define LED_PIN 38
#define BUILTIN_LED1 21
#define NUM_LEDS 1
#define RX_PIN 5
#define TX_PIN 7
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// RX, TX (connect TX of other Board to RX of this Board, and vice versa)
HardwareSerial mySerial(1); // Use UART1
void setup() {
Serial.begin(115200);
mySerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
pinMode(21, OUTPUT);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
digitalWrite (21, HIGH);
}
void loop() {
if (Serial.available()) {
digitalWrite (BUILTIN_LED1, HIGH);
delay(200);
digitalWrite (BUILTIN_LED1, LOW);
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
mySerial.print(input);
}
if (mySerial.available()) {
String input = mySerial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
Serial.print(input);
}
delay(50);
}
Board Pinouts
The Barduino pinout shows:

LED on Pin 48 NEOPIXEL on Pin 38
And here is a pinout for my own development Board

LED on Pin 21
Pin Selection for Communication

I realise that for this assignment each board needs and RX and TX pin assigned. So on the Barduino there are many available pins as well as specifically assigned pins. However on my development board I can see pin 5 goes to the DIM OUT of the Dimmer Connector, and Pin 7 goes to the PIR Data line.
So given that they are both data lines they are suitable for RX and TX.
I successfully managed to control Board B the Barduino with my Dev Board ESP32 by switching on Blue, Green, Off controls.
Conversely I was able to control my Dev Board A with the Barduino using commands like ON, OFF, BLINK
Barduino Code (Board B)
#include
#define LED_PIN 38
#define NUM_LEDS 1
#define RX_PIN 5
#define TX_PIN 7
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
// RX, TX (connect TX of other Board to RX of this Board, and vice versa)
HardwareSerial mySerial(1); // Use UART1
void setup() {
Serial.begin(115200);
mySerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
pinMode(48, OUTPUT);
pixels.begin();
pixels.show();
Serial.println("Type 'red', 'green', or 'blue' in Serial Monitor:");
digitalWrite (48, HIGH);
}
void loop() {
if (Serial.available()) {
digitalWrite (48, HIGH);
delay(200);
digitalWrite (48, LOW);
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
mySerial.print(input);
}
if (mySerial.available()) {
String input = mySerial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "red") {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
} else if (input == "green") {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
} else if (input == "blue") {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
} else {
pixels.setPixelColor(0, 0); // turn off if unknown command
}
pixels.show();
Serial.print(input);
}
delay(50);
}
Now I have Board A and Board B controls side by side:

So essentially what happened here is on Board A my custom board when I type in RED GREEN or BLUE those colours switch on on the NEOPIXEL of the BARDUINO. When I type another command which is unprogrammed then the light switches off.
On the other hand when something is typed into the BOARD B command nothing happens to my Development board because it has not been programmed to receive an instruction.
So The following code for Board A changes things so that it will be able to receive code such as RED REDOFF or REDFAST, and it will switch on the red light, switch it off or blink it fast. I do this since my dev board doesn't have a NEOPIXEL RGB.
Modified Board A Code
#define LED_PIN 21
#define RX_PIN 5
#define TX_PIN 7
HardwareSerial mySerial(1); // Use UART1
void setup() {
Serial.begin(115200);
mySerial.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH); // Start with LED ON
Serial.println("BOARD_A: Type 'on', 'off', or 'blink' in Serial Monitor:");
Serial.println("BOARD_B: Type 'red', 'green', or 'blue' in Serial Monitor:");
}
void loop() {
if (Serial.available()) {
String input = Serial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "on") {
digitalWrite(LED_PIN, HIGH);
} else if (input == "off") {
digitalWrite(LED_PIN, LOW);
} else if (input == "blink") {
digitalWrite(LED_PIN, HIGH);
delay(5000);
digitalWrite(LED_PIN, LOW);
}
mySerial.println(input); // echo to other board
}
if (mySerial.available()) {
String input = mySerial.readStringUntil('\n');
input.trim(); // remove any trailing newline or spaces
if (input == "on") {
digitalWrite(LED_PIN, HIGH);
} else if (input == "off") {
digitalWrite(LED_PIN, LOW);
} else if (input == "blink") {
digitalWrite(LED_PIN, HIGH);
delay(5000);
digitalWrite(LED_PIN, LOW);
}
Serial.println(input); // echo back to Serial Monitor
}
delay(50);
}
I successfully managed to control Board B the Barduino with my Dev Board ESP32 by switching on Blue, Green, Off controls. Conversely I was able to control my Dev Board A with the Barduino using commands like ON, OFF, and BLINK