WEEK 11 Embedded Networking and Communications
GROUP ASSIGNMENT:
Arduino to Arduino Communication Using I2C
For the Group Assignment I used some tutorials to understand and communicate between two Arduino UNO’s
https://www.electronicwings.com/arduino/arduino-i2c
https://dronebotworkshop.com/i2c-arduino-arduino/
What is I2C?
I2C stands for Inter-Integrated Circuit. It is a way for electronic devices to talk to each other using only two wires. One wire is used to carry data (this is called SDA), and the other wire is used to keep everything in sync with timing (this is called SCL).
You can think of it like two people passing notes in class, where one person decides when to send the note (the timing), and the other person listens and reads the message.
With I2C, one device is in charge of starting the communication. This is called the "main" device. The other device waits and responds when it is told to. This is called the "secondary" device.
I2C is useful because it lets multiple devices share the same two wires to communicate, instead of needing a lot of separate connections.
How I Connected Two Arduino Boards
I used two Arduino UNO boards. I connected them with these three wires:
- A wire from A4 on the first Arduino to A4 on the second Arduino (this is SDA, the data wire)
- A wire from A5 on the first Arduino to A5 on the second Arduino (this is SCL, the clock or timing wire)
- A wire from GND on the first Arduino to GND on the second Arduino (this is the ground wire, which connects the two boards' power systems)
Both boards need to share a ground connection so they can understand each other's signals.
How the Communication Works
To make the two Arduinos talk to each other, I used the tutorial’s code:
-
The first Arduino acts as the "main" device. It sends messages.
#include <Wire.h> void setup() { Serial.begin(9600); /* begin serial comm. */ Wire.begin(); /* join i2c bus as master */ Serial.println("I am I2C Master"); } void loop() { Wire.beginTransmission(8); /* begin with device address 8 */ Wire.write("Hello Slave"); /* sends hello string */ Wire.endTransmission(); /* stop transmitting */ Wire.requestFrom(8, 9); /* request & read data of size 9 from slave */ while(Wire.available()){ char c = Wire.read();/* read data received from slave */ Serial.print(c); } Serial.println(); delay(1000); }
-
The second Arduino acts as the "secondary" device. It waits and receives messages.
#include <Wire.h> void setup() { Wire.begin(8); /* join i2c bus with address 8 */ Wire.onReceive(receiveEvent); /* register receive event */ Wire.onRequest(requestEvent); /* register request event */ Serial.begin(9600); /* start serial comm. */ Serial.println("I am I2C Slave"); } void loop() { delay(100); } // function that executes whenever data is received from master void receiveEvent(int howMany) { while (0 <Wire.available()) { char c = Wire.read(); /* receive byte as a character */ Serial.print(c); /* print the character */ } Serial.println(); /* to newline */ } // function that executes whenever data is requested from master void requestEvent() { Wire.write("Hi Master"); /*send string on request */ }
Each Arduino is programmed using the Arduino software. I used a library called "Wire" which is already included in the Arduino software. This library makes it easy to use the I2C system.
The main Arduino starts communication and sends a short message like a number or a word. The secondary Arduino listens and receives that message. I checked the results using the Serial Monitor (a tool in the Arduino software that lets you see messages printed from the boards).
What I Learned:
- I2C allows two (or more) Arduino boards to communicate using only two wires for data.
- One board controls when and what is sent (main), and the other listens and responds (secondary).
- It is important to connect the ground wire between the boards.
- Using the Serial Monitor helps confirm that the communication is working.
This kind of connection is useful when you want one Arduino to control or collect information from other boards or sensors.
INDIVIDUAL ASSIGNMENT:
I2C BETWEEN XIAOESP32 C3 x XIAOESP32 C3
I used this tutorial to understand I2C connection between two ESP32
https://randomnerdtutorials.com/esp32-i2c-master-slave-arduino/
I decided to make a new PCB for THE BUTTON and unfortunately I overlooked a mistake I did in THE REWARD MACHINE’s PCB and I repeated it:
I spend 2 days looking for the problem in the code and in the program (because the wiring and paths were showing good connection, but between wrong pins on two boards)
On the top of this I struggled with the FlatCam program again. Suddenly it was not showing me path outcome.
My PCB came out with very thin paths, since I couldn’t put the offset OUT.
But I mange to solder everything.
Some of the paths unglued from the board, because they were just a little bit thicker then hair (on the photo they look nicer then in reality)
Unfortunately the pin header didn’t have enough surface to hold onto so while I was detaching the Xiao to make some jumping wires connection because of the wrong pinouts- it pulled everything out
Now I need to make a new PCB. The program is not stable as I already know from my previous week. I was keep reinstalling the app hoping it will come back when suddenly, by checking my previous screenshots I realized I wasn’t in the advanced mode… I didn’t know I had to activate it, so I’ll add this tip in the https://fabacademy.org/2025/labs/benfica/students/daniel-osika/WEEK08/
CONNECTION BETWEEN THE BUTTON & THE REWARD MACHINE
MAIN (square board)
#include <Arduino.h>
#include <Wire.h>
const int button = D7; // Button pin
const int led = D2; // Local LED (optional)
const int squareAddress = 0x08; // I2C address of Square
bool lastButtonState = HIGH; // Previous state (starts HIGH = not pressed)
void setup() {
delay(1000);
Serial.begin(115200);
pinMode(button, INPUT); // External pull-up
pinMode(led, OUTPUT); // Optional local LED
Wire.begin(); // Start I2C as master
Serial.println("Circle ready (I2C master)");
}
void loop() {
bool currentState = digitalRead(button);
// Only act on state change
if (currentState != lastButtonState) {
lastButtonState = currentState;
// Invert to get "pressed = LOW"
bool pressed = (currentState == LOW);
digitalWrite(led, pressed); // Optional: reflect button locally
Wire.beginTransmission(squareAddress); // Begin I2C transmission
Wire.write(pressed ? '1' : '0'); // Send '1' or '0'
Wire.endTransmission(); // End transmission
Serial.println(pressed ? "Button pressed → LED ON" : "Button released → LED OFF");
}
delay(50); // Small debounce delay
}
SECONDARY (circle board- changed for the a breadboard)
#include <Arduino.h>
#include <Wire.h>
const int led = D7; // LED pin
const int i2cAddress = 0x08; // I2C address of this board
// Function to handle incoming I2C data
void receiveEvent(int numBytes) {
if (numBytes > 0) {
char command = Wire.read(); // Read the first byte
if (command == '1') {
digitalWrite(led, HIGH); // Turn LED on
Serial.println("LED ON (received 1)");
} else if (command == '0') {
digitalWrite(led, LOW); // Turn LED off
Serial.println("LED OFF (received 0)");
}
}
}
void setup() {
delay(1000);
Serial.begin(115200);
pinMode(led, OUTPUT); // Set LED as output
digitalWrite(led, LOW); // Ensure LED is off initially
Wire.begin(i2cAddress); // Start I2C as slave
Wire.onReceive(receiveEvent); // Register receive event handler
Serial.println("Square ready (I2C slave)");
}
void loop() {
// Nothing needed here — everything happens on receiveEvent
}
Since I destroyed THE BUTTON PCB I used a breadboard, and THE REWARD MACHINE PCB had possibility to use I2C connection because on my pin D6 I also had a header. Finally I made it work!!!
FILES:
KICAD
BUTTON
FLATCAM
BUTTON
CHECKLIST:
Group assignment:
- Send a message between two projects
- Document your work to the group work page and reflect on your individual page what you learned
Individual assignment:
- design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices
Learning outcomes:
- Demonstrate workflows used in network design
- Implement and interpret networking protocols and/or communication protocols
Have you answered these questions?
- Linked to the group assignment page
- Documented your project and what you have learned from implementing networking and/or communication protocols.
- Explained the programming process(es) you used.
- Ensured and documented that your addressing for boards works
- Outlined problems and how you fixed them.
- Included design files (or linked to where they are located if you are using a board you have designed and fabricated earlier) and original source code.
- Included a ‘hero shot’ of your network and/or communications setup