Week 11: Networking & Communications
Objectives
These are the tasks for this week:
- Individual Assignment:
- design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s)
- Group Assignment:
- send a message between two projects
Timeline
Wednesday
- Class by Neil ✔
Thursday
- Class by Saheen ✔
- Setting up my website ✔
- Researching ideas
Friday
- Designing PCB
- Documentation
Saturday
- Designing PCB
- Final Project Work
Sunday
- Designing PCB
- Documentation
Monday
- PCB Production
- Documentation
Tuesday
- PCB Production
- Programming
- Documentation
- Local Review
Wednesday
- Programming
- Review by Neil
Group Assignment
Individual Assignment
Using the Attiny 412
For this week, I will be referencing Midhun's (FA2023) and Adrian Torress' documentation, but I will be modifying it for the Attiny 1614 chip for the nodes and a development board I made during Electronics Poduction Week as my master board. I wanted to use I2C and UART communication protocol

These is the pinmapping of Attiny1614

The datasheet for the Attiny can be seen here
Communication Protocols
Designing the Servo Driver Nodes
This week I wanted to design modular servo driver boards that can each use 4 servos.


Schematic
For this week I wanted to design boards that can accept both I2C and UART communication protocols

A tip by You can simply use Ctrl+C > Ctrl+V
to copy and paste pictures into KiCAD

For I2C communication I will be using Midhun's (FA2023) documentation, but adapting for Attiny 1614 (he used ATtiny 412) I tried improving on the original design by adding UART connections following the convention followed by FTDI to be able to debug the code if required.

I wanted to make connections for both I2C and UART to in my boards. Since we have 02x03 IDC connectors, based on instructor input, I tried designing a hybrid connector for both I2C and UART connections

This is how the completed schematic for my servo driver board looks like

PCB Designing
Since I want to make multiple copies, ideally the node PCB should be small. So, once I was able to get the connections right, I took a screenshot of the mock PCB for reference and proceeded to remove the trace,compress the space in between and add the traces again to make the PCB smaller

Since my board had to be designed in such a way that it is easily milled in a repeatable manner, I wanted to avoid using wired vias for connections that I used previously. This increased design time by a lot, and in the end I had to add a 0 ohm resistor to make one connection to GND. This is how my node PCB looks like once done.

Making the PCB

Milling
Just like previous weeks, I milled the boards. This included two nodes and one FTDI programer board to be able to program and debig the Attiny 1614.

But later I realized that the programmer board I had milled was wrong, and I had to discard it because of lack of time
Bill of Materials
Just like before, I used the interactive BOM plugin to create a rough draft of required components, which was then used to create the final BOM sheet

These are the BOM sheets for the two nodes (Node 1 has additional 4.99 K resistors for SDA and SCL pins of I2C connection, since I do not have them pulled up in the master board) and the new programmer desiigned by out instructor Saheen.


Soldering
These are how my node boards look like after soldering:

Verification
Using the Benchtop Power Supply


Using the Blink program
I did face problems while trying to burn a bootloader and program Node 1 using the older bootloader (which was since replaced by the new one I milled today), but I was able to fix it using some help from Akash
Now to make the connectors for wired connections. My instructor helped make a connector using 2 02x03 IDC connectors for each node and a 02x02 IDC connector (for I2C) and a 1x02 connector (for RX, TX) at the master board.


The picture shown below shows a diagram of how the connector was designed:

Programming
Program 1: Testing I2C Connection
I will be using this Xiao ESP32 C6 Development Board I made in Electronics Production Week
Master Board

Code for master board
To make it for my Xiao, I had replaced Wire.write("x is ");
in the original code with Wire.write((const uint8_t*)"x is ", 5);
to avoid this error:
Compilation error: invalid conversion from 'const char*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive]
For more explanation, click here.
First we plug the master board and prepare the IDE and upload the following code

// Wire Master Writer
// by Nicholas Zambetti < http://www.zambetti.com> and modified by Noel Joseph Saji 09/04/2022
// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
}
byte x = 0;
void loop() {
Wire.beginTransmission(8); // transmit to device #8
Wire.write((const uint8_t*)"x is ", 5); // sends five bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting
x++;
delay(500);
}
Code for Nodes
Then we plug in one of the nodes plugged with the programmer are the IDE. Then we set the following in tools in the Arduino IDE

