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¶
- This weeks group assignment was to get two boards made by different group members to communicate.
- Our groups work was documented here: Networking and Commincations- Group assignment.
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¶
- For this assignemnt I decided to use my ATtiny board that I built for my final project, which you can see here: making my new board- output week, and using the oled screen and ultrasonic sensor I used here: input device week.
- The 2nd microcontroller I decided to use was the SEEED rp2040 with the vertical pins soldered on.
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
- The RP2040
- All wired up. Here’s what everything looks like connected together:
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.