14. Networking and communications


After seeing that I could use the Satshakits as the boards for this week, I decided to just use these. Originally, the Satshakit boards had one trace that you have to manually cut. Kai edited the board so that you wouldn’t have to manually cut it. I milled and soldered these boards. After going through this extensive process, I realized that this would not be enough for this week’s assignment. I would have to, at least, alter the board so that it was my own design. I did gain two Satshakits by doing this, but I effectively didn’t accomplish anything for this week

New Plan

Like Sarah Coston last year, I decided to go with a very simple method of communication between two boards. This is the tutorial she used, and I followed the same one. I knew that this tutorial would help me achieve the assignment for the week because, in the code that the tutorial gives, the master and slave boards enter the I2C address with a certain address name.

Board Design 1 (Fail)

I wanted to create really basic boards with an ATtiny44, FTDI / pin header for programming, and a pin header for the I2C communications. On the tutorial, it showed that the two ATmegas were only connected via two analog pins and ground. So, the pin header for the I2C communications will connect two analog pins and ground between the board.

Basically all of the pins on the ATtiny44 can be analog pins (see pinout below), so I just assigned the pins to PA2 and PA3.

Final schematic:

Final board:

Final soldered board:

Don’t download my Eagle files for this board, they don’t work.


After making the board, I tried to upload the master code found on the tutorial I referenced.

#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character


However, Arduino gave me this error:

'Serial' was not declared in this scope

I remembered that ATtinys don’t have the serial function that Arduino uses (during inputs week, I circumvented this fact by using Software Serial). So, I tried to fix the code to work with Software Serial. I referenced my inputs week software serial code to do so, and I ended up with this:

#include <Wire.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 9);

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  mySerial.begin(9600);  // start serial for output

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    mySerial.print(c);         // print the character


Arduino then gave me this error:

Error compiling for board ATtiny24/44/84.

I didn’t know what this meant. I didn’t know enough about what this code is actually doing with the Wire library to fix the code and use Software Serial.


I found out from an Arduino post that the ATtiny24/44/84s cannot use the Wire library. I found a library on Github with basically the same functionality as the standard Wire library. I added this to my Arduino libraries.

I altered the code so that, instead of using the wire, library, I included the library I just added. I removed the #include <Wire.h> and added:

#include <twi.h>
#include <TinyWire.h>

After that, I wasn’t experienced enough to mess around with the code to get it to work, so abandoned this board.

Board Design 2

I decided to take example from board Neil put on the assignment page. Neil explained it in the lecture, so I felt like I understood it better. Here’s the schematic (the hello.bus.45.bridge.py):

Here’s my final schematic:

Dr. Harris telling me that the programming pins (like SCK or MISO) can also be used for other things was one of the most critical pieces of information that I’ve learned in Fab Academy. This information is especially useful when using a microcontroller with fewer pins, like the ATtiny45.

I decided not to make different types of master and slave boards (for example, making one master and two slave boards) because of time, similarity between the two schematics, and functionality. Probably most relevantly, making two separate board designs is more time consuming than just making one board design. Also, Neil’s master and slave boards on the assignment page are basically the same board, except that slave boards don’t have FTDIs. I made three of the same boards, and the advantage to that was that any of the three could be used as the master. In the situation that my one master board broke or something, I wouldn’t be screwed. I could just grab another one of my boards and use that as the master.

Here’s my final board:

Final soldered board:

Download my Eagle files for this board



I used the code posted on the assignment page. I’ll explain the code:

#define node_id '0'

This line is critical; boards should have different node IDs so that they can identify each other and respond when called upon.

