This is a draft so you have access to the code used on the two ESP32 microcontrollers. I wrote these instructions while building the project but have not proofread them really. I will finalize the article when I get some free time and add more content to it with better formatting. These instructions go along with this video.
Here is a guide with code and setup instructions for two ESP32 boards to wirelessly transmit data of four proximity sensors. All analog input values will be converted to 12-bit (0-4095) by the ESP32 ADC and sent using ESP-NOW protocol as a 12 bit output. This is received as a 12-bit values and then converted to 8-bit(0-255) by dividing by 16. This 8-bit output is turned into a PWM signal.
The PWM Signal will be turned into an analog signal by using a 10kΩ Resistor and a100nF Capacitor as a RC filter. This will create the original analog signal that was send out. This will be amplified by an LM358 op-amp and a gain of 2 will be applied by using two 10K resistors. The output will power a display LED to show the signal was received. It will also go into a second op-amp which will act as buffer to endure the outputs signal is matched. This output will will feed into the artificial neuron. When activated the output will increase the firing rate of that neuron.
ESP32 Setup Instructions
Part 1: Software Setup
Steps to Upload Code for the Receiver First. (Cause you need the MAC Address for the Transmitter)
When I plugged in ESP 32 with USB data cable nothing would show up. I had to update the drivers.
Go to device manager.
Look for, CP2102 USB to UART bridge Controller
The drivers for this device are not installed. (Code 28)
There are no compatible drivers for this device.
To find a driver for this device, click Update Driver.
Download the correct driver:
-
Go to https://www.silabs.com/developer-tools/usb-to-uart-bridge-vcp-drivers?tab=downloads
-
Download ” CP210x Universal Windows Driver” as a zip
-
Extract the zip file
Right click in device manager, update driver, Browse you computer and selected select the extracted folder. CP210x_Universal_Windows_Driver -
restart your computer.
-
Now you can delete the zip and extracted folder.
Under Ports I see Silicon Labs CP210x USB UART Bridge(com3)
-
Now we can upload files to the ESP 32 with port (COM3) in your code editor or Arduino IDE.
Step 1: Download and Install Arduino IDE
-
Go to the official Arduino website: https://www.arduino.cc/en/software
-
Download “Arduino IDE 2.3.2” for Windows
-
Install Arduino IDE:
-
Run the downloaded installer
-
Accept the license agreement
-
Choose installation location (default is fine)
-
Allow the driver installation when prompted
-
Wait for installation to complete
-
Step 2: Configure Arduino IDE for ESP32
-
Open Arduino IDE
-
Go to File > Preferences
-
In the “Additional Boards Manager URLs” field, paste:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
-
Click “OK”
-
Go to Tools > Board > Boards Manager
-
In the search box, type “ESP32”
-
Look for “esp32 by Espressif Systems” and click “Install” Version 3.2.0
-
Wait for installation to complete
Step 3: Select ESP32 Board and Port
-
Go to Tools > Board
-
Look for “ESP32 Arduino” section and select “ESP32 Dev Module”
-
Go to Tools > Port
-
Select “COM3 (Silicon Labs CP210x USB to UART Bridge)”
Step 4: Get Your Receiver’s MAC Address
You need to first upload a MAC address finder code to your receiver ESP32. Here’s how:
-
Create a new sketch in Arduino IDE
-
Copy and paste this code:
- #include <WiFi.h>
- void setup() {
- Serial.begin(115200);
- delay(1000); // Wait for serial to initialize
- Serial.println(“Starting…”);
- // Initialize WiFi
- WiFi.mode(WIFI_STA);
- delay(500); // Small delay for WiFi to initialize
- Serial.print(“ESP Board MAC Address: “);
- Serial.println(WiFi.macAddress());
- }
- void loop() {
- // Nothing here
- }
Save file as MAC_Finder
Upload this code to the ESP32 that will be your receiver.
void loop() {}
-
Upload this code to the ESP32 that will be your receiver by clicking upload.
-
Open Serial Monitor (Tools > Serial Monitor), set baud rate to 115200
-
You might need to push EN (rest) button on the ESP board.
-
You should see output like: ESP Board MAC Address: 24:6F:28:AE:C5:9C
My Actual MAC Address was.
ESP Board MAC Address: F4:65:0B:56:66:6C
Code should be updated.
uint8_t receiverAddress[] = {0xF4, 0x65, 0x0B, 0x56, 0x66, 0x6C};
Step 5: Upload the Receiver Code
// Complete Receiver Code
// Receiver Code – PWM Output Pins
#include <esp_now.h>
#include <WiFi.h>
// Structure to match transmitter’s data
typedef struct struct_message {
int sensor1;
int sensor2;
int sensor3;
int sensor4;
} struct_message;
struct_message sensorData;
// Optimal PWM output pin definitions
const int OUTPUT1_PIN = 13; // PWM Channel 0
const int OUTPUT2_PIN = 14; // PWM Channel 1
const int OUTPUT3_PIN = 26; // PWM Channel 3
const int OUTPUT4_PIN = 27; // PWM Channel 2
// PWM settings
const int PWM_FREQ = 16000; // 16 kHz frequency
const int PWM_RESOLUTION = 8; // 8-bit resolution (0-255)
// Updated callback function signature for ESP32 Core 3.x
void OnDataRecv(const esp_now_recv_info *info, const uint8_t *incomingData, int len) {
memcpy(&sensorData, incomingData, sizeof(sensorData));
// Debug output
Serial.print(“Sensor 1: “); Serial.println(sensorData.sensor1);
Serial.print(“Sensor 2: “); Serial.println(sensorData.sensor2);
Serial.print(“Sensor 3: “); Serial.println(sensorData.sensor3);
Serial.print(“Sensor 4: “); Serial.println(sensorData.sensor4);
Serial.println(“——————–“);
// Convert 12-bit ADC values (0-4095) to 8-bit PWM (0-255)
ledcWrite(OUTPUT1_PIN, sensorData.sensor1 / 16);
ledcWrite(OUTPUT2_PIN, sensorData.sensor2 / 16);
ledcWrite(OUTPUT3_PIN, sensorData.sensor3 / 16);
ledcWrite(OUTPUT4_PIN, sensorData.sensor4 / 16);
}
void setup() {
Serial.begin(115200);
delay(1000); // Give Serial time to initialize
// Set device as WiFi station and initialize
WiFi.mode(WIFI_STA);
WiFi.begin(); // Initialize WiFi without connecting to a network
delay(100); // Give WiFi time to initialize
// Display MAC address
Serial.print(“ESP Board MAC Address: “);
Serial.println(WiFi.macAddress());
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println(“Error initializing ESP-NOW”);
return;
}
esp_now_register_recv_cb(OnDataRecv);
// Setup PWM using new API for ESP32 Core 3.x
ledcAttach(OUTPUT1_PIN, PWM_FREQ, PWM_RESOLUTION);
ledcAttach(OUTPUT2_PIN, PWM_FREQ, PWM_RESOLUTION);
ledcAttach(OUTPUT3_PIN, PWM_FREQ, PWM_RESOLUTION);
ledcAttach(OUTPUT4_PIN, PWM_FREQ, PWM_RESOLUTION);
Serial.println(“Receiver ready!”);
}
void loop() {
// Main loop does nothing – all handled in callback
}
-
Create a new sketch in Arduino IDE (File > New Sketch)
-
Copy and paste the complete receiver code from the document above.
-
Save the file as “ESP32_Receiver”
-
Upload it to the ESP32 that will be your receiver
-
Press the EN to start running the code.
-
Open Serial Monitor to verify it’s working. It should show MAC Address.
Now we need to initialize the receiver ESP32 and upload this Transmitter code.
Configure Arduino IDE for on the Receiver ESP32
All the Drivers and board information was previously setup. Nothing should need to be done.
Step 1: Upload the Transmitter Code.
- Copy and past code and the Save the file as “ESP32_Transmitter”
-
Upload it to the ESP32 that will be your transmitter.
-
Press the EN to start running the code.
-
Open Serial Monitor to verify it’s working. It should show MAC Address.
// Complete Transmitter Code – Analog Sensors – Fixed for ESP32 Core v5.x
#include <esp_now.h>
#include <WiFi.h>
#include <esp_task_wdt.h>
// Replace with your receiver’s MAC address
uint8_t receiverAddress[] = {0xF4, 0x65, 0x0B, 0x56, 0x66, 0x6C};
// Structure for sensor data
typedef struct struct_message {
int sensor1;
int sensor2;
int sensor3;
int sensor4;
} struct_message;
struct_message sensorData;
esp_now_peer_info_t peerInfo;
// Analog sensor pin definitions (reordered to match physical layout)
const int SENSOR1_PIN = 33; // ADC1_CH5 (bidirectional)
const int SENSOR2_PIN = 32; // ADC1_CH4 (bidirectional)
const int SENSOR3_PIN = 35; // ADC1_CH7 (input-only)
const int SENSOR4_PIN = 34; // ADC1_CH6 (input-only)
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print(“Last Packet Send Status: “);
Serial.println(status == ESP_NOW_SEND_SUCCESS ? “Delivery Success” : “Delivery Fail”);
}
void setup() {
Serial.begin(115200);
// No pinMode needed for analog input
// Set device as WiFi station
WiFi.mode(WIFI_STA);
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println(“Error initializing ESP-NOW”);
return;
}
// Register callback function
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, receiverAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println(“Failed to add peer”);
return;
}
// Initialize watchdog timer using newer format
esp_task_wdt_config_t twdt_config = {
.timeout_ms = 5000,
.idle_core_mask = 0,
.trigger_panic = true
};
esp_task_wdt_init(&twdt_config); // Initialize with config structure
esp_task_wdt_add(NULL); // Add current task to WDT
Serial.println(“Transmitter ready!”);
Serial.println(“Receiver MAC address: F4:65:0B:56:66:6C”);
}
void loop() {
// Reset watchdog timer
esp_task_wdt_reset();
// Read analog values (0-4095)
sensorData.sensor1 = analogRead(SENSOR1_PIN);
sensorData.sensor2 = analogRead(SENSOR2_PIN);
sensorData.sensor3 = analogRead(SENSOR3_PIN);
sensorData.sensor4 = analogRead(SENSOR4_PIN);
// Debug output
Serial.printf(“Analog Values: %d, %d, %d, %d\n”,
sensorData.sensor1,
sensorData.sensor2,
sensorData.sensor3,
sensorData.sensor4);
// Send data via ESP-NOW
esp_err_t result = esp_now_send(receiverAddress, (uint8_t *) &sensorData, sizeof(sensorData));
// Debug output for transmission status
if (result == ESP_OK) {
Serial.println(“Sent successfully”);
} else {
Serial.println(“Error sending data”);
}
delay(10); // Send every 10ms (I should made it 1 for 1ms that will make the response time faster with less delay)
}
After Upload
-
Open Serial Monitor (Tools > Serial Monitor), set baud rate to 115200
-
You may need to push the EN (rest) button on the ESP board.
-
You should see
Sent successfully
Analog Values, 111, 416, 0, 0
Hardware Wiring Instructions
Part 1: Hardware Wiring
Transmitter Board:
-
Power connections:
-
5V battery positive → ESP32 VIN pin
-
5V battery ground → ESP32 GND pin
-
5V battery positive → Breadboard positive power rail (+)
-
5V battery ground → Breadboard ground rail (-)
-
-
Proximity sensor connections:
-
All 4 sensors:
-
VCC → Breadboard positive rail (+)
-
GND → Breadboard ground rail (-)
-
-
Sensor 1 OUT → ESP32 pin D33
-
Right Proximity sensor
-
-
Sensor 2 OUT → ESP32 pin D32
Front Proximity sensor -
Sensor 3 OUT → ESP32 pin D35
-
Back Proximity sensor
-
-
Sensor 4 OUT → ESP32 pin D34
-
Left Proximity sensor
Wring Transmitter and Proximity Sensors.
Configuration:
Proximity Sensor Out → ESP32 GPIO pin (direct)
Proximity Sensor Out → LM358 Pin 3
LM358 Pin 2 → LM358 Pin 1 (feedback)
LM358 Pin 1 → Current limiting resistor → LED → GND
Connections
Op-amp 1 (Front)
Pin 3: Non-inverting input (+) – Connect your input signal from the proximity sensor here
Pin 2: Inverting input (-) – Connect this directly to
Pin 1 (output) connects to Pin 2 (inverting input) for feedback and also goes through a resistor to the LED.
Pin 4: Connect to GND
Pin 8: to positive supply
Op-amp 2 (Right)
Pin 5: Non-inverting input (+) – Connect your input signal from the proximity sensor here
Pin 6: Inverting input (-) – Connect this directly to
Pin 7 (output) connects to Pin 6 (inverting input) for feedback and also goes through a resistor to the LED.
Op-amp 1 (Left)
Pin 3: Non-inverting input (+) – Connect your input signal from the proximity sensor here
Pin 2: Inverting input (-) – Connect this directly to
Pin 1 (output) connects to Pin 2 (inverting input) for feedback and also goes through a resistor to the LED.
Pin 4: Connect to GND
Pin 8: to positive supply
Op-amp 2 (Back)
Pin 5: Non-inverting input (+) – Connect your input signal from the proximity sensor here
Pin 6: Inverting input (-) – Connect this directly to
Pin 7 (output) connects to Pin 6 (inverting input) for feedback and also goes through a resistor to the LED.
Wiring the Receiver Board:
-
Power connections:
-
5V power supply positive → ESP32 VIN pin
-
5V power supply ground → ESP32 GND pin
-
-
Output connections (optional – for testing):
-
D13, Right Proximity sensor PWM Output
-
D14, Front Proximity sensor PWM Output
-
D26, Back Proximity sensor PWM Output
-
D27, Left Proximity sensor PWM Output
-

Cody started the Global Science Network with the idea people should be focusing more time, energy, and resources on useful projects. He has a bachelor’s degree in aerospace engineering and a master’s degree in mechanical engineering. Cody has worked for the US federal government, a university, a large corporation, small businesses, and for himself. He has done human brain computer interface research and is currently working towards creating non-biological human consciousness.