Skip to content

Network and Communication:

link to Fab Academy class links

My notes on the Networking and Communications lecture

I found this class to be intimidating, but it got me thinking about using networking to solve some real world problems in my own life. - can I make a wifi network connection to easily control my kid's access to the internet? - I believe I can do this by making them use a designated wifi connection, but it would be nice to press a button to turn it on and off - can I create a communication device that my kids can use to reach me without internet or cellphones? - I know this is a radio, but can I make a less embarrassing one? "Mom's technically impressive named walkie-talkie" - Can I fix / make my own remote and receiver to make my ceiling faucet work? - I just installed a ceiling mounted faucet, and the remote is ... not good. I have been sent 5, only 2 have worked, and the first working one stopped working after overheating. The current one only works when plugged in. I have also had the receiver part replaced.
Kohler Purist Suspend

> when looking up this link, I just found out that my faucet has been discontinued.  I am not surprised.

Group assignment:

  • Send a message between two projects
  • Document your work to the group work page and reflect on your individual page what you learned

Click here to see our group page

Our group used an ESP32-C3 serial printing onto Camile's computer to create a wifi server for our group to connect to.

I installed a program from the examples in Arduino IDE with the ssid and password Camile provided.

opening example file

The code is linked here

I tried to connect my RP2040 to it first, but could not get it to connect.

I switched to my ESP32-S3, and was connecting, but not connected.

not connecting

I attached the antenna to my ESP32-S3, and it connected:

connected

I went to my computer's wifi, and selected Camile's server, yourAP:

selecting wifi

I also opened the IP address in my webbroser, and was able to turn on and off a light. The LED commands were reversed, but it worked.

Angela and Kim were also able to make the LED blink from their own computers, and Camile could see when we joined her server.

Individual assignment:

  • design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output device(s)

Key things to remember / check (learned the hard way):

  1. close the serial monitor! Use this code in terminal if you can not find any open serial monitors. ```python{ kill -9 $(lsof | grep usbmodem | awk '{print $2}'
    2. on ESPs press boot + reset, release reset then boot to load a new program.  2 solid sticks are helpful to push the buttons.
    3. check the pinout diagrams - AI gets these wrong, and you will get them wrong, and they will magically change on you
    4. check that you are loading to the correct board.  It show in the dropdown menu at the top of the Arduino IDE sketch window.
    5. use a large delay time to be able ot see your outputs, delay(500)
        - even better to use a variable for the delay! 
    6. use the multimeter to check voltages!
    7. keep a 3v button battery handy to check your LEDs, you may have blown them up
    8. This code will show you the names of any nodes attached to the master.  Reset multiple times to see which names consistantly reapear.  The other ones are feedback on the line.
    
    ```cpp
      #include <Wire.h>                                                                              
      void setup() {                                                                                 
        Serial.begin(115200);                                                                        
        Wire.begin();                                                                                
        delay(1000);                                                                                 
        Serial.println("Scanning...");                                                               
        for (uint8_t addr = 1; addr < 127; addr++) {                                                 
          Wire.beginTransmission(addr);                                                              
          if (Wire.endTransmission() == 0) {                                                         
            Serial.print("Found device at 0x");                                                      
            Serial.println(addr, HEX);                                                            
          }                                                                                          
        }                                                                                         
        Serial.println("Done.");                                                                  
      }                                                                                              
      void loop() {}
    

I used the Expert Network Map to see where I should look for help this week.

Expert map

Only 2 dots, Adrian Torres, and Quentin Bolsee. I am not surprised.

Inspirational YouTube tutorial on building an Xiao ESP32-S3 Sense Spy Cam - github repo for valleytechsolutions / Xiao-ESP32-S3-Spy-Cam

I think I may have been overthinking networking. It seems like something very complicated with special pins; UART, TX / RX, I2C, SPI, but I think it boils down to input and output devices linked to microcontrollers.

I used Claude.ai to explain networking so that I could ask clarifying questions. See Claude explaining networking here

So a microcontroller would recieve a signal that triggers an action, and / or a microcontroller would send a signal. Below is a visual representation of my understanding of networking. The "master" is a teacher, and the "slaves" are the students.

networking _class_ drawing

