Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Based Multi-Sensor Motion Tracking System with Wi-Fi Connectivity

View and Edit Project In Cirkit DesignerImage of ESP32-Based Multi-Sensor Motion Tracking System with Wi-Fi Connectivity

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

Wiring Details

MPU-6050

Adafruit TCA9548A

ESP32 (30 pin)

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.