tockn / MPU6050_tockn

Arduino library for easy communication with MPU6050
227 stars 89 forks source link

ESP8266 COMPATIBILITY #3

Open JansZoro opened 6 years ago

JansZoro commented 6 years ago

There is a way to make it works in a ESP8266 Based Dev Board?

Thanks...

rtek1000 commented 6 years ago

Hello, Look this: [esp8266-sensor-mpu6050] https://github.com/rondawg369/esp8266-sensor-mpu6050

tockn commented 6 years ago

This code may work.
Could you try it?
I have only ESP32.

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup() {
  Serial.begin(9600);
  int SDA = 4;  // you can choose SDA pin
  int SCL = 14;  // you can choose SCL pin
  Wire.begin(SDA, SCL);
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
}

void loop() {
  mpu6050.update();
  Serial.print("angleX : ");
  Serial.print(mpu6050.getAngleX());
  Serial.print("\tangleY : ");
  Serial.print(mpu6050.getAngleY());
  Serial.print("\tangleZ : ");
  Serial.println(mpu6050.getAngleZ());
}
JansZoro commented 6 years ago

Thanks @rtek1000, the link you shared to me was too usefull to understand how the MPU6050 works. And @tockn, I'm going to test it and latter give you a feedback.

rtek1000 commented 6 years ago

Hello,

The sensor is very simple, just need to read the datasheet and the other document about the registers map.

These documents are complements, frankly I think they should be just one, as are the datasheet of the pic of the microchip.

https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf

https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

JansZoro commented 6 years ago

@tockn unfortunately the code doesn't work on NodeMCU dev board V1.0. It Show values like there is no an I2C device connected.

image

tockn commented 6 years ago

hmm...
My ESP32 works perfectly this code.
Could you check your wiring? (Especially SCL and SDA)

gnaneshwar1 commented 6 years ago

/*This code actually works but prints the incrementing the gyroangle values, and goes on incrementing by 0.1 /sec or so

using esp8266 esp 01 module and mpu6050 gy521

please help*/

include

include

include

MPU6050 mpu6050(Wire);

const char ssid = "TP-LINK_ED27"; const char password = "19137216";

// Create an instance of the server // specify the port to listen on as an argument WiFiServer server(80);

void setup() { delay(1000); Wire.begin(0,2); Serial.begin(115200); delay(1000);

// Connect to WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid);

WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected");

// Start the server server.begin(); Serial.println("Server started");

// Print the IP address Serial.println(WiFi.localIP());

delay(5000);

mpu6050.begin(); delay(1000); mpu6050.calcGyroOffsets(true);

delay(1000); }

