Skip to content

13. NETWORKING & COMMUNICATION - done. to be marked

This weeks task was to connect two or more microprocessors together and get them to communicate.

Group work

Individual assignment

  • This week individual assignment is to design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s).

parts

my board

  • The 2nd microcontroller I decided to use was the SEEED rp2040 with the vertical pins soldered on.

rp2040 wired up

Wiring it up

  • Connecting the 2 boards together involved:
  • Connecting the RX pin from board 1 to the TX pin of board 2.
  • Connecting the TX pin from board 1 to the RX pin of board 2.
  • Connecting the Vcc pin from board 1 to the 5V of board 2 so that either board could power the other (after one was disconnected from a computer).
  • Connecting the GND pin from board 1 to the 5V of board 2 so that either board could power the other.
------------     -------------
|       RX |-----| TX        |
|       TX |-----| RX        |
|      Vcc |-----| 5V        |
|      GND |-----| GND       |
|          |     |           |
|          |     |           |
|  board1  |     |    board2 |
------------     -------------
  • my ATtiny board

ATtiny wired attiny1614

  • The RP2040

RP2040 wired rp2040 pinouts

  • All wired up. Here’s what everything looks like connected together:

RP2040 wired

Programming

  • I programmed the boards using Arduino IDE.

  • I used a seperate computer for each microcontroller (a desktop and a laptop). This was to avoid potential conflicts.

  • I had a different program for each microcontroller:

  • Program 1 (Attiny board):

  • Constantly measures the the ultrasonic reading and displays it on OLED screen.
  • When it recieves a MSG, reads the MSG and displays it on OLED screen and then send a confirmation MSG and the ultrasonic reading for the exact moment back.
  • ATtiny Program
/*
James Khan Fab Academy networking and communication week week.
https://fabacademy.org/2021/labs/vancouver/students/james-khan/assignments/week13/

Used the code I developed for my input week as a starting point and modified for communication.
https://fabacademy.org/2021/labs/vancouver/students/james-khan/assignments/week11/

This program is for my selfmade Attiny14 board and has an ultrasonic sensor attached to it 
and communicates with another board (an RP2040, with a different program).

This program constantly measures the distance from the ultrasonic sensor.
When it gets sent a message on its RX data pin, it displays that message
on the attached OLED screen as well. It then sends back confirmation on the TX pin along with the
measured distance.
*/

#include <Wire.h>             // for OLED
#include <Adafruit_GFX.h>     // for OLED
#include <Adafruit_SSD1306.h> // for OLED

const int SCREEN_WIDTH = 128; // OLED display width, in pixels
const int SCREEN_HEIGHT = 64; // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // for OLED

// DEfine variables Ultrasonic
#define ECHO_PIN 9
#define TRIG_PIN 8

String incomingString ; //to hold incomming serial data.

void setup() {

  Serial.begin(115200); //

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed")); // genetare arror msg if oled can't initialize
    while(true);
  }

  // for ultrasonic setup
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

  //read and calculate the distance from ultrasonic sensor. 
long readDistanceCM() {  // changed it from the regular float because of memory issues with serial.print
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  unsigned long duration = pulseIn(ECHO_PIN, HIGH);  //corrects possible negative interperetation if measurement too big
  return duration * 0.034 / 2;
}

void loop() {

  long distance = readDistanceCM(); // changed it from the regular float because of memory issues using serial.print
  delay(200); 

  if (Serial.available()) {         
      incomingString=Serial.readString(); // If anything comes in Serial save it to variable
      Serial.print("got it: ");           // send confirmation back to sender with string sent
      Serial.println(incomingString);
      Serial.print("dist: "); 
      Serial.println(distance);           // send the distance measured from attiny's ultrasonic sensor to serial 
      delay(100);
  }

  display.clearDisplay();               // oled clear
  display.setTextSize(2);               // oled setup
    // text size of 2 only gives us grid size of 10 wide by 4 tall characters.
    // but a text size of 1 is pretty tiny to show up well on a video, but gives allot more characters.
    // the below prompts are minimal to keep the bigger size font.
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("d:");                // static display
  display.println(distance);          // display distance
  display.println("incoming:");       // static display
  display.println(incomingString);    // display string from serial input
  display.display();
  display.println("\n");
  delay(200);

}
  • Program 2 (RP2040):
  • When it receives a MSG on serial (from the computer’s serial monitor), reads that MSG and sends it on serial1 (to the ATtiny board).
  • When it recievs a MSG on serial1 (from ATtiny), reads that MSG and sends it to serial (computer).
  • RP2040 Program
/*
James Khan Fab Academy networking and communication week week.
https://fabacademy.org/2021/labs/vancouver/students/james-khan/assignments/week13/

Used the code I developed for my input week as a starting point and modified for communication.
https://fabacademy.org/2021/labs/vancouver/students/james-khan/assignments/week11/

This program is for an SEEED RP2040 board 
and communicates with my self made ATtiny board (with a different program).

This program constantly listens for a message on two seperate serial ports
Serial is the regular connection to the computer via USB
SErial1 is the UART connection to my second board

When a message comes in on either of the serial ports it 
sends the message on the other serial port.
*/

void setup() {
  delay(2000);
  Serial.begin(115200);               // set's up the connection speed, needs to match the other program
  delay(200);
  Serial1.begin(115200, SERIAL_8N1);  //defines a unique Serial addresses:default Serial is USB/computer, Serial1 is RX/TX or UART
  Serial.println("\n--- UART communication with XIAO RP2040 ---");
  Serial.println("-------------------------------------------------------");
}

void loop() {
  if (Serial.available()) {         // If I send anything from the computer's serial monitor
    Serial1.write(Serial.read());   // then rean it and send it over UART to other device   
       // read it and send it out Serial1 (pins 0 & 1)
    digitalWrite(29, HIGH);
    delay(50);
    digitalWrite(29, LOW);          // flashes LED to indicate received sent
  }

  if (Serial1.available()) {        // If anything comes in Serial1 (my connected second board)
    Serial.write(Serial1.read());   // then send it to the computer's serial monitor
    digitalWrite(29, HIGH);
    delay(50);
    digitalWrite(29, LOW);          // flashes LED to indicate received message
  }
}

Running the programs

  • After writing the programs to each board from their connected computers, I disconnected the Attiny from its desktop while leaving the RP2040 connected to its laptop.

  • I did this so that it could genuinly be demonstrated that they were talking to each other and not being faked with a connection to a second computer.

  • I then used the serial monitor on the laptop to send MSGs to the RP2040 and recorded the results.

Lessons learnt

  • the ATtiny’s onboard memory fills up really fast. Even if you think your code is quite small, when compiling from your C++ program, it can actually get big quickly depending on the variables, libraries and profecures and functions you use.
  • I kept getting a memory full error when making small tweaks to my ATtiny program.
  • I eventually fixed it by changing the readDistanceCM function to use “long integer” variables instead of “float” variables. It seems the assembly code generated or memory allocation needed for using floating point variables was much bigger than just integers.

  • The UART protocall is a very old one, but still works really well.


Last update: May 14, 2025