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

ESP32 and MPU6050 Battery-Powered Motion Sensor with Bluetooth Connectivity

View and Edit Project In Cirkit DesignerImage of ESP32 and MPU6050 Battery-Powered Motion Sensor with Bluetooth Connectivity

Circuit Documentation

Summary

This circuit is designed to interface an ESP32 microcontroller with an MPU6050 accelerometer and gyroscope sensor, a limit switch, a solenoid, and a motor driver. The circuit is powered by a 18650 Li-ion battery, which is managed by a TP4056 charging module. The power is regulated using Mini 560 step-down converters. The ESP32 communicates with the MPU6050 via I2C and controls the motor driver and solenoid through GPIO pins.

Component List

  1. ESP32 Devkit V1

    • Description: A powerful microcontroller with built-in Wi-Fi and Bluetooth capabilities.
    • Pins: 3V3, GND, D15, D2, D4, RX2, TX2, D5, D18, D19, D21, RX0, TX0, D22, D23, EN, VP, VN, D34, D35, D32, D33, D25, D26, D27, D14, D12, D13, VIN
  2. InvenSense MPU6050

    • Description: A 6-axis motion tracking device that combines a 3-axis gyroscope and a 3-axis accelerometer.
    • Pins: VCC, GND, SCL, SDA, XDA, XCL, AD0, INT
  3. 18650 Li-ion Battery

    • Description: A rechargeable lithium-ion battery.
    • Pins: -, +
  4. Mini 560 Step Down 20-7V to 5V

    • Description: A step-down voltage regulator that converts 20-7V input to 5V output.
    • Pins: IN-, IN+, OUT-, OUT+
  5. TP4056

    • Description: A lithium battery charger module with overcharge protection.
    • Pins: OUT-, B-, B+, OUT+, IN-, IN+
  6. Limit Switch

    • Description: A mechanical switch that can be used to detect the presence or absence of an object.
    • Pins: C, NO, NC
  7. Toggle Switch

    • Description: A switch that can be toggled between two states.
    • Pins: L1, COM, L2
  8. Motor Driver - N-Mos PWM Trigger

    • Description: A motor driver that uses PWM signals to control the motor.
    • Pins: + PWM, GND, OUT -, OUT +, DC OUT +, DC IN -
  9. Solenoid

    • Description: An electromechanical device that converts electrical energy into linear motion.
    • Pins: pin1, pin2

Wiring Details

ESP32 Devkit V1

InvenSense MPU6050

18650 Li-ion Battery

Mini 560 Step Down 20-7V to 5V (Instance 1)

Mini 560 Step Down 20-7V to 5V (Instance 2)

TP4056

Limit Switch

Toggle Switch

Motor Driver - N-Mos PWM Trigger

Solenoid

Code Documentation

Main Code (sketch.ino)

#include <Arduino.h>
#include <Wire.h>
#include <BluetoothSerial.h>
#include "MPU6050_6Axis_MotionApps20.h"

MPU6050 mpu;
BluetoothSerial SerialBT;

struct Button {
  const uint8_t PIN;
  uint32_t numberKeyPresses;
  bool pressed;
};

volatile bool interruptFlag = true;
unsigned long lastInterruptTime = 0;
const unsigned long debounceTime = 3000;

Button button1 = {18, 0, false};

void IRAM_ATTR isr() {
  unsigned long currentTime = millis();
  if (currentTime - lastInterruptTime < debounceTime) {
    return;
  }
  lastInterruptTime = currentTime;
  button1.numberKeyPresses++;
  button1.pressed = true;
}

#define OUTPUT_READABLE_QUATERNION

bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];

Quaternion q;
VectorInt16 aa;
VectorInt16 aaReal;
VectorInt16 aaWorld;
VectorFloat gravity;
float euler[3];
float ypr[3];

uint8_t teapotPacket[14] = {'$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\\r', '\\n'};

volatile bool mpuInterrupt = false;
void dmpDataReady() {
  mpuInterrupt = true;
}

void setup() {
  Wire.begin();
  Wire.setClock(400000);

  Serial.begin(115200);
  SerialBT.begin("ESP32_YUSUF");
  SerialBT.print("Bluetooth started");

  pinMode(button1.PIN, INPUT_PULLUP);
  attachInterrupt(button1.PIN, isr, FALLING);

  while (!Serial);

  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();

  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();

  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788);

  if (devStatus == 0) {
    mpu.CalibrateAccel(6);
    mpu.CalibrateGyro(6);
    mpu.PrintActiveOffsets();
    Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    mpuIntStatus = mpu.getIntStatus();
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }
}

void loop() {
  if (!dmpReady) return;
  if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
#ifdef OUTPUT_READABLE_QUATERNION
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    Serial.print(q.w);
    Serial.print(",");
    Serial.print(q.x);
    Serial.print(",");
    Serial.print(q.y);
    Serial.print(",");
    Serial.print