14. Networking and communications¶
Assignment
This week's individual assignment was to design, build, and connect wired or wireless node(s) with network or bus addresses. The group assignment was to send a message between two projects. Group Work
Week 14 Individual Assignment
For this week's individual assignment, I decided to control an LED via Serial using one board to print to serial and another with an onboard LED to read serial from the other board and toggle the LED upon the reception of a pre-determined string.
As my input board that I designed during input week features RX and TX pins that allow for serial communication between boards, I would only need to design a single board for this week's assignment that would serve as the slave board, used for reading serial and turning on its onboard LED if a certain serial output was printed by the code on the input board. I booted up EAGLE, my circuitry design software of choice, and began designing a board featuring the ATTiny412 microcontroller, an LED, and all of the necessary components to ensure the longevity of the board.
I began by placing all of the components that I would need on my slave board in the schematic design section of EAGLE. I placed a 3x1 header pin array for uploading via UPDI, a 1 uF capacitor, a 399 Ohm resistor, an LED, a 2x1 header array for serial communication, and of course the ATTiny412 microcontroller.
Next, I used the 'net' tool to route wires between all of the components in the manner that they would appear in my final board design. After I made all of the necessary connections, I generated a .BRD file from this schematic and routed the traces to generate the file that would be used on our OtherMill Milling Machines to mill my board.
I decided to route the traces for this baord as close together as possible to see how small of a board I could make. I believe this is the smallest-footprint configuration possible with the ATTiny412 and all of the components on my board without using double-sided PCB.
I named all of the traces in the above .brd file using the pinout for the ATTiny412 microcontroller that I would be using on my slave board, allowing me to cross-reference my .BRD file when wiring my final board, allowing for the program and serial communication process to progress vastly more efficiently than if I did not label the traces within EAGLE. Next, I exported the files from EAGLE and milled them in our lab. I used the workflow that is included below for milling my board on the OtherMill milling machines that we have in our lab.
Images of final board
After milling and soldering the necessary components onto my board, I was left with the above piece of minuscule innovation.
After soldering my slave board, I decided to test it by uploading an example blink sketch to the board. As the 'blink' example generally uses the onboard LED pin of the Arduino Uno, pin 13, I simply changed this value to pin 3 and uploaded to code via UPDI by using the jtag2UPDI programmer in the Arduino IDE and selected the ATTiny412 from the boards available in the megaTinyCore boards library.
Next, I needed to write code for both my master and slave boards. For the master board I wrote a very simple program that sent the same message at intervals of 10 seconds.
void setup(){
Serial.begin(115200);
Serial.write("Beginning to write serial at set intervals");
}
void loop(){
Serial.println("Serial.print");
delay(10000);
}
For my slave board, I wrote a slightly more complicated script as I would need to actually read the data from serial and then toggle an LED if the print matched "Serial print". To do this, I simply set a string 'serial' to the string of a serial output by invoking the Serial.readString() function which simply takes the most recent serial output and makes it a string. Using this string, I compared it to the pre-set "password" String, "Serial print", and toggled the onboard LED on for 3-seconds if the String matched "Serial print". Otherwise, I simply turned the LED off. Finally, I added a short delay after each iteration of the main function in order to allow time for the next print statement to populate in serial.
const int ledPin = 3;
String serial = "";
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
Serial.write("ready to read via serial");
digitalWrite(ledPin, HIGH);
delay(1000);
}
void loop() {
serial = Serial.readString();
Serial.println(serial);
if(serial == "Serial print"){
digitalWrite(ledPin, HIGH);
delay(3000);
}
else{
digitalWrite(ledPin, LOW);
}
digitalWrite(ledPin, LOW);
delay(1000);
}
After plugging everything into my board and uploading the codes to both my input board and slave board, my LED began blinking as intended, concluding my work for this week's individual assignment.
Networking With Unique Board ID's
While my previous work allows me to commuincate via serial between a single master and a single slave board, the single TX/RX pins that I included on my original board design only allow for communication via two nodes of a network, meaning that I would never be able to communicate over a network of more than one slave board. As such, I would need to implement a way to communicate across a network of multiple boards, which is why I decided add a unique ID to each slave board's code that would be checked whenever serial is sent across my network of boards. In doing this, I would be able to address the LED on any board that was connected to a line of many of the same board. In order to do this, I would need to add more headers to my EAGLE design in order to allow for serial communication across my entire network of boards. I decided to test with only two of the same board in order to conserve material and save time, but this could be used with as many boards as possible in the future.
I began my work for this portion of this week's assignment by beginning to redesign my board schematic in EAGLE. Re-designing the schematic to add more TX/RX pins and more VCC/GND pins allowed me to connect a theoretically unlimited amount of node boards.
I made my first board from the redesigned board file that I designed and soldered the various components onto the board. After uploading a basic blink sketch to this board to verify that it would actually work, I made two more of the same board that would serve as slave boards when I attempted to network my boards together to satisfy the requirements for this week's assignment. The image below displays the IDE settings that I used for uploading my Arduino sketch to my board that features that jtag-programmable ATTiny412 microcontroller.
After milling, soldering, and testing two more of the same board that I described above, I was ready to begin networking these three boards. As described above, I wanted to give a unique hard-coded "ID" to each one of the slave boards in the network, which would allow each board to execute code only when a certain number was broadcast over serial by a slave board, effectively allowing for an infinite number of boards to be added to the network. The programming for this task was incredibly simple, as I really only needed two different basic Arduino sketches to allow my projects to funciton as intended. For the master board, I simply created a program that broadcast either a one or a two to serial every three seconds, which would trigger the light on the board with the respective ID as the one broadcast by the master board.
void setup(){
pinMode(3, OUTPUT);
digitalWrite(ledPin, HIGH);
Serial.begin(115200);
Serial.println("test");
}
// the loop function runs over and over again forever
void loop() {
Serial.println(random(1, 2));
delay(3500);
}
The code for the slave board was slightly more complicated, as I needed to await a serial message from the master board, interpret the response, and toggle the state of the LED's based on the received number. Still, this did not take very long to do.
const int ledPin = 3;
const String ID = "1";
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
}
void loop() {
if(Serial.readString().equals(ID)){
digitalWrite(ledPin, HIGH);
delay(3000);
digitalWrite(ledPin, LOW);
}
}
After uploading the above program to each of my two slave boards, obviously with the ID changed to "2" for the second board. I powered all of my boards to each other by using the extra headers that I added in EAGLE and provided each board with a common serial connection using the additional TX/RX headers that I added during the redesign phase of this portion of this week's work. After connecting everything, my network functioned properly on the first attempt!. I've included a short video of the project working as intended below.
Conclusion
This week's invidual assignmnet allowed me to further my abilities in EAGLE and provided me with a better understanding of how serial communication can work across two or more boards and exposed me to the many possible applications of this knowledge in my future endeavors. I plan on applying this newfound knowledge of serial communication in the development of my interface for my final project, as I will be communicating via serial between my input board and a Raspberry Pi using the same methods that I covered in my documentation for this week.
Week 14 Group Assignment
This week's group assignment was to communicate between two of our projects. To accomplish this, Fab academy students Drew Griggs and Teddy Warner, communicated via serial between the two boards that they designed for this week's assignment. A video of the group work is included below and the group site work for this week can be accessed here. For my contribution to this week's group work, I documented Drew and Teddy's work on the group site.
Download this week’s files! (20 kB)