networking and communications¶
Assignment¶
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
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)
Additional Personal Goals¶
To get some work done on my final project, if I can get all my individual work done for this week a little early. Our group work will have to wait a bit since the lab is closed until Tuesday for holiday weekend.
The Group Work¶
Link to our group page here
We have Super Coding Kim on our team.. so I thought I should do a bit of learning before meeting up with our team on the group work. Before firewalls and hackers, I used to set up our wifi routers and stuff, and network us enough to use QuickBooks enterprise. Now that we have a uniFi and it's more complicated, I just do the server updates and have access to the UniFi. The new stuff is cool, but complicated. All this to say, I have seen some stuff, but don't know much.
So claude suggeted I meet NetworkChuck and Professor Messer OSI model to take some lessons.
After watching these videos, it was much easier to understand what we were trying to do and the lingo behind it. In the group work, Kim Alexander talked with me about DHCP and showing me in the code where the web server was being hosted up. Then on her machine how she was connecting to. Then when we moved into the photorsensor work, she showed me how to look and see the get and codes for /H and /L for the light to blink on the server chip based on what the client chip was sending.
The Individual Work¶
My asset files are here.
Wifi Communication with ESP32-C6¶
I did some work getting my ESP32-C6 to communicate with a web interface on my phone to get ready for my final project. I was pretty excited until I saw the notification on the mattermost that said we needed more than a webpage on the phone to the chip communication. LOL.
Finding a new project¶
The Wednesday lesson was over my head. I really don't think I understood 95% of what was being presented. I decided I needed to watch some tutorials and get enough background information that I could process the assisgnment. To kick start the learning in the correct direction, I put the excersize requirements, along with the matter most clarification into claude and asked
PROMPT: week 11 netowrking.. this is my homework ... • design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s) - ideas on what i can do - i have a few esp32c3 and esp32c6 chips at home
Reponse.. was a few choices.. but I am going to share the one that I am going to follow up on.
CLAUDE: (recommended) ESP-NOW sensor mesh
Two ESP32s talk directly peer-to-peer (no router needed). Each chip has its own MAC address as its network address. One reads a button or sensor, the other blinks an LED or buzzes. Great for demonstrating addressed nodes + I/O.
Given what you already have and your comfort level with plain Arduino code, ESP-NOW is probably your sweet spot — here's why it nails the assignment:
- Each ESP32's MAC address is its network address (no router, no broker, directly checkable in code)
- You can use your capacitive touch pin as the input and a buzzer or LED as the output — hardware you've already wired up
- Works with C3 and C6 boards together
- Code is simple: esp_now_send() / OnDataRecv callback, no unfamiliar libraries beyond the built-in ESP-NOW API
The I²C single-board option is the quickest if you have any I²C sensors lying around (even a basic temp sensor) — you can do the whole thing on one chip and document the 7-bit addresses from the scan.
NOTE: I do not have an I2C board lying around.. but if I finish this assignment in time, I am going to try to make one.. I do have two ESP32 boards milled and working. So I am going to start with learning about ESP-NOW
PROMPT: OK - find me a tutorial on ESP-NOW and what kind of boards should i design and mill?
CLAUDE: Great tutorials found. Here's the rundown:
Best tutorials for you:
- Random Nerd Tutorials — the gold standard: randomnerdtutorials.com/esp-now-esp32-arduino-ide — step by step, circuit diagrams, code included
- FritzenLab — actually uses a C3 and a XIAO ESP32-C6 together (same chips you have), walks through getting the MAC address of each board and doing transmitter→receiver with Arduino code — very relevant: fritzenlab.net
- Official Espressif Arduino docs — covers the newer ESP-NOW library in Arduino Core 3.0.0, including a simplified
ESP_NOW_Serial_Classfor two-device setups that reduces boilerplate significantly: developer.espressif.com
One key note from FritzenLab: you don't need a WiFi password or home router — ESP-NOW communicates directly between boards. You just need to hardcode the receiver's MAC address into the transmitter's code.
Now — what boards to design and mill:
For this assignment, you want two simple breakout-style boards, each hosting one of your bare ESP32 chips (C3 or C6 XIAO modules) plus minimal I/O. Here's what makes sense given your existing PCB milling setup:
Board 1 — Sender node - XIAO ESP32-C3 or C6 footprint (you already have this in KiCad) - Capacitive touch pad (just a copper pour on the PCB, no extra parts — you've already done this on GPIO 0/2) - Optional: status LED + 330Ω resistor - USB passthrough for power/programming
Board 2 — Receiver node
- XIAO ESP32-C3 or C6 footprint
- Piezo buzzer (you know tone() cold) or LED
- Same USB power
Why this is perfect for milling: - Both boards are nearly identical — mill them from the same file, just load different firmware - No fine-pitch SMD components beyond what you've already milled (0805 resistors, XIAO footprint) - The capacitive touch input is literally just a copper island — no extra parts, no soldering complexity - Buzzer can be a through-hole piezo dropped into two drilled holes
The story for your documentation writes itself: touch the pad on Board 1 → ESP-NOW packet fires → Board 2 buzzes. Each board's MAC address is its network address. Clean, simple, provably node-to-node.
Want me to sketch out the schematic/KiCad layout plan for both boards?
PROMPT: if you can actually giec me a picture.. ot your --- lines (those confuse me often)
CLAUDE: Here's a visual picture of both boards — what they look like and how they connect:

So that's the two boards. Each one is a small FR-1 PCB you mill that holds:
The teal board (sender) has your XIAO module, a copper pour touch pad (no extra parts — you've done this before), and a status LED with a resistor. You touch it, it sends.
The purple board (receiver) has your XIAO module, a through-hole piezo buzzer dropped into two drilled holes, and a confirmation LED. It receives the packet and makes noise.
Both boards are nearly identical in layout — same XIAO footprint, same USB connector placement — so you can essentially mill one KiCad file twice and just load different firmware. The touch pad is literally just a copper island connected to GPIO 0 or 2, so no extra components there at all.
PROMPT: could i use a photoresistor instead of a touch pad?
CLAUDE: Yes, absolutely — a photoresistor works great and is actually easier to wire than capacitive touch. Instead of touching the pad, you cover it with your hand (or shine a light on it) to trigger the send.
You already know the wiring from your pill dispenser work — voltage divider, 3.3V, analog read. The only change in code is swapping the touch read for an analogRead() and checking if the value goes above or below a threshold.
The board design barely changes — instead of a copper pour pad, you just add two through-hole drill points for the photoresistor legs and a through-hole resistor (10kΩ) for the divider. Even simpler to mill and solder.
Getting MAC addresses¶
I decided to use my boards from week8 and week 9 to do this project so that I could do more work on my final if time permitted... and it did (progress made).. yay!
Following along the fritzenlab tutorial mentioend earlier I started working on getting MAC I.D.'s for my ESP 32 boards.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include <esp_wifi.h>
void readMacAddress(){
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop(){
}
Loaded the MAC reading code on each ESP32 and got the MAC addresses of each unit.
SENDER ESP32 Board MAC Address of the light sensor and servo control board: 24
4a
51:74
See above.. this is funny - html turned my MAC adresses into fun symbols... I left it because its funny.. here is the information again with markers to keep is as a MAC address.
SENDER ESP32 Board MAC Address of the light sensor and servo control board: 24:ec:4a:ca:51:74
08:18:15.407 -> [DEFAULT] ESP32 RECEIVER Board MAC Address of my very first board: e4:b3:23:c5:3d:a4
Coding Mentor Talk¶
I took a break here to talk to my coding mentor Kenny Hu. We went over my plan and lined it out.
- set up one side to be listening (slave)
- Set up the other side to be broadcasting (master)
- Master sends out one message and then the slave responds that it got the message
Once connection layer is established - then we figure out how the connection plays into our application
- Define application - device B powers on two lights
- When device A - experiences low light - light one lights up
- Master sudo code: while sensor is less than 600, we will send a note over the esp Slave needs a register call back
I don't need protocolling unless I am doing multiple things.. Protocolling: design how my packet is designed (what each bit and byte in the packet means)
I'm really trying to get all my questions ready for open time which starts in 30 minutes.
Open Time help
From Rico Kanthatham
Everything you need to know about different Serial Communication protocols
With this video, I learned about the wired protocols UART, SPI, I²C and how they send thier data... clocks, no clocks, etc...
Resources on ESP NOW From saheen palayi
Setting Up the SENDER and RECEIVER¶
I wired up my ESP32 from week 8 and my ESP 32 from week 9/10 and plugged them both into my computer for this week 11 project.

I followed the fritzenlab tutorial that was mentioned before which is based on the Random Nerd Tutorials project and code.
I was able to get the receiver and the sender set up with thier starter code. Then I added my MAC addreses where indicated and started testing.
I had a couple bumps along the way - the first one was a compilation error.
C:\Users\camil\FAB_ACADEMY\Arduino\reciever\reciever.ino: In function 'void setup()':
C:\Users\camil\FAB_ACADEMY\Arduino\reciever\reciever.ino:48:28: error: invalid conversion from 'void (*)(const uint8_t*, esp_now_send_status_t)' {aka 'void (*)(const unsigned char*, esp_now_send_status_t)'} to 'esp_now_send_cb_t' {aka 'void (*)(const wifi_tx_info_t*, esp_now_send_status_t)'} [-fpermissive]
48 | esp_now_register_send_cb(OnDataSent);
| ^~~~~~~~~~
| |
| void (*)(const uint8_t*, esp_now_send_status_t) {aka void (*)(const unsigned char*, esp_now_send_status_t)}
In file included from C:\Users\camil\FAB_ACADEMY\Arduino\reciever\reciever.ino:7:
C:\Users\camil\AppData\Local\Arduino15\packages\esp32\tools\esp32c3-libs\3.3.7/include/esp_wifi/include/esp_now.h:193:54: note: initializing argument 1 of 'esp_err_t esp_now_register_send_cb(esp_now_send_cb_t)'
193 | esp_err_t esp_now_register_send_cb(esp_now_send_cb_t cb);
| ~~~~~~~~~~~~~~~~~~^~
exit status 1
Compilation error: invalid conversion from 'void (*)(const uint8_t*, esp_now_send_status_t)' {aka 'void (*)(const unsigned char*, esp_now_send_status_t)'} to 'esp_now_send_cb_t' {aka 'void (*)(const wifi_tx_info_t*, esp_now_send_status_t)'} [-fpermissive]
I put this entire error into claude, and the bottom line is that becuase the code written was for ESP version 2.0 and I am using 3.7.7, I needed to make the following little change.
CHANGE THIS SECTION:
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
Change to
void OnDataSent(const wifi_tx_info_t *tx_info, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Sent OK" : "Send Failed");
}
This is a breaking API change in the ESP32 Arduino core v3.x — the esp_now_send_cb_t signature changed. The first parameter is no longer const uint8_t mac_addr but instead const wifi_tx_info_t.
The code starts with setting up the mutually agreed upon structure and then goes into instructions. There are many print lns to be able to debug issues.
My next little bump was that I put the sender code on the reciever and vica versa.. and then the MAC ID was pointing to itself. I had the chips plugged into port 10 and 14 and couldn't remember which was which port. I had a 50/50 chance.

I loaded the code onto the different ESP's and and I was able to get a successful messages on both the sender serial monitor and the receiver serial monitor.


Integrating the Photosensor code into the Sender and Receiever Code¶
Since I already had my photosensor code and my sender code and my reciever code, I decided to enlist claude in teaching me how to integrate them.
PROMPT (plus my code from photo resistor , sender and receiver in the beginning) I have a receiver, sender, and photoresistor code. I want to integrate the photoresistor into the two other codes. I want to read the photo resistor on sender, and then blink the light on reciever when its under 600
Discussion with Claude on integrating my code¶
Integrating my codes together as suggested by claude pretty much worked.. except that I have a pull up resistor on my LED, so the light was staying on all the time. I went into the code and just changed the receiever code to have the else point to turn the pin HIGH instead of LOW.
if (myData.d) {
// Blink 3 times when dark
for (int i = 0; i < 3; i++) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
} else {
digitalWrite(ledPin, LOW); // changed this to HIGH becuase its a pull up
}
The code has the sender check for the light and if its a threshold of 600 or less, it will flash the receiver light 3 times. It checks about every 2 seconds, so you can see the delay of the light going out when I move my hand before it stops blinking.
I had help holding the camera this time.. and I made the video landscape :-) Yay!