Embedded Networking and Communications

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 device

#.Group assignment:

Group Work Reflection

Here is the Group assignment(link)

#.Individual assignment

The goal of this week’s individual assignment was to:

Design, build, and connect wired or wireless node(s) with network or bus addresses and a local input and/or output device.

This challenge was all about exploring embedded communication between devices and implementing a real connection using a protocol of choice.

My Approach

I started by revisiting the communication protocols supported by the microcontroller I used when designing my board back in Week 8 — specifically UART, SPI, and I2C. Among these, I found I2C the most suitable for simple communication between two boards with minimal wiring.

Resources & Tools:

  • My custom board from Week 8,based on the XIAO RP2040.
  • An Arduino Uno R3 , used as the secondary node.
  • Basic I2C wiring: SDA, SCL, and Ground.

The Journey

Learning the Protocol:

To confidently implement I2C, I explored tutorials and documentation online. A helpful resource was Soldered’s guide on I2C , as well as various YouTube videos that simplified how data is transmitted using this protocol.

Implementation Plan:

  • Master: My board (XIAO RP2040)
  • Slave: Arduino Uno R3
  • Address: 0x08
  • Goal: Send a message ("Hello") from the master, and get a response ("World!") from the slave.

Wiring:

  • SDA and SCL connected between the boards.
  • GND shared between devices.
  • On Arduino Uno R3: SDA = A4, SCL = A5

image

I connected my board and the Arduino Uno R3 using the appropriate pins (SDA to A4, SCL to A5, and a common GND) to set up I2C communication.

Code Implementation

Master (My board)


              #include 


                #define SLAVE_ADDRESS 0x08
                
                
                void setup() {
                  Wire.begin(); // master mode
                  Serial.begin(115200);
                  delay(1000);
                  Serial.println("I2C Master Ready");
                }
                
                
                void loop() {
                  Wire.beginTransmission(SLAVE_ADDRESS);
                  Wire.write("Hello");
                  Wire.endTransmission();
                  Serial.println("Sent: Hello");
                
                
                  delay(1000);
                
                
                  Wire.requestFrom(SLAVE_ADDRESS, 6);
                  while (Wire.available()) {
                    char c = Wire.read();
                    Serial.print(c);
                  }
                  Serial.println();
                
                
                  delay(2000);
                }
                
             

Master Code (XIAO RP2040):

The master starts by including the I2C library and sets the slave address to 0x08. Wire.begin() sets up the XIAO RP2040 as the master.

In the loop, it starts a transmission to the slave, sends the word "Hello", and ends the transmission. It also prints that message to the Serial Monitor. Then it waits a second and requests 6 bytes from the slave. If data is available, it reads and prints it one character at a time. A final delay gives time to view results before repeating the loop. The master keeps sending "Hello" and expects "World!" (6 bytes) in return.

Slave (Arduino Uno R3)


              #include 


                void setup() {
                  Wire.begin(0x08); // slave mode with address 0x08
                  Wire.onReceive(receiveEvent);
                  Wire.onRequest(requestEvent);
                  Serial.begin(9600);
                  Serial.println("I2C Slave Ready");
                }
                
                
                void loop() {
                  delay(100); // passive loop
                }
                
                
                void receiveEvent(int howMany) {
                  Serial.print("Received: ");
                  while (Wire.available()) {
                    char c = Wire.read();
                    Serial.print(c);
                  }
                  Serial.println();
                }
                
                
                void requestEvent() {
                  Wire.write("World!");
                }
                
             

Slave Code (Arduino Uno R3):

The slave uses Wire.begin(0x08) to set its address and listens for communication from the master. Wire.onReceive(receiveEvent) tells it what to do when it gets data. Wire.onRequest(requestEvent) tells it what to do when the master asks for data.

The main loop does nothing since all the work happens in the background. In receiveEvent(), it reads and prints the data sent from the master. In requestEvent(), it replies by sending "World!" (6 bytes), which is what the master asked for. So the slave simply waits, listens, and responds.

Result:

Everything worked as expected!

  • The master printed Sent: Hello and received World! from the slave.
  • The slave printed Received: Hello when the master sent data.
  • image

    On the left, my XIAO RP2040 board is acting as the master, printing "Sent: Hello" and "World!" in the Serial Monitor. On the right, the Arduino Uno R3 is working as the slave, displaying "Received: Hello" in its Serial Monitor.

    image

    View of both boards with I2C communication in action: The XIAO RP2040 (master) and Arduino Uno R3 (slave) successfully exchanging data over I2C.

  • The communication was fast, consistent, and reliable across multiple cycles.

For a bit of fun, I wanted to try sending an emoji since emojis are commonly used in modern messaging. I updated my code to send a smiling emoji 😂 from the master to the slave, and then had the master request a 6 bytes response from the slave, which I set to be the word "smile!"

image

The smiling emoji was successfully sent from the master on the left and received by the Arduino on the right, as shown in the image above.

Reflection and Takeaways

This week deepened my understanding of embedded communication protocols, especially UART and I2C. I learned the importance of carefully managing device addresses, byte lengths, and ensuring proper electrical connections particularly when working with boards that operate at different voltages.