Skip to content

14. Networking and communications

Throughout this week, I explored UART and more I2C connections, ultimately creating a xiao RP2040 bridge to ATtiny1614 node system.

Assignment

group assignment:

  • send a message between two projects

individual assignment:

  • design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s)

UART: The Universal Asynchronous Receiver/Transmitter

UART defines a set of rules for exchanging serial data between two or more devices, or in this case, microcontrollers. Using only three signals, Tx (transmitted serial data), Rx (received serial data), and ground, it provides a robust way for users to access several microcontrollers at once and improves the processing speed overall.

I had originally intended to use UART in my final project to communicate between an xiao RP2040 and an attiny1614, but after repeated issues with UPDI initialization and lack of understanding of how UART worked, I decided to go back to a fundamental level and attempt UART on a breadboard with two Xiao RP2040s. For some guidance, I looked towards previous grad’s documentation. I ended up finding Ryan Kim’s documentation, who similarly experimented with xiao RP2040s and raspberry pi picos. After reading his documentation, I felt like I better grasped the basics of the protocol, including defining

In order to use the protocol, I needed to first create the following connections between the RX, TX, and GND pins:

         Sender                          Receiver

 +---------------------+          +---------------------+  
 |        XIAO RP      |          | XIAO RP2040         |
 |         2040        |          |                     |  
 |                  TX +----------+ RX                  |
 |                     |          |                     |    
 |                  RX +----------+ TX                  |     
 |                     |          |                     |      
 |                  GND +----------+ GND                |     
 |                     |          |                     |
 +---------------------+          +---------------------+

                     UART Prototcol         

Below is my setup with the two xiao RP2040s. I included a resistor and an LED as well to serve as an active indicator of whether the serials were truly communicating with each other:

I plugged each xiao rp2040 into different computers, before selectingRaspberry pi as my board in Arduino IDE and uploading the following programs (modified). Note that these two programs follow a similar format, and there isn’t necessarily a distinct sender/receiver, as the boards are communicating mutually with each other.

Board 1 Code:

void setup() {
  delay(2000);
  Serial.begin(9600); // initializes Serial
  pinMode(29, OUTPUT); //defines pin for LED

  delay(200);
  Serial1.begin(9600, SERIAL_8N1);  //SERIAL_8N1 is the default available serial port; Serial1.begin() addresses 1 out of 2 devices involved in the protocol
  Serial.println("\n--- UART communication with XIAO RP2040 ---");
  Serial.println("SERIAL1_TX: " + String(SERIAL1_TX));
  Serial.println("SERIAL1_RX: " + String(SERIAL1_RX));
  Serial.println("-------------------------------------------------------");
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial (USB),
    Serial1.write(Serial.read()); 
    digitalWrite(29, HIGH);
    delay(500);
    digitalWrite(29, LOW);   // read it and light up the LED accordingly
  }

  if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
    char serial1_In = Serial1.read();
    Serial.write(Serial1.read());
    digitalWrite(29, HIGH);
    delay(500);
    digitalWrite(29, LOW);
  }
}

Board 2 Code:

void setup() {
  pinMode(29, OUTPUT);
  delay(2000);
  Serial.begin(9600);
  delay(200);
  Serial1.begin(9600, SERIAL_8N1);  //defines a unique Serial and addresses 1 out of 2 devices involved in the protocol
  Serial.println("\n--- UART communication with XIAO RP2040 ---");
  Serial.println("SERIAL1_TX: " + String(SERIAL1_TX));
  Serial.println("SERIAL1_RX: " + String(SERIAL1_RX));
  Serial.println("-------------------------------------------------------");
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial (USB),
    Serial1.write(Serial.read());
       // read it and send it out Serial1 (pins 0 & 1)
    digitalWrite(29, HIGH);
    delay(500);
    digitalWrite(29, LOW);
  }

  if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
    Serial.write(Serial1.read());
    digitalWrite(29, HIGH);
    delay(500);
    digitalWrite(29, LOW);   // flashes LED to indicate received message
  }
}

For more information regarding serial ports, visit this website.

Opening the serial monitors on both computers, I could send and receive messages now from both devices! At the same time, the LEDs turn on as an indicator. Here is what it looks like working:

Although this system worked pretty well and is deemed the “easiest form of networking,” I didn’t find the process very intuitive, and I struggled quite a bit to understand it conceptually. Additionally, this protocol simply isn’t as effective as others, such as I2C, when incorporating more than one node at a time.