This feels very similar to what I have already done in week 10. I sent a signal to an output device, the speaker, based on the input received from my photosensor. I guess the difference is that the TX, and SCL pins send signal regularly. I can replicate this by synchronizing the signals to be sent and received. Which is how the Attiny older models work.

I would like to use an IR LED and a receiver to send a signal, but I feel this would be more of a switch than networking.

It was explained to me during open time, that the communications part of network and communications is inputs and outputs, but the networking part is speaking to multiple machines.

My plan of action is:

  1. make 3 nodes that have an input and output, 1 master and 2 slaves. All with have serial print for testing individually. The output will help me determine if the nodes are working while not directly communicating to the serial monitor.

  2. test each node on its own to see if their code is working

  3. connect through UART connections to the master, and read node sensor readings

Stop, and spend time with my family. Should I have more time these steps are bonus:

  1. send a signal that turns on and / or off the output devices on the slave nodes

  2. connect through I2C

  3. connect through wireless

  4. connect through bluetooth

I need to use what I have available, the XIAO ESP32-C6, the ATtiny412, the XIAO RP2040, and possibly the XIAO ESP32-S3 sense.

I have not yet used the Attiny or the ESP32-S3 sense.
The datasheet and other helpful information on the ESP32_S3 can be found at wiki.seedstudio.com

ESP32-S3 pinout

Click here for the ATtiny412 datasheet

ATtiny412 pinout diagram:

ATtiny412 pinout

ATtiny412 with breatkout board: ATtiny412 pinout on breakout board

Attempt 1:

Step 1:

I will need to install the program on the ATtiny, which does not have a bootloader. So I hooked up my ESP32-C6 to the ATtiny in this configuration, then connected it to my computer.

ATtiny to ESP for programing

I had to install the board manager for the ATtiny to my Arduino IDE by going into settings, which opens a preference window preferences

In the "Additional boards manager URLs:" I added:

http://drazzy.com/package_drazzy.com_index.json

In tools -> Board -> board manager I chose megaTinyCore by Spencer Konde megaTinyCore

Then choose ATtiny412. It will now show ATtiny412 in the top dropdown board menu. attiny-board-choice

Go to Tools -> Port -> choose the port associated with my XIAO that is already plugged in. Go to Tools -> Programmer -> SerialUPDI - 57600 baud

Then check to make sure by looking in the tools menu.

check

I hooked up a photo resistor, and a hall effect sensor to the ATtiny with help of Claude.ai. You can follow the transcript and images from my chat here.

ATtiny412 hooked up to ESP32-C6 for programing: attiny412 to esp32-c6

ATtiny412 containing a Hall Effect sensor and a photoresistor, as node to ESP32-C6 master:

attiny412 to esp32-c6

I tried running Claude's program, but had this error message:

Port monitor error: command 'open'failed: Serial port busy.

- I had opened the serial monitor, and the program needed that port to load the program

- It then compiled, but the port was still busy

- I had to use terminal to "kill" the serial monitor, but by the time I ran the kill code it had closed.  There had just been a long delay.

already-killed

The code can now starts uploading, and gets another error "uploading error: exit status 1."

uploading error: exit status 1

I gave Claude the error code, and we are working through it. Claude says that the chip is sending "garbage" back, which means that there is some wiring issues. I have tried:

- checking all the 3v3 and ground connections

- checking all my wiring:

programing attiny wiring

esp pinD6, blue on row 24 goes to row 22, there it joins a 1K resistor.  the resistor bridges the bread board to row 22 where it connects with the green wire that leads to pin D7 (RX on row 24) and the yellow wire that goes from row 22 to row 16 where it connects to pin 5 of the breakout board.  orange wire on the attiny goes from pin 1 of the breakout board to the  poitive voltage rail that is connected the the right side positive voltage rail and the 3v3 voltage output, the 3rd pin down on the right of the esp.  The ground are the brown wires, that are connected to the negative rails on the breadboard, which lead to the 2nd pin down on the right of the esp.  The ground is attached to pin 8 of the breakout board for the attiny412.

- I ran this program to test if my problem is in the ESP32-C6 board.
void setup() {
    Serial.begin(115200);
    Serial1.begin(57600, SERIAL_8N1, 7, 6); // RX=D7, TX=D6
    Serial.println("Loopback test starting...");
}