Additionally we set the supply side voltage to 3.3 V if it does not work at 5V using the toggle switch in the programmer. Then we add the following code:
// Slave-reader
//
// Wire Slave Receiver
//
// by Nicholas Zambetti < http://www.zambetti.com> and modified by Saheen Palayi 06/06/2022
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose, but must
// acknowledge this project. Copyright is retained and
// must be preserved. The work is provided as is; no
// warranty is provided, and users accept all liability.
//
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006 by Nicholas Zambetti
// This example code is in the public domain.
//Added software serial for Attiny84
// #include <SoftwareSerial.h>
#include <Wire.h>
// Software serial rx,tx pins of Attiny84
const byte rxPin = 0;
const byte txPin = 1;
//declaring mySerial as SoftwareSerial
// SoftwareSerial mySerial(rxPin, txPin);
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
// Serial.println("hello");
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
Connecting Different Boards
I connected the boards as shown below using the connector I made previously

Program 2: Controlling LEDs using a Switch through I2C
Code for Master Board
#include <Wire.h>
#define LED D3
#define Switch D2
int Sval;
int counter = 0;
void setup() {
pinMode(Switch, INPUT);
pinMode(LED, OUTPUT);
Serial.begin(9600);
Wire.begin();
}
void loop() {
Sval=digitalRead(Switch);
if (Sval==1){
digitalWrite(LED, LOW);
}
else if (Sval == 0) {
digitalWrite(LED, HIGH); //Debugging LED on Master board lights up to confirm that switch has been pressed.
counter++;
Serial.print("counter: ");
Serial.println(counter);
int slaveAddress = (counter % 2 == 0) ? 8 : 9;
int ledState = (counter % 2 == 0) ? 0 : 1;
// Send command to toggle LED on the selected slave device
Wire.beginTransmission(slaveAddress);
Wire.write(ledState);
Wire.endTransmission();
delay(500);
}
else if (Sval==0){
}
delay(100);
Serial.println(Sval);
}
Conclusion
Mistakes & Solutions
- ProshPlay 3D model missing: If 3D models are not being updated even after attaching the correct link in 3D preview, try updating the footprint library and repeat the relinking process once again
- Not able to burn bootloader/upload program using SerialUPDI and Attiny1614: While trying to burn the bootloader, I got an error saying
Failed to burn bootloader
After consulting ChatGPT, I tried measuring voltage drop at the chip whch was measured at only 3V, even though at the supply side there was 5V drop. I tested the continuity at the GND line and found that I used a 1k resistor instead of a 0 ohm resistor, which I then replaced, but it still did not solve the problem bad solder joint in the 0 Ohm resistor which prevented current from flowing through it.
The next morning, Akash (FA2025) helped solve the problem by changing the supply voltage to 3.3 V (from 5V) using the toggle switch on the programmer, and setting the clock speed to 16 MHz (instead of default 20MHz). The problem with the voltage supply is caused by problems with the old programmer board (which will be replaced by the new one I will use today), but I am unaware of what it has to do with clock speed, but based on ChatGPT prompts, higher clock speeds require more precise timing and tighter voltage requirements, and due to errors that crept in while designing the boards (or the programmer), the chip is not stable enough to be communicated to at this clock speed fo 20MHz, so you need to slow it down.
The ChatGPT prompts I used have been listed below:
ChatGPT Prompt 1: Explain this error to me: "Traceback (most recent call last)..."Prompt 1: Explain this error to me: "Traceback (most recent call last)..."
This error message is a Python traceback, which shows the sequence of function calls that led to a crash in the program.
What is a Traceback?
A traceback is Python’s way of telling you where something went wrong. It shows the call stack: a list of all the functions that were running before the error occurred.
In your case:
The script
prog.py
from the megaTinyCore package tried to program an ATtiny chip using the UPDI interface. It failed with:pymcuprog.pymcuprog_errors.PymcuprogError: UPDI initialisation failed
This means the tool couldn’t establish a connection to the microcontroller using UPDI (Unified Program and Debug Interface).
Possible Causes:
- Wrong COM port selected
- Incorrect programmer or board setting
- Missing or incorrect 4.7kΩ pull-up resistor
- Target microcontroller not powered
- Communication speed too high
- Chip might have UPDI disabled (fuse change)
How to Fix It:
- Double-check your wiring and power supply
- Select the correct COM port and programmer (e.g., jtag2updi)
- Use a 4.7kΩ resistor between TX and UPDI
- Lower the UPDI baud rate
- Make sure the chip hasn’t had UPDI disabled
ChatGPT Prompt 2: What is a traceback?Prompt 2: What is a traceback?
A traceback is an error report generated by Python when something goes wrong during program execution.
Why it’s Called a "Traceback"
It “traces back” through the function calls that led to the error. This helps you understand where and why your code crashed.
What it Shows:
- File name and line number where the error occurred
- The exact function call hierarchy
- The type of error (e.g.,
ZeroDivisionError
,TypeError
, etc.)
Example:
Traceback (most recent call last): File "main.py", line 10, in
divide() File "main.py", line 5, in divide result = 1 / 0 ZeroDivisionError: division by zero This example shows a division by zero inside a function called by the main program. The traceback tells you exactly where the problem occurred.
ChatGPT Prompt 3: Why did changing clock speed and voltage fix my UPDI error?Prompt 3: Why did changing clock speed and voltage fix my UPDI error?
When you reduced the clock speed and changed the supply voltage, you made your ATtiny microcontroller more stable during UPDI communication.
Why Lower Clock Speed Helped:
- High speeds (like 20 MHz) make the chip more sensitive to voltage dips and noise.
- Lowering to 16 MHz reduces timing errors and makes UPDI sync more reliable.
Why 3.3V Supply Helped:
- Many ATtiny chips are optimized for 3.3V operation.
- If your UPDI programmer is 3.3V and the chip runs at 5V, you get voltage mismatch.
- 3.3V keeps logic levels compatible, reducing chances of failed communication.
Summary:
- ✅ Lower clock = more stability
- ✅ 3.3V supply = better compatibility with your UPDI programmer
- ✅ Easier for programmer to sync and upload code without errors
- Compilation error while using
Wire.write() for I2C connection
:Acccording to ChatGPT you cannot directly use strings inWire.write()
for I2C connection Wire.write(uint8_t)
→ expects a single byte (like a number or a character)Wire.write(const uint8_t*, size_t)
→ used to send strings or byte arrays
Prompt 1: C:\Users\sajin\AppData\Local\Temp\.arduinoIDE-unsaved202539-6036-1s2r5bv.0ytn\sketch_apr9b\sketch_apr9b.ino: In function 'void loop()': C:\Users\sajin\AppData\Local\Temp\.arduinoIDE-unsaved202539-6036-1s2r5bv.0ytn\sketch_apr9b\sketch_apr9b.ino:23:14: error: invalid conversion from 'const char*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive] 23 | Wire.write("x is "); // sends five bytes | ^~~~~~~ | | | const char* In file included from C:\Users\sajin\AppData\Local\Temp\.arduinoIDE-unsaved202539-6036-1s2r5bv.0ytn\sketch_apr9b\sketch_apr9b.ino:13: C:\Users\sajin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.2.0\libraries\Wire\src/Wire.h:135:16: note: initializing argument 1 of 'virtual size_t TwoWire::write(uint8_t)' 135 | size_t write(uint8_t) override; | ^~~~~~~ exit status 1 Compilation error: invalid conversion from 'const char*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive]
The error you're seeing is caused by trying to pass a string literal (a const char*
) to the version of Wire.write()
that only accepts a single byte (uint8_t
). The function you're calling doesn't match any overloaded version that takes a string.
✅ How to Fix It:
Use the correct overloaded version of Wire.write()
that accepts a byte array or string:
Wire.write((const uint8_t*)"x is ", 5);
Or, to make it dynamic and safe:
const char* message = "x is ";
Wire.write((const uint8_t*)message, strlen(message));
This tells the compiler explicitly that you're sending a pointer to a string and how many bytes to write.
🔍 Why It Matters:
Design Files
Click here to access the design files