13. Networking¶
Group Assigment¶
This week’s group assignment was to send a message between group projects. To do this, Angelina Yang and I just connected our individual projects for this week. The documentation for this week’s group assignment can be found here.
Assignment¶
This week’s individual assignment was to connect wired or wireless nodes with network or bus addresses. I attempted a couple different ways of using I2C.
I2C Between 2 ATtiny412s¶
For a long time, I tried to get I2C between 2 ATtiny412s to work. Because of my original input in inputs week, I had some experience with I2C, but still did not really understand it. Some of the parts of the proccess involved in these attempts is documented in my Week 11 (Inputs Week) Documentation. I wanted to use the same boards I used for my input for my I2C networking between boards. After I made the two boards discussed in my Week 12 documentation, I realized that I needed a pull-up resisitor on both SCL and SDA for I2C to work properly. Because of this, I designed and milled three of a new board. This is the design:
I2C Between ATtiny412 and Seeed Xiao RP2040¶
Eventually, I decided I should try to get I2C working between an ATtiny412 and a RP2040 as an RP2040 can connect to Serial Monitor, which allows for a much easier debugging process, as it is easier to tell what is working and what is not. I began by creating a board for both the ATtiny412 and the RP2040. I had the ATtiny412 board also have headers allowing it to simultaneously connect to a step response, as I’ve decided I want to utilize this in my final project. Here are the two boards I made:
#include // library for I2C
#define SLAVE_ADDRESS 8 // address assigned to slave in its code upon Wire.begin initialization
void setup() {
Wire.begin(); // join i2c bus (my code worked when I removed master's address but idk if you can have it)
pinMode(D8, OUTPUT); // initalizing LED output (not used in this code so not revelant)
}
void loop() {
Wire.beginTransmission(SLAVE_ADDRESS); // transmit to device
Wire.write(1); // write 1
Wire.endTransmission(); // stop transmitting
delay(500); // delay in between transmissions
Wire.beginTransmission(SLAVE_ADDRESS); // transmit to device
Wire.write(0); // write 0
Wire.endTransmission(); // stop transmitting
delay(1000); // delay in between transmissions
}
And this was my code for the ATtiny412 as a slave:
int d1=0;
int LED=4;
#include
void setup() {
Wire.begin(8); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
pinMode(LED, OUTPUT);
Wire.onReceive(recieveEvent);
}
void loop() {
if (d1==1) {
digitalWrite(LED, HIGH);
}
else {
digitalWrite(LED, LOW);
}
}
void recieveEvent(int howMany)
{
while (Wire.available())
{
d1 = Wire.read();
}
}
And this is the video of I2C finally working:
My code is very similar to Adrian Torres’, as I wanted to deviate from what is sure to work as little as possible. However, after this I began incorporating different elements into the code. I began by getting the ATtiny412 to send messages to the RP2040. This took a little time, but I eventually arrived at this code for the RP2040 as a slave:
#include
#define SLAVE_ADDRESS 8
#define Master_address 9
int c = 0;
void setup() {
Wire.begin(9);
Serial.begin(9600);
Wire.onReceive(recieveEvent);
}
void loop() {
}
void recieveEvent(int howMany)
{
while (Wire.available())
{
c = Wire.read();
Serial.println(c);
}
}
And this was the code for the ATtiny412 as a master:
int d1=0;
int LED=4;
#define Master_address 9
#define SLAVE_ADDRESS 8
#include
void setup() {
Wire.begin();
pinMode(LED, OUTPUT);
}
void loop() {
Wire.beginTransmission(Master_address);
Wire.write(1);
Wire.endTransmission();
delay(500);
Wire.beginTransmission(Master_address);
Wire.write(0);
Wire.endTransmission();
delay(1000);
}
Both are very similar to how they were with the RP2040 as the master, except I wanted to Serial print the message when it was received from the ATtiny412, so that is why I included the Serial.println(c)
. This way it is much easier to see what is going on. Here is a video of the RP2040 receiving 1s and 0s through I2C and printing them to the Serial monitor on Arduino.
Networking with Input¶
I then attached my Flubben II board (made in Inputs Week) to the ATtiny412 board so that I could measure inputs from this step response and then communicate them to the RP2040. After a lot of failed attempts, I got the input working and the boards to communicate simultaneously, however, the readings the Serial Monitor showed were very different than the actual readings. Here is the code I used for the RP2040 (basically the same as above):
#include
int c = 0;
#define SLAVE_ADDRESS 8
#define Master_address 9
#include
void setup() {
Serial.begin(9600);
Wire.begin(9); // join i2c bus (address optional for master)
Wire.onReceive(recieveEvent);
}
void loop() {
}
void recieveEvent(int howMany)
{
while (Wire.available()) {
c=Wire.read();
Serial.print(c);
}
Serial.println();
}
And this is the code I used for the ATtiny412, integrating the input code into the I2C code:
int LED=4;
#define rxpin 1 // RX pin on ATtiny412
#define txpin 0 // TX pin on ATtiny412
#define settle 100 // Time for voltage to settle
#define samples 100 // How many samples of analogRead it takes in given time
#define Master_address 9
#define SLAVE_ADDRESS 8
#include
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
pinMode(LED, OUTPUT);
pinMode(txpin, OUTPUT); // Initializing the TX pin as OUTPUT (for sending signals through TX and recieving and measuring those same signals and their strengths through RX)
}
void loop() {
long int avg = average(); // Takes one sample of average() function
instantCheck();
Wire.beginTransmission(Master_address); // transmit to device #4
Wire.write(average());
Wire.endTransmission(); // stop transmitting
delay(1000);
}
long int average() { // Function to find the average change in signal
long int up, down, avg;
avg = 0; // Initializing avg as 0
noInterrupts(); // Disables all other activities
for (int i = 0; i < samples; i++) { // For loop which loops (samples) times
digitalWrite(txpin, HIGH); // Sends signal through TX pin
up = analogRead(rxpin); // Recieves signal through RX pin
delayMicroseconds(settle); // Delays for 100 microseconds so that signal can level out
digitalWrite(txpin, LOW); // Takes away signal from TX
down = analogRead(rxpin); // Reads RX pin after removing signal
delayMicroseconds(settle); // Delays again so that signal can level out
avg += up - down; // Measuring capacitance of system as in theory avg should be 0 if copper plates were connected
}
interrupts(); // Allows other activites to occur again
return avg; // Returns the avg value
}
void instantCheck() { // Function to simply check functionality of the program
long int avg = average(); // Takes one sample of average() function
if (avg > 7080 ) { // If capacitance over
digitalWrite(4, LOW);
}
else {
digitalWrite(4, HIGH);
}
}
And here is a video of the readings I was seeing on the Serial Monitor:
Generally, the readings appeared somewhat random between about -100 and 100, although when I put my hand really close or touched the Flubben II board it would generally read a high value negative number for about two readings before reverting back to normal. Overall, there was no significant enough correlation or pattern from the readings that I could deduce. I know this is an issue in the I2C connection because, when I fine-tuned the conditional argument if (avg>7080)
to 7080 (it often changes depending on the surrondings), the LED would consistently turn on as I moved my hand close to the board, and turn off otherwise, so the avg
value had to be consistenly around 7080 +-20-50. To try to troubleshoot, I attempted to send the message “Hello” from the ATtiny412 to the RP2040 through I2C. When I tried to print this on the Serial Monitor, it came up with all sorts of symbols and plain squares (meaning it did not understand the message), confirming my suspicion that something was wrong with the I2C. However, for now I will be happy that I got I2C working and an input connected to it.
Week Reflection¶
This week was a long struggle, but eventually saw a satisfying outcome. Although I never got I2C working between two ATtiny412s, I got working what I will likely use in my final project and learned a lot about I2C and other methods of networking in the process. Now that I am confident in my capabilities revolving around the designing and creation of applicable boards, in the future I will try to focus my time more on the software side of things, where I could learn a whole lot more (and likely more applicable skills), instead of overloading my time with monotonous board development.
File Downloads¶
You can download the files used in the processes included in this documentation here.