void loop() {
    Serial1.println("UPDI test ping");
    delay(100);

    if (Serial1.available()) {
        String response = Serial1.readStringUntil('\n');
        Serial.print("Got back: ");
        Serial.println(response);
    }
    delay(1000);
}

I was using the wrong pin number!! RX=D6 GPIO 16, TX=D7 GPIO 17

The code should be:

Serial1.begin(57600, SERIAL_8N1, 17, 16);

Unfortunately that still didn't solve my problem.

Remember (at least for my ESP32-C6) I must press Boot and Reset. Then release Reset, then Boot each time I want to reprogram my ESP32-C6 chip!

I tried using different protocoll to program the chip, and eventually switched to the RP2040. Unfortunately the RP2040 couldn't program the ATtiny either.

After many trials, tests, fixes and setbacks, Claude and I determined that my ATtiny412 chip is damaged. My final test that led to this conclusion was a voltage reading from each pin to the ground. Only the vcc and ground read correctly. The other pins should have been at 3.28v, but read much lower. I am not sure why they should have an output at all. Shouldn't they be reading zero until they have been writen to HIGH? Either way, they are not reading properly.

The chip was likely damaged by my poor soldering skills, and attempts to fix the soldering or rough handling.

For the transcript of my chat session with Claude.ai click here. In it you can follow all the tests I ran through.

My last prompt, not shown in the transcript was, "how long have I been actively working on getting the ATtiny chip to work with you?" In short, the answer was 7 active hours of troubleshooting!

Attempt 2

Steps 1 & 2:

I used Claude.ai to create walk me through a simple networking set up using the microcontrolers, sensors, and output devices I have on hand. Once I understand how everything works, I can make something more interesting.

I had Claude keep a transcript of our work, including images I uploaded to it. That document can be found here networking with claude.

In summary I created 3 nodes:

  1. ESP32-C6: Master
    • Photoresistor
    • speaker

Video of isolated Node 1 sped up by 4x to decrease file size:

Node 1 (Master) final code:

#include <Wire.h>

#define PHOTO_PIN 0
#define BUZZER_PIN 1
#define LIGHT_THRESHOLD 500  // chosen after testing (reads < 500 if dark)

void setup() {
  Serial.begin(115200);
  pinMode(BUZZER_PIN, OUTPUT);
  Wire.begin();  // master — no address needed
  Serial.println("ESP32-C6 Master ready");
  delay(1000);
  Wire.setTimeOut(10);
}

void loop() {
  // --- Read own photoresistor ---
  int myPhoto = analogRead(PHOTO_PIN);
  bool myDark = (myPhoto < LIGHT_THRESHOLD); // if node1 senses darkness myPhoto < LIGHT_THRESHOLD
  if (myDark) {
    tone(BUZZER_PIN, 1000, 200);  // buzz on low light
  }

  // --- Poll RP2040 (0x08) for Hall effect reading ---
  Wire.requestFrom(0x8, 1);                                                                    
  int hallVal = Wire.available() ? Wire.read() : -1;
  if (hallVal == -1) Wire.clearWriteError(); 


  // --- Poll ESP32-S3 (0x09) for photoresistor reading ---
  //  Wire.requestFrom(0x09, 2);                                                                   
  //  int s3Photo = -1;                                                                            
  //  if (Wire.available() >= 2) s3Photo = (Wire.read() << 8) | Wire.read();                       
  //  else Wire.clearWriteError();


  // --- Serial monitor output ---
  Serial.println("=== Node Readings ===");
  Serial.print("Node 1 (ESP32-C6) photoresistor: ");
  Serial.println(myPhoto);
  Serial.print("Node 2 (RP2040)   hall effect:   ");
  Serial.println(hallVal == 1 ? "MAGNET DETECTED" : "no magnet");
  //Serial.print("Node 3 (ESP32-S3) photoresistor: ");
  //Serial.println(s3Photo);
  Serial.println();

  delay(1000);
}
  1. RP2040 Slave 0x08
    • hall effect sensor
    • led

Video of isolated Node 2 sped up by 4x to decrease file size:

Node 2 final code:

#include <Wire.h>

#define I2C_SLAVE_ADDR 0x08
#define HALL_PIN 27
#define LED_PIN 4

volatile bool ledCommand = false;
int hallVal = 0;