The main while loop has a lot going on. Here it is:

   while (1) {
      get_char(&serial_pins, serial_pin_in, &chr);
      if (chr == node_id) {
         output(serial_direction, serial_pin_out);
         static const char message[] PROGMEM = "node ";
         put_string(&serial_port, serial_pin_out, (PGM_P) message);
         put_char(&serial_port, serial_pin_out, chr);
         put_char(&serial_port, serial_pin_out, 10); // new line
         input(serial_direction, serial_pin_out);

The while loop enables the slave boards to listen to the master board’s transmissions. The slave board will flash() the onboard LED when it has received a signal.

Then, the if statement checks whether the character the master is sending out (which originally comes from the user typing into the Serial Monitor) matches the slave board’s node ID (established in the #define piece of code shown above). If the ID matches, it makes the common line (receiving line) an output (transmission line) and sends the ID back to the master board. Finally, the slave board will flash() its LED and return to having the common line as an input.

I put this code into Arduino. When I compiled it, Arduino ~got angry~ and said that PB4 “was not declared in this scope.” However, I know that PB4 is just C code for pin 4. This is where I transferred over to Powershell. I didn’t know why Arduino wasn’t accepting the C code even though Arduino is literally based off of C.

Download my Arduino code


Aside from working in Powershell in Week 5, I don’t have very much experience with it. When I thought that Arduino wasn’t working, I switched to Powershell. I really didn’t need to do this, since Arduino did eventually work for this code. I relearned how to send code through Powershell, though.

First, I took the code that Neil had on the assignment page and put it onto a Notepad document. By showing the extensions (circled in red), I edited the extension name. I made the extension “.c” on the Notepad document. I also put the Makefile that Neil also provided in the same folder. I went into the Makefile and changed the top line (where the name of the document is) to match “hello_bus_45”.

By showing the extensions on the file names within Finder, I edited the extensions on the files. I removed the Makefile’s extension, and its little icon became plain white.

Within Powershell, I navigated to the folder I wanted to use by using cd. Then, I used ls to show what was inside the folder I navigated to. I tried to make the .hex and .out files, but it didn’t fully work.

As shown underneath the ls, it made the .out file but not the .hex file.

I fixed this problem by editing the Makefile. I got rid of the ;/ indicated.

When I sent the make command after editing the Makefile, it successfully made the .hex and .out files. I included a listing of the files in the folder to demonstrate that everything is there.

I used the make program-usbtiny to upload the code via the USBtiny programmer that we have. It successfully uploaded for the first two boards (“Ace” and “Daryl”).

However, Powershell gave me errors when I tried to upload code to “Frunk” (like Frank but with a u, name suggested by Will). I followed the exact same steps that I had for the previous two boards and Frunk wasn’t different at all, so I don’t know what caused that.

Download my Powershell files

This includes the:

  • Makefile
  • C file
  • Hex file
  • Out file

for the board with the node ID “0”.


I headed to Arduino to use the Serial Monitor, even though I only had Ace and Daryl. When I typed in 0, 1, or 2, nothing happened in the Serial Monitor. Lights weren’t going off even as I sent messages through the Serial Monitor, so I knew something was wrong. I switched back to Arduino.

Back to Arduino

After Powershell also didn’t work, I decided to try to return to Arduino. I think, when I previously tried to use Arduino, my board just wasn’t plugged in and I was confused by the error it spit back. This time, when I tried to upload code, Arduino gave me the following error:

avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)
the selected serial port 
 does not exist or your board is not connected

“USBtiny device” refers to my programmer, not my board. So, I figured that the programmer wasn’t snug enough inside the USB port. I added more electrical tape underneath the programmer so that it fit better. This got rid of the problem, and the code uploaded!

Once the code was uploaded to the first board Ace, I uploaded the code to Daryl and Frunk. They all uploaded without problems. Then, I set up the boards in the manner shown below. The programmer and FTDI were connected to the master board, and the slave boards were connected by the bus to each other and the master board.

When I opened the Serial Monitor again and tried to send characters 0, 1, and 2, nothing happened again. I then realized that I didn’t change the node ID in the code before uploading it to the different boards. So, I essentially created 3 boards all with the same ID (0). I went back and made Daryl’s ID 1 and Frunk’s ID 2 by editing that #define statement. I left Ace’s ID as 0.

I opened up the Serial Monitor again, but I still wasn’t getting anything back when I sent 0, 1, and 2. This was because Neil connected his LED to the MOSI pin, or PB0. I connected my LED to MISO, or PB1. In Neil’s code, the following section deals with the LED:

#define led_port PORTB
#define led_direction DDRB
#define led_pin (1 << PB0)

I changed it to:

#define led_port PORTB
#define led_direction DDRB
#define led_pin (1 << PB1)

Changing this enabled my boards to successfully communicate!! However, I was only able to get two boards to communicate at a time. All boards worked two at a time, but never three. My first video shows Ace and Daryl working, and the second video shows Ace and Frunk. In both videos, notice the LED flashes as the boards communicate and respond to my Serial Monitor inputs.

Ace and Daryl (ID 0/1):

Ace and Frunk (ID 0/2):

Special thanks to Kai and Will this week for pointing out where I was making dumb errors and making my life more difficult for myself. Also, thank you again to Will for offering up the wonderful name “Frunk” for the board with ID 2.

Download all of my files from this week

Specific downloads are also included in their respective sections.

Group Assignment

For this week, we decided to connect Katie’s modified Satshakit and Kai’s LCD board. Katie’s board read incoming data from her force sensor, and the data was presented on Kai’s LCD.

I helped Kai get his LCD board working (his documentation is here) by providing expertise on Software Serial, which I learned a lot about and documented in Week 11. He used Software Serial for the RX function for the LCD board. We also used normal Serial communication for TX on Katie’s modified Satsha.

Here’s the code we used on Katie’s Satsha:

/* FSR simple testing sketch.

Connect one end of FSR to power, the other end to Analog 0.

Then connect one end of a 10K resistor from Analog 0 to ground

For more information see www.ladyada.net/learn/sensors/fsr.html */

int fsrPin = 4;     // the FSR and 10K pulldown are connected to a0

int fsrReading;     // the analog reading from the FSR resistor divider

void setup(void) {

  // We'll send debugging information via the Serial monitor



void loop(void) {

  fsrReading = analogRead(fsrPin); 

  Serial.print("Analog reading = ");

  Serial.print(fsrReading);     // the raw analog reading

  // We'll have a few threshholds, qualitatively determined

  if (fsrReading < 10) {

    Serial.println(" - No pressure");

  } else if (fsrReading < 200) {

    Serial.println(" - Light touch");

  } else if (fsrReading < 500) {

    Serial.println(" - Light squeeze");

  } else if (fsrReading < 800) {

    Serial.println(" - Medium squeeze");

  } else {

    Serial.println(" - Big squeeze");




The setup (also seen in the video):

Here are the boards communicating:

Download the group project code