I2C: Inter-Integrate Circuit

Resources:

INSERT BREADBoARD ADVENTURES

Creating a Pomo-Master and Node Board

Designing in KiCad

While designing my networking board for this assignment, I chose to create an all-in-one board, including SDA/SCL pins for an I2C connection, as well as RX/TX pins for UART (though for this week, I’ll be primarily using I2C). I wanted these boards to be used for my final project as well, so I tried to incoporate other useful aspects, such as separate I2C pins for a time-of-flight sensor, a button, and LEDS for charlieplexing (refer to Electronics Design). I ultimately created a master with the xiao RP2040 and a node with the ATtiny1614. After a few tries of routing these boards, here is what I came with:

Pomo-master Board:

For the edge cuts of my board, I wanted to do a design that related to my final project, similar to how Teddy Warner created aqua-ponics related boards. Thus, I searched online for a .svg of a tomato, since tomatos are often associated with the pomodoro technique. I scaled this file up in Fusion360, before returning to Kicad and selecting File>Import>Graphics. To create the outside shape as well as the interior details, I created two .dxf files and subsequently inserted them onto the edge cut and silkscreen layers.

Disclosure: this is a tomato, not a pomegranate.

ATtiny1614 Board:

This was my experimental board, so I wanted to include RX/TX pins, I2C communication pins, I2C pins for sensors, charlieplexing, phototransistors, etc. Here is what the schematic looked like:

Although the ideas behind the board were fun in hindsight, routing it was truly hectic. I ended up using two different trace widths, between 0.5 mm and 0.3 mm, for many of the traces that ran below components.

Milling and Iterations

In terms of milling, I followed the same process as previous weeks–plotting/saving my KiCad files as Gerbers, importing into the Bantam software, and configring z-axis and tool settings. The only difference this time was the tool I used for the tiny traces between the ATtiny pads, in which I selected the .005” engraving bit.

A few times during the outline, I noticed that the bit was plunging into the spoilboard and producing a loud noise. I fixed this later on by slightly increasing the z-material offset until the sound was reduced (though I did break a bit the first time this happened..).

Afterwards, I soldered on the following components:

Pomo-master Board:

Component Quantity
Seeed Xiao RP2040 1
SMD red LED 2
4-pin SMT vertical male header (FTDI) 1
3-pin SMT vertical male header (FTDI) 1
499 1206 SMD resistor 2
970 nF capacitor (~1uF) 1
Milled PCB 1
Tactile push button 1

ATtiny1614 Board:

Component Quantity
ATtiny1614 1
SMD red LED 2
SMD green LED 2
SMD orange LED 2
SMD white LED 1
4-pin SMT vertical male header (FTDI) 1
3-pin SMT vertical male header (FTDI) 1
499 1206 SMD resistor 4
970 nF capacitor (~1uF) 1
Milled PCB 1
2x04 SMT vertical male header 2
4.99 k 1206 SMD resistor 3
SMD visible and IR phototransistor 1

Programming The Boards Individually

Although soldering and milling had brought few setbacks, the programming portion was quite difficult–even when programming the boards individually. Not only did I receive the UPDI initialization failed each time I uploaded a program through the QuenTorres board, but I had also gained a new error, RSP_NO_TARGET_POWER. At the same time, I managed to rip the copper pads off my two iterations I had created at that time, meaning I would have to start over from scratch :(.

RIP to my record of not ripping traces..

While I was producing the third iteration, Teddy Warner visited Charlotte Latin and talked a bit about his pitch and new company. I eventually let him choose (bless) the ATtiny1614 on my new board. This board turned out way better than previous versions, and it was able to properly receive code through JTAG. However, I was struggling to get my charlieplexing to fully work. For some reason, only 2 out of the 6 LEDs were turning on! After an hour of troubleshooting, I realized that the soldering between the charlieplexing 1 pin and the resistor wasn’t solid, so I went back in and fixed the connection.

For reference, I used the same code as I did in Electronics Design week, only changing the charlieplexing pins to 10, 9, and 8 based on the ATtiny1614 pinout.

INSERT ATTINY PINOUT HEREE

Thank you to Teddy Warner for choosing the ATtiny; if you’re reading this, you should check out his new company and product, Tone. 👍

Below are the final boards side-by-side:

After milling the ATtiny board three times total, here are all the iterations laid out:


Last update: May 9, 2024