void onRequest() {
    uint8_t val = (digitalRead(HALL_PIN) == LOW) ? 1 : 0;  // 1=magnet, 0=no magnet
    Wire.write(val);  //sends sensor reading of magnet or no magnet to node 1
}

void onReceive(int bytes) {
  if (Wire.available()) {
    ledCommand = Wire.read();  // receive LED command from master
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(HALL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);

 Wire.setSDA(6); Wire.setSCL(7);
  Wire.begin(I2C_SLAVE_ADDR); 
  Wire.onRequest(onRequest);
  Wire.onReceive(onReceive);
  Serial.println("RP2040 Slave 0x08 ready");
}

void loop() {
  hallVal = digitalRead(HALL_PIN);  // A3144: LOW = magnet detected
  bool magnetDetected = (hallVal == LOW);

  // local logic: magnet detected → LED on
  digitalWrite(LED_PIN, magnetDetected ? HIGH : LOW);

  // also obey master command
  // (master can override with ledCommand if desired)

  Serial.print("Hall effect: ");
  Serial.println(magnetDetected ? "MAGNET DETECTED" : "no magnet");

  delay(200);
}
  1. ESP32-S3 Slave 0x09
    • Photoresistor
    • led

Video of isolated Node 3:

Node 3 final code:

#include <Wire.h>

#define I2C_SLAVE_ADDR 0x09
#define PHOTO_PIN 1
#define LED_PIN 2
#define LIGHT_THRESHOLD 2000  // adjusted after testing, reads about 2500 when covered, and 1000 when uncovered

volatile bool ledCommand = false;
int photoVal = 0;

void onRequest() {
  uint8_t hi = (photoVal >> 8) & 0xFF;
  uint8_t lo = photoVal & 0xFF;
  Wire.write(hi);
  Wire.write(lo);  // send 2 bytes for 12-bit ADC value
}

void onReceive(int bytes) {
  if (Wire.available()) {
    ledCommand = Wire.read();
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);


  Wire.begin(I2C_SLAVE_ADDR, 5, 6); //added pins 5,6 sor SDA, SLA
  Wire.onRequest(onRequest);
  Wire.onReceive(onReceive);
  Serial.println("ESP32-S3 Slave 0x09 ready");
}

void loop() {
  photoVal = analogRead(PHOTO_PIN);
  bool dark = (photoVal > LIGHT_THRESHOLD); // > LIGHT_THRESHOLD because the sensor reads about 2500 when dark

  digitalWrite(LED_PIN, dark ? HIGH : LOW);

  Serial.print("Photoresistor: ");
  Serial.println(photoVal);

  delay(200);
}

Problems I encountered were:

- Node 2 is on my idea-pcb
    - after so many times putting the plug in and pulling it out, my board failed.  The female header came off.  It even pulled a connecting pin out of the header! I moved to a breadboard.

broken-idea-pcb

- bad wiring, and while I fixed that I accidentally directly connected the led to the power and ground causing it to turn on.  I removed it immediately, less than a second, but it had fried my LED.  I didn't realize this until the LED circuit wasn't working.  I used my multimeter to determine that there was no current flowing, and remembered my earlier mistake.  I tested the LED with my handy 3V button battery, and it didn't work.  The circuit worked once I replaced my LED.

- programming errors including 
    - missing ";" 
    - a command outside of a loop 
    - wrong pin numbers

Claude gave up at about 1am saying, "ESP32-S3 I2C slave mode is fundamentally unreliable in the Arduino Wire library — confirmed across many attempts. A working 2-node I2C network already exists: Node 1 (ESP32-C6 master) and Node 2 (RP2040 slave at 0x08). This satisfies the assignment. Suggested accepting the 2-node setup, removing the ESP32-S3 poll from master code to fix garbled output, and documenting the ESP32-S3 as a third node tested independently with I2C slave reliability issues."

I tried a few more ideas though - switching the ESP32-S3 for my son's ESP32-C6 - same issue, it ran on its own, but did not send to the master - moving the wires around the pins just incase they were numbered wrong - didn't work - switching out the wires to the junction for SDA and SCL to make sure the wires worked - didn't change anything

So now at 2am, I feel I have exhausted my options, and myself.

Video of the 2 nodes working together sped up by 4x to decrease file size:

A funny thing happened as I finally left my office. When I turned off my lights, my circuit began to beep. It made me jump, and hurry to unplug my circuit.

Why my program didn't work:

I asked Mr. Dubick for help, and he found out that the ESP32-C6 can only work as the Leader/ Node 1 chip due. He is working on a detailed slideshow to explain the situation.

I talked about the issue during the Saturday open time, and Saheen followed up on the mattermost channel.

"saheen.palayi 1:15 PM

@dorian-fritze ("follow up from saturdays Global Open Time") Answer to your Communication week Issue Dorian's Week 11 Doc:- we(me and @miriam.choi ) are tested the I2C Slave and Master (Leader and Follower) Issues with all the Xiao ESP32 versions(C3,S3, C6) available with us, and found that the communication between Xiao ESP32 C3 and Xiao ESP32 S3 are stable across the dev boards over I2C both Leader/Follower mode , but the Xiao ESP32 C6 only works in a Leader mode, the follower not supports in Arduino IDE. And This Form pointing out the issue and a work around for the ESP32 C6 to use the ESP IDF frame work"

He also linked to this forum post on Seeed studio XIAO ESP32C6 I2C Slave Pins?

2 RP2040s

I was able to get my newly printed node board to connect, and fix my "idea pcb." I connected both of them with RP2040s. I also tried a nRF52840 I found in the used RP2040 bin that I took by accident, and the esp32-s3. I could not get the nRF5240 to print back to the serial monitor for some reason, and the esp32-s3 could not be found on my computer at all.

I asked Claude to edit my master code to be just the 2 rp2040s with this prompt and follow ups.

I am going to past in 2 codes. First is the node2 code, then there is the old master code. I currently have 2 node2's working, and want to rewrite the master code to match the wireing of the node2, a hall sensor and light, not a photosensor and speaker. can you rewrite it for me?

❯ i want to use one of the node2 as the master, and take the esp32 out

❯ i am only having 1 master and 1 slave, both are rp2040s

Claude gave me this code. #include

#define HALL_PIN 27
#define LED_PIN 3

void setup() { Serial.begin(115200); pinMode(HALL_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);

Wire.setSDA(6);
Wire.setSCL(7);
Wire.begin();  // master — no address needed
Wire.setTimeOut(10);                                                                                                                                              
Serial.println("RP2040 Master ready");
delay(1000);

}

void loop() { // --- Read own hall sensor --- bool myMagnet = (digitalRead(HALL_PIN) == LOW); digitalWrite(LED_PIN, myMagnet ? HIGH : LOW);

// --- Poll slave RP2040 (0x08) ---                                                                                                                               
Wire.requestFrom(0x08, 1);
int hall08 = Wire.available() ? Wire.read() : -1;                                                                                                                 
if (hall08 == -1) Wire.clearWriteError();

// --- Serial monitor output ---                                                                                                                                  
Serial.println("=== Node Readings ===");
Serial.print("Node 1 (RP2040 master) hall effect: ");                                                                                                             
Serial.println(myMagnet ? "MAGNET DETECTED" : "no magnet");
Serial.print("Node 2 (RP2040 0x08)   hall effect: ");                                                                                                             
Serial.println(hall08 == 1 ? "MAGNET DETECTED" : hall08 == -1 ? "no response" : "no magnet");
Serial.println();

delay(1000);

}

I tried to trouble shoot, I swapped boards, tested independently, checked wires, but I still can't get them to talk to eachother.I hope to get my esp32-c6 back from Mr. Dubick soon so I can try with that since it had been working with the RP2040, and I milled some boards.

I kind of milled some boards. My student board came out well dispite my missing a connection, and having a tool failior at the beginning of the edge cut. I was able to fix the missing connection with some wire, and I used the board dispite not being fully cut out. My idea board cut well again. The Teacher board was missing a section of connecitons, which were my falt in KiCad, but I fixed those, and have been learning mods to work with my new milling machine. Unfortunately I still have a lot to learn, and have yet to successfully cut out the board. I am running out of blank pcb boards.

Creating my pcb boards

I designed a Teacher/ Leader/ Node 1 board:

F_Cu.svg: teacher node 1

Edge_Cuts.svg: teacher node 1 edge cuts

and the students/ Node boards:

F_Cu.svg: student nodes F_Cu

Edge_Cuts.svg: student nodes edge cuts