void loop() { // Check if a client has connected

WiFiClient client = server.available(); if (!client) { Serial.print("Client not connect"); delay(1000);

return;

}

// Wait until the client sends some data Serial.println("new client"); while (!client.available()) { delay(1); }

mpu6050.update(); client.print(mpu6050.getGyroAngleX()); client.print(","); client.print(mpu6050.getGyroAngleY()); client.print(","); client.println(mpu6050.getGyroAngleZ()); delay(100);

delay(1);

Serial.println("Client disonnected");

// The client will actually be disconnected // when the function returns and 'client' object is detroyed }

Catochi commented 5 years ago

Had the same issue. Fixed it by lowering the samples from 3000 to 200. In calcGyroOffsets() in MPU6050_tockn.cpp, you can limit the sampling. The ESP8266 currently has some issues with high value for loops. Hope it helps.

dzulkiflijoey commented 5 years ago

can u show me which one need to be lowering the sample from 3000 to 200??

void MPU6050::calcGyroOffsets(bool console){ float x = 0, y = 0, z = 0; int16_t rx, ry, rz;

delay(1000); if(console){ Serial.println(); Serial.println("========================================"); Serial.println("calculate gyro offsets"); Serial.print("DO NOT MOVE A MPU6050"); } for(int i = 0; i < 3000; i++){ if(console && i % 1000 == 0){ Serial.print("."); } wire->beginTransmission(MPU6050_ADDR); wire->write(0x3B); wire->endTransmission(false); wire->requestFrom((int)MPU6050_ADDR, 14, (int)true);

    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    rx = wire->read() << 8 | wire->read();
    ry = wire->read() << 8 | wire->read();
    rz = wire->read() << 8 | wire->read();

    x += ((float)rx) / 65.5;
    y += ((float)ry) / 65.5;
    z += ((float)rz) / 65.5;
}
gyroXoffset = x / 3000;
gyroYoffset = y / 3000;
gyroZoffset = z / 3000;

if(console){
Serial.println();
    Serial.println("Done!!!");
    Serial.print("X : ");Serial.println(gyroXoffset);
    Serial.print("Y : ");Serial.println(gyroYoffset);
    Serial.print("Z : ");Serial.println(gyroZoffset);
    Serial.println("Program will start after 3 seconds");
Serial.print("========================================");
    delay(3000);
}

}

Catochi commented 5 years ago

use this :

`#include "MPU6050_tockn.h"

include "Arduino.h"

MPU6050::MPU6050(TwoWire &w){ wire = &w; accCoef = 0.02f; gyroCoef = 0.98f; }

MPU6050::MPU6050(TwoWire &w, float aC, float gC){ wire = &w; accCoef = aC; gyroCoef = gC; }

void MPU6050::begin(){ writeMPU6050(MPU6050_SMPLRT_DIV, 0x00); writeMPU6050(MPU6050_CONFIG, 0x00); writeMPU6050(MPU6050_GYRO_CONFIG, 0x08); writeMPU6050(MPU6050_ACCEL_CONFIG, 0x00); writeMPU6050(MPU6050_PWR_MGMT_1, 0x01); this->update(); angleGyroX = 0; angleGyroY = 0; angleX = this->getAccAngleX(); angleY = this->getAccAngleY(); preInterval = millis(); }

void MPU6050::writeMPU6050(byte reg, byte data){ wire->beginTransmission(MPU6050_ADDR); wire->write(reg); wire->write(data); wire->endTransmission(); }

byte MPU6050::readMPU6050(byte reg) { wire->beginTransmission(MPU6050_ADDR); wire->write(reg); wire->endTransmission(true); wire->requestFrom((uint8_t)MPU6050_ADDR, (size_t)2/length/); byte data = wire->read(); wire->read(); return data; }

void MPU6050::setGyroOffsets(float x, float y, float z){ gyroXoffset = x; gyroYoffset = y; gyroZoffset = z; }

void MPU6050::calcGyroOffsets(bool console){ float x = 0, y = 0, z = 0; int16_t rx, ry, rz;

delay(1000); /if(console){ Serial.println(); Serial.println("========================================"); Serial.println("calculate gyro offsets"); Serial.print("DO NOT MOVE A MPU6050"); }/ for(int i = 0; i < 1200; i++){ if(console && i % 1000 == 0){ Serial.print("."); } wire->beginTransmission(MPU6050_ADDR); wire->write(0x3B); wire->endTransmission(false); wire->requestFrom((int)MPU6050_ADDR, 14, (int)true);

    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    wire->read() << 8 | wire->read();
    rx = wire->read() << 8 | wire->read();
    ry = wire->read() << 8 | wire->read();
    rz = wire->read() << 8 | wire->read();

    x += ((float)rx) / 65.5;
    y += ((float)ry) / 65.5;
    z += ((float)rz) / 65.5;
}
gyroXoffset = x / 1200;
gyroYoffset = y / 1200;
gyroZoffset = z / 1200;

/*if(console){
Serial.println();
    Serial.println("Done!!!");
    Serial.print("X : ");Serial.println(gyroXoffset);
    Serial.print("Y : ");Serial.println(gyroYoffset);
    Serial.print("Z : ");Serial.println(gyroZoffset);
    Serial.println("Program will start after 3 seconds");
Serial.print("========================================");
    delay(3000);
}*/

}

void MPU6050::update(){ wire->beginTransmission(MPU6050_ADDR); wire->write(0x3B); wire->endTransmission(false); wire->requestFrom((int)MPU6050_ADDR, 14, (int)true);

rawAccX = wire->read() << 8 | wire->read();
rawAccY = wire->read() << 8 | wire->read();
rawAccZ = wire->read() << 8 | wire->read();
rawTemp = wire->read() << 8 | wire->read();
rawGyroX = wire->read() << 8 | wire->read();
rawGyroY = wire->read() << 8 | wire->read();
rawGyroZ = wire->read() << 8 | wire->read();

temp = (rawTemp + 12412.0) / 340.0;

accX = ((float)rawAccX) / 16384.0;
accY = ((float)rawAccY) / 16384.0;
accZ = ((float)rawAccZ) / 16384.0;

angleAccX = atan2(accY, accZ + abs(accX)) * 360 / 2.0 / PI;
angleAccY = atan2(accX, accZ + abs(accY)) * 360 / -2.0 / PI;

gyroX = ((float)rawGyroX) / 65.5;
gyroY = ((float)rawGyroY) / 65.5;
gyroZ = ((float)rawGyroZ) / 65.5;

gyroX -= gyroXoffset;
gyroY -= gyroYoffset;
gyroZ -= gyroZoffset;

interval = (millis() - preInterval) * 0.001;

angleGyroX += gyroX * interval;
angleGyroY += gyroY * interval;
angleGyroZ += gyroZ * interval;

angleX = (gyroCoef * (angleX + gyroX * interval)) + (accCoef * angleAccX);
angleY = (gyroCoef * (angleY + gyroY * interval)) + (accCoef * angleAccY);
angleZ = angleGyroZ;

preInterval = millis();

}`

Hopefully it works for you

netpipe commented 2 years ago

https://github.com/netpipe/HappyHands/tree/main/gyroArduino/MPU6050_tockn-swire

https://www.youtube.com/watch?v=Li6GyubiEls