Assignment Brief:
- Design, build, and connect wired or wireless nodes with network or bus addresses, incorporating
local input and/or output devices.
- As a Gorup send a message between two different projects.
Networking and Communications
Networking and communication (in short) refers to how devices like computers, phones, or machines connect
and exchange data with each other using wired or wireless connections. It includes systems like the
internet, Wi-Fi, Bluetooth, and more, allowing information sharing, collaboration, and remote access.
In the week, I learn't a lot of theory knowledge. I started with referring to
week 04: Embedded Programming. Brushing up learns from there of Serial communication
and parallel communication. Serial = like sending messages one by one over WhatsApp.
Parallel = like talking to someone in person using many words at once.
Parallel communication
serial communication
UART, USART, SERCOM, PIO, and Bit-bang
Then further I learn about UART, USART, SERCOM, PIO, and Bit-bang. are all types of serial communication
used by microcontrollers to exchange data with other devices like sensors, chips, or computers. They
send data one bit at a time over a line. Some use dedicated hardware (like UART and USART), others offer
flexible configuration (like SERCOM), custom protocol creation (like PIO), or rely entirely on software
control (like Bit-banging). Note: synchronization refer to clock. I would suggest to refer to
week 04: Embedded Programming week before diving into Networking and communication.
UART (Universal Asynchronous Receiver/Transmitter)
A hardware module for serial communication using 2 wires (TX & RX). It doesn't use a clock signal—relies
on timing.
USART (Universal Synchronous/Asynchronous Receiver/Transmitter)
Like UART but more advanced. Can do both asynchronous (UART) and synchronous (uses a clock)
communication.
SERCOM (Serial Communication Interface)
Found in Atmel, eg. Atitiny and Aurdino.
A flexible peripheral in some microcontrollers (like from Microchip) that can be configured as UART,
SPI, or I2C—based on your needs.
PIO (Programmable I/O)
Found in RP2040 (Raspberry Pi Pico). Lets you create custom I/O protocols in hardware, very flexible and
fast for custom tasks.
Bit-bang
A software-only method to simulate communication (like UART, SPI, etc.) using GPIO pins. Slower and
processor-heavy but works without special hardware.
RS-232, RS-422, and RS-485
RS-232, RS-422, and RS-485 are serial communication standards that define the electrical signals, wiring,
and data transmission rules for sending data between devices.
RS-232 is for short-distance, point-to-point communication (like old COM ports).
RS-422 supports longer distances and faster speeds with one sender and multiple receivers. That is
10 multipliers.
RS-485 is great for industrial use, allowing multiple devices to communicate over long distances
using a shared bus.
Some important terms I learn were:
🔁 Full-duplex: Data can be sent and received at the same time (like a phone call).
🔁 Half-duplex: Data can be sent or received, but not both at once (like a walkie-talkie).
Broad Hops is the number of devices (routers) a data packet passes through to reach its
destination.
Fewer hops = faster communication. Example: If data goes from PC → Router 1 → Router 2 → Server,
that’s a hop count of 3.
Broad Hops
Refers to how far a broadcast message can travel in a network.
Usually limited to avoid network congestion. A broadcast sends data to all devices on a local
network, and usually, routers block broadcasts from going too far to reduce traffic.
SPI, I2C AND I3C Communication
SPI (Serial Peripheral Interface), I2C (Inter-Integrated Circuit), and I3C (Improved Inter-Integrated
Circuit) are serial communication protocols used in electronics to allow microcontrollers to communicate
with other devices like sensors, displays, memory chips, and more.
They define how data is transferred between a central controller (called the master) and connected
devices (called slaves or peripherals), using specific rules, wire setups, and speeds
SPI (Serial Peripheral Interface)
- Fast, full-duplex, 4-wire protocol: MISO (Master inslave out), MOSI (Master out slave in), SCLK
(Clock), SS (Chip selector)
- Master-slave setup
- Good for short-distance, high-speed communication
- Devices need separate chip select lines
I2C (Inter-Integrated Circuit)
- 2-wire protocol SDA (Serial Data Line), SCL (Serial Clock Line).
- Supports multiple masters and slaves
- Uses addressing to manage devices (no extra chip select lines)
- Slower than SPI but simpler wiring
SPI (Serial Peripheral Interface)
I2C (Inter-Integrated Circuit)
I3C (Improved Inter-Integrated Circuit)
- Next-gen version of I2C
- Backward compatible with I2C
- Faster, lower power, dynamic addressing, better device management
- Ideal for modern sensors in smartphones, wearables, etc.
TWI (Two-Wire Interface)
TWI is essentially Atmel/Microchip’s name for I2C—it uses two wires (SDA & SCL) for communication
between devices. TWI = same as I2C, just a different name used by some microcontrollers. Functionally,
they work the same way.
Some important terms I learn were: These terms are used in SPI communication to show data
direction
between the controller (master) and peripheral (slave).
- PICO – Peripheral In, Controller Out
Data sent from controller to peripheral (like sending commands). Just as MISO in SPI Communication.
- POCI – Peripheral Out, Controller In
Data sent from peripheral to controller (like reading sensor data). Just as MISO in SPI
Communication.
ATP, USB, Ethernet, CAN, LIN, Modbus, and DMX
These are all communication protocols—which means they are sets of rules that devices follow to send and
receive data. All of these are special languages that devices use to exchange data, each designed for a
specific purpose—computers, vehicles, factories, or lighting setups.
1. ATP (Advanced Transport Protocol)
- Used in wireless systems like Zigbee, Bluetooth, LoRa.
- Standard for connecting devices to computers.
Supports data + power; speeds up to 40 Gbps.
- Provides reliable data transfer with error checking and retransmission mechanisms.
- Needs a host device.
- Used in: Wireless sensor networks and industrial IoT applications.
2. USB (Universal Serial Bus)
- Serial communication standard for connecting peripherals to computers.
- Uses a host-controller model (host = PC, peripherals = devices).
- Supports different speeds: USB 1.1: 12 Mbps to USB 4.0: 40 Gbps
- Use Cases:
Connecting peripherals (mice, keyboards, printers, etc.).
Data transfer (external drives, flash drives).
Charging and powering devices.
3. Ethernet
- Wired networking standard used for local area networks (LANs).
- Uses packet-based communication with MAC addressing.
\- Speed variations:
Fast Ethernet: 100 Mbps to 40G/100G Ethernet: High-performance networking.
- Use Cases:
Office and industrial networking.
IoT and embedded systems (with Ethernet-enabled microcontrollers).
Server-to-server high-speed communication.
4. CAN (Controller Area Network)
- Multi-master, differential serial bus used in automotive and industrial applications.
- Supports real-time communication with priority-based arbitration.
- CAN FD (Flexible Data Rate): Up to 8 Mbps.
- Uses differential signaling for noise immunity.
Works over a twisted pair for robustness in noisy environments.
- Use Cases:
Automotive (ECU communication: engine, ABS, airbags).
Industrial automation (robots, factory control).
5. LIN (Local Interconnect Network)
- Simplified, low-cost alternative to CAN for non-critical applications.
- Uses single-wire communication with a master-slave topology.
- Lower speed than CAN (~19.2 kbps to 20 kbps).
- Use Cases:
Car window controls, seat adjustment, lighting.
Low-cost sensor communication in vehicles.
6. Modbus
is a communication protocol used in industrial automation.
Devices like PLCs, sensors, and controllers use it to exchange data. Use: Factories, SCADA systems,
process control.
7. DMX (Digital Multiplex) is a protocol for controlling stage lighting and effects.
Sends fast, continuous signals to lights, fog machines, and dimmers.
Use: Theatres, concerts, event lighting setups.
OSI Layers
The OSI (Open Systems Interconnection) Model is a conceptual framework that describes how data moves
or travels from one device to another over a network, in 7 layers, each with a specific function.
Real-World Example of OSI Model in Action (Web Browsing)
You type "www.google.com" in your browser (Layer 7 - HTTP).
The browser encrypts the request using TLS (Layer 6 - SSL/TLS).
A session is established with Google’s server (Layer 5 - TCP Session).
The data is broken into packets using TCP (Layer 4 - Transport).
Each packet is assigned an IP address (Layer 3 - IP Routing).
The packet is sent over an Ethernet/Wi-Fi connection (Layer 2 - MAC, Wi-Fi).
The data is converted into electrical signals or radio waves (Layer 1 - PHY).
Wire sheilding
Cable shielding protects signal wires from electrical noise and interference. It's used in communication,
audio, and data cables to ensure clean signal transmission.
Different types (Unshielded, Foil, Braid, Foil + Braid) offer varying levels of protection—more
shielding means better performance, especially in noisy environments. More shielding = better signal
quality and less interference.
Unshielded – No protection from interference.
Foil Shield – Basic protection using a thin foil wrap.
Braid Shield – Better shielding with a metal mesh.
Foil & Braid – Best protection using both foil and mesh.
Assignment: Networking and Communication
My this week's assignment is divided into to three parts
- Aurdino to Arduino using I2C
- Xiao RP2040 to Arduino UNO using I2C
- NodeMCU (ESP8266) to NodeMCU using wireless connection
Aurdino to Arduino to XAIO using I2C
NodeMCU (ESP8266) to NodeMCU using wireless connection
I2C Between Arduinos
I referred to the Instructables link, I2C Between Arduinos by Cornelam. I2C (Inter-Integrated Circuit) is a serial communication
protocol that lets multiple devices (like sensors or other Arduinos) talk using just two wires:
SDA – Serial Data Line
SCL – Serial Clock Line
One Arduino acts as the Master, and others as Slaves. Each slave has a unique address, and the master
controls all communication.
Efficient for connecting many devices.
Less wiring.
Used for sensor modules, EEPROMs, other Arduinos, etc.
Wire connections
Connect pins A4/SDA and A5/SCL on one Arduino to the same pins on the other one.
The GND line has to be common for both Arduinos. Connect it with a jumper.
Further, I connected an LED at pin 12 and GND to slave Aurdino.
Note: Remember never to connect 5 V and 3.3 V Arduinos together. It won't
hurt the 5V Arduino, but it will certainly annoy its 3.3 V!
Uploaded the Master code to the Arduino Master.
Uploaded the Slave code to the Arduino Slave.
#include
int slaveAddress = 9; // Slave I2C address (same as in the slave code)
void setup() {
// Start the I2C communication as master
Wire.begin();
// Start the serial communication for debugging
Serial.begin(9600);
delay(1000); // Wait for Serial to initialize
}
void loop() {
// Send a command to the slave to blink the LED
Wire.beginTransmission(slaveAddress);
Wire.write('1'); // Send the command '1' to make the slave blink the LED
Wire.endTransmission();
// Print to Serial Monitor
Serial.println("Sent command to blink LED");
// Wait 2 seconds before sending the next command
delay(2000);
}
#include
int LED = 12; // Pin for the LED
int x = 0; // Variable to store received data
void setup() {
// Define the LED pin as Output
pinMode(LED, OUTPUT);
// Start the I2C Bus as Slave with address 9
Wire.begin(9);
// Attach the receive function to handle I2C communication
Wire.onReceive(receiveEvent);
// Start serial communication for debugging
Serial.begin(9600);
}
void receiveEvent(int bytes) {
x = Wire.read(); // Read the byte sent from the master
}
void loop() {
// Print the received value to Serial Monitor for debugging
Serial.print("Received value: ");
Serial.println(x);
// If the value received is '1', blink the LED every 1 second
if (x == '1') {
digitalWrite(LED, HIGH); // Turn the LED on
delay(1000); // Wait for 1 second
digitalWrite(LED, LOW); // Turn the LED off
delay(1000); // Wait for 1 second
}
// Optional: Small delay to avoid overloading the Serial Monitor
delay(100);
}
Here:
LED is the pin where the LED is connected and
x stores the received data from the master.
Once the code was uploaded to both the Arduino's and the program ran smoothly, the code was stored in the
memory for aurdino.
So I removed the USB cables for both and gave a Power battery supply to the Master Arduino. The Arduino
didnt work on a Lower Battery Supply. It needed a
Supply of 5V or above.
Note: Use the VIN pin for to power the Arduino, as VIN + GNd goes through
regulator and
powers it smoothly.
Xiao RP2040 to Arduino UNO using I2C
Referring to Documentation of my senior, Siddharth Agarwal for Xiao RP2040 to Arduino UNO using I2C. I learnt a few things from the
documentation
Like:
One, RP2040 to RP2040 does not work due to a bug in the chip itself, and Two, When connecting
RP2040
to anything else, to be cautious of the voltage difference.
He has added my professor
Jesal Sir's
Quote which I learnt the hard way buy burning a Xaio. Quoting
“One has to be careful here, since the XIAO operates at 3.3 V while the Uno operates at 5 V. The I2C
connection operates at whatever the Master is operating at. So the XIAO being the Primary or Master
would work for the Uno but not the other way
!"
Wire connections
SDA (D4) [XIAO] to SDA (A4) [Uno]
SCL (D5) [XIAO] to SCL (A5) [Uno]
common GND
LED on Arduino and pin 12 and GND
Uploaded the Master code to the XAIO Master.
Uploaded the Slave code to the Arduino Slave.
#include
int slaveAddress = 9; // The address of the Arduino Uno (slave)
void setup() {
// Start the I2C communication as master
Wire.begin();
// Start the serial communication for debugging
Serial.begin(9600);
delay(1000); // Wait for Serial to initialize
}
void loop() {
// Send a command to the slave to blink the LED
Wire.beginTransmission(slaveAddress);
Wire.write('1'); // Send the command '1' to make the slave blink the LED
Wire.endTransmission();
// Print to Serial Monitor
Serial.println("Sent command to blink LED");
// Wait 2 seconds before sending the next command
delay(2000);
}
#include
int LED = 12; // Pin for the LED
int x = 0; // Variable to store received data
void setup() {
// Define the LED pin as Output
pinMode(LED, OUTPUT);
// Start the I2C Bus as Slave with address 9
Wire.begin(9);
// Attach the receive function to handle I2C communication
Wire.onReceive(receiveEvent);
// Start serial communication for debugging
Serial.begin(9600);
}
void receiveEvent(int bytes) {
x = Wire.read(); // Read the byte sent from the master
}
void loop() {
// Print the received value to Serial Monitor for debugging
Serial.print("Received value: ");
Serial.println(x);
// If the value received is '1', blink the LED every 1 second
if (x == '1') {
digitalWrite(LED, HIGH); // Turn the LED on
delay(1000); // Wait for 1 second
digitalWrite(LED, LOW); // Turn the LED off
delay(1000); // Wait for 1 second
}
// Optional: Small delay to avoid overloading the Serial Monitor
delay(100);
}
NodeMCU to NodeMCU
The NodeMCU uses an ESP8266 microcontroller which can communicate wirelessly over wi-fi or bluetooth. In this
week, we communicate between the nodeMCUs using a wireless communication protocol called ESPNow, which runs
on top of WiFi. Again I referred to
Siddharth's Documentation for Node MCU connection
Difference between NODE MCU and ESP32
The NodeMCU and ESP32 are both popular microcontroller boards used in IoT and embedded projects, but they
differ in capabilities, hardware, and use cases.
Node MCU pinout:
Setting up the IDE
In order to program the NodeMCU, we need to first install the necessary drivers. This can be found on this
link
Silicone
Labs for Arduino IDE. Most NodeMCU boards use a CP210x USB to UART bridge made by Silicon Labs.
Without the correct driver, your computer might not detect the board properly, and you won't be able to
upload code from the Arduino IDE or any other development environment.
I installed the Universal windows driver and ran the program on my computer, and run the
programme on software.
Board setup on Arduino IDE
I opened up Arduino IDE and went to “Preferences” under File.
There, under “Additional Boards Manager URL” I added the following link:
https://arduino.esp8266.com/stable/package_esp8266com_index.json
and finally, I went to the Board Manager under Tools and searched for ESP8266 by Community and installed it.
Tools> Boards> Board manager to set up the
Add the board manager URL link.
Preferences> Library> Search for esp8266.
Install esp8266 by esp8266 community.
Tools> Boards> esp8266> Generic esp8266 Module.
Connect NodeMCU to the port and set the board as well.
Mater Connections
Slave connections.
Mater Connections
Slave connections.
Generating Mac address
To start with any wireless communication, we need to first find the Mac Address of the microcontroller we are
using. Mac Address has nothing to do with the MacBook or Apple and actually stands for “Media Access Control
Address”. It is the unique address/identifier of a controller that can communicate wirelessly.
You simply run the Mac Address code after connecting your microcontroller and once uploaded, hit the “Reset”
button on your microcontroller and look at your Serial Monitor. You will find the unique 6-figure address of
your controller.
Add Mac Address code.
// For ESP 32:
// #include
// For ESP8266
#include
void setup(){
Serial.begin(115200);
delay(500);
Serial.println();
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
}
void loop(){}
Upload the Mac Address code.
Press Control> Shift M> Serial Monitor
Slave Mac Address code.
Master Mac Address Code
Slave Mac Address
Master Mac Address
#include // initializing the required resource libraries
#include
uint8_t broadcastAddress[] = {0x30,0x30,0xF9,0x17,0xF8,0x94}; // Secondary's MAC Address 2C:f4:32:OE:EO:F8
#define BUTTON_PIN 13 // The ESP8266 pin D7 connected to button
typedef struct struct_message { //create a structure called "message" and add the contents of the message
int btnstate; //integer value "c"
} struct_message;
struct_message myData;
// Create a struct_message called myData
unsigned long lastTime = 0;
unsigned long timerDelay = 1000; // send readings timer
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
void setup() {
Serial.begin(115200); // Init Serial Monitor
WiFi.mode(WIFI_STA); // Set device as a Wi-Fi Station
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
// Initialize the Serial to communicate with the Serial Monitor.
pinMode(BUTTON_PIN, INPUT_PULLUP); // Configure the ESP8266 pin as a pull-up input: HIGH when the button is open, LOW when pressed.
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
//int button_state = digitalRead(BUTTON_PIN); // read the state of the switch/button:
myData.btnstate = digitalRead(BUTTON_PIN);
Serial.println(myData.btnstate); // print out the button's state
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
lastTime = millis();
}
}
#include
#include
#define LEDpin D7 //Connect LED on pin 2
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message { //create a structure called "message" and add the contents of the messag
int btnstate; //integer value "State"
} struct_message;
struct_message myData; // Create a struct_message called myData
// Callback function that will be executed when data is received
void OnDataRecv(uint8_t *mac, uint8_t *incomingData, uint8_t len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Received state: ");
Serial.println(myData.btnstate);
Serial.println();
}
void setup() {
pinMode(LEDpin, OUTPUT); //Define LED as output
Serial.begin(115200); // Initialize Serial Monitor
WiFi.mode(WIFI_STA); // Set device as a Wi-Fi Station
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
if (myData.btnstate == 0) {
digitalWrite(LEDpin, HIGH);
} else {
digitalWrite(LEDpin, LOW);
}
}
As you can see, I uploaded an LED blink code to the Master Node MCU to blink and LED at the Slave Node MCU and
the Code Uploaded successfully.
#define ledPin 1 // D1 = GPIO5 on NodeMCU
void setup() {
pinMode(ledPin, OUTPUT); // Set D1 as an OUTPUT pin
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn the LED ON
delay(1000); // Wait for 1 second
digitalWrite(ledPin, LOW); // Turn the LED OFF
delay(1000); // Wait for 1 second
}
Learning and Process
During the Networking and Communication week, I attempted to establish communication between two NodeMCU
boards. I successfully uploaded the code onto both boards; however, there was no visible response from the
NodeMCUs.
Initially, I suspected a networking issue, but I observed that even a single NodeMCU, when tested
independently, showed no action. This led me to investigate further and conclude that the problem likely
lies in the code configuration — specifically, how the pins were defined and managed.
Thus I tried different GPIO pin confuguration like
However, with multiple attempts, the code didnt work. I am yet to debug the issue for the same.
Considering the time constrains I moved forward with
the Group assignment as the Node MCU was for my learning experiance and not related to my final project.