ESP32-Based Multi-Sensor Motion Tracking System with Wi-Fi Connectivity
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to interface multiple MPU-6050 sensors with an ESP32 microcontroller through a set of Adafruit TCA9548A I2C multiplexers. The MPU-6050 sensors are 6-axis motion tracking devices that combine a 3-axis gyroscope and a 3-axis accelerometer. The Adafruit TCA9548A I2C multiplexers allow for multiple sensors to be connected to the same I2C bus without address conflicts. The ESP32 microcontroller is used to read sensor data from the MPU-6050s and transmit the data over Wi-Fi using UDP packets.
Component List
- MPU-6050: A 6-axis motion tracking device that combines a 3-axis gyroscope and a 3-axis accelerometer.
- Adafruit TCA9548A: An I2C multiplexer that allows for multiple I2C devices with the same address to be connected to a single microcontroller.
- ESP32 (30 pin): A microcontroller with Wi-Fi and Bluetooth capabilities, which is used to read data from the sensors and send it over the network.
Wiring Details
MPU-6050
VCC: Connected to the power supply (3.3V or 5V depending on the system).GND: Connected to the ground.SCL: Connected to the corresponding SCL pin on the Adafruit TCA9548A.SDA: Connected to the corresponding SDA pin on the Adafruit TCA9548A.XDA,XCL,AD0,INT: Not connected in this circuit.
Adafruit TCA9548A
VCC: Connected to the power supply (3.3V or 5V depending on the system).GND: Connected to the ground.INPUTSDA: Connected to the SDA pin on the ESP32.INPUTSCL: Connected to the SCL pin on the ESP32.RESET: Not connected in this circuit.A0,A1,A2: Address pins, connected to either VCC or GND to set the I2C address.0SDA,0SCLto7SDA,7SCL: Each pair is connected to the corresponding SDA and SCL pins of an MPU-6050 sensor.
ESP32 (30 pin)
3V3: Connected to the 3.3V power supply.GND: Connected to the ground.D21(SDA): Connected to the INPUTSDA pin on the Adafruit TCA9548A.D22(SCL): Connected to the INPUTSCL pin on the Adafruit TCA9548A.- Other pins are not used in this circuit.
Documented Code
#include <WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
// Wi-Fi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// UDP settings
WiFiUDP udp;
const char* udpAddress = "192.168.1.100"; // IP address of the computer running Blender
const int udpPort = 12345; // Port number
// Define TCA9548A and MPU6050 settings (as in previous setup)
#define TCA_ADDRESS_1 0x70
#define TCA_ADDRESS_2 0x71
#define TCA_ADDRESS_3 0x72
Adafruit_MPU6050 mpu;
// Function to select a TCA9548A channel
void tcaSelect(uint8_t tcaAddress, uint8_t channel) {
if (channel > 7) return;
Wire.beginTransmission(tcaAddress);
Wire.write(1 << channel);
Wire.endTransmission();
}
// Assign sensor numbers to corresponding bone names
const char* sensorNames[17] = {
"head", // MPU6050 No.01
"shoulder_R", // MPU6050 No.02
"shoulder_L", // MPU6050 No.03
"upper_arm_R", // MPU6050 No.04
"forarm_R", // MPU6050 No.05
"hand_R", // MPU6050 No.06
"upper_arm_L", // MPU6050 No.07
"forarm_L", // MPU6050 No.08
"hand_L", // MPU6050 No.09
"spine.002", // MPU6050 No.10 (CHEST)
"spine", // MPU6050 No.11 (CENTER OF GRAVITY)
"thigh_R", // MPU6050 No.12
"shine_R", // MPU6050 No.13
"foot_R", // MPU6050 No.14
"thigh_L", // MPU6050 No.15
"shine_L", // MPU6050 No.16
"foot_L" // MPU6050 No.17
};
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA pin 21, SCL pin 22
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialize MPU6050 sensors
for (uint8_t tca = TCA_ADDRESS_1; tca <= TCA_ADDRESS_3; tca++) {
for (uint8_t channel = 0; channel < 8; channel++) {
tcaSelect(tca, channel);
if (!mpu.begin(0x68) && !mpu.begin(0x69)) {
Serial.print("Could not find MPU6050 on TCA ");
Serial.print(tca, HEX);
Serial.print(", channel ");
Serial.println(channel);
} else {
Serial.print("MPU6050 found on TCA ");
Serial.print(tca, HEX);
Serial.print(", channel ");
Serial.println(channel);
}
delay(100);
}
}
}
void loop() {
// Store all sensor data in one string
String allSensorData = "";
int sensorIndex = 0;
// Read data from each MPU6050 and prepare for a single UDP send
for (uint8_t tca = TCA_ADDRESS_1; tca <= TCA_ADDRESS_3; tca++) {
for (uint8_t channel = 0; channel < 8; channel++) {
if (sensorIndex >= 17) break;
tcaSelect(tca, channel);
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Format data for the current sensor
String data = String(sensorNames[sensorIndex]) + "," +
"AX=" + String(a.acceleration.x) + "," +
"AY=" + String(a.acceleration.y) + "," +
"AZ=" + String(a.acceleration.z) + "," +
"GX=" + String(g.gyro.x) + "," +
"GY=" + String(g.gyro.y) + "," +
"GZ=" + String(g.gyro.z) + ";";
allSensorData += data;
sensorIndex++;
}
}
// Send all data in a single UDP packet
udp.beginPacket(udpAddress, udpPort);
udp.print(allSensorData);
udp.endPacket();
Serial.println(allSensorData); // Print data to Serial for debugging
// Delay to achieve 60fps (1000ms / 60fps = ~16.67ms per frame)
delay(16); // Approximate delay for 60fps
}
This code is designed to run on an ESP32 microcontroller. It initializes Wi-Fi and UDP communication, sets up the I2C bus, and scans for MPU6050 sensors on all channels of the TCA9548A multiplexers. It then reads the sensor data and sends it over UDP to a specified IP address and port. The code also includes a mapping of sensor indices to human-readable names for easier identification of the data.