robtillaart / gy521 Goto Github PK
View Code? Open in Web Editor NEWArduino library for GY521 accelerometer- gyroscope a.k.a. MCU-6050
License: MIT License
Arduino library for GY521 accelerometer- gyroscope a.k.a. MCU-6050
License: MIT License
The getRegister() function can fail and should set an error flag.
This should be handled better in the library.
Although chances are pretty small I2C errors can occur due to noise or whatever.
need to add
Using the library with and Arduino NANO works fine. I'm plotting getAccelX, getAccelY, getAccelZ on a serial plotter and values are as expected (+1 / -1 for gradually changing position.
However, using a teensy 3.2 the same code produces very wrong results. The issue is with how the ints are treated on a 32 bit MCU, easy fix, here's how....
replace any int with int16_t and add the uint16_t to the entire value
_ax = ( ( ((int)Wire.read()) << 8) | Wire.read() ); // ACCEL_XOUT_H ACCEL_XOUT_L
final code
_ax = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // ACCEL_XOUT_H ACCEL_XOUT_L
_ay = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // ACCEL_YOUT_H ACCEL_YOUT_L
_az = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // ACCEL_ZOUT_H ACCEL_ZOUT_L
// TEMPERATURE
_temperature = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // TEMP_OUT_H TEMP_OUT_L
// GYROSCOPE
_gx = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // GYRO_XOUT_H GYRO_XOUT_L
_gy = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // GYRO_YOUT_H GYRO_YOUT_L
_gz = (int16_t)(((int16_t)Wire.read() << 8) | Wire.read()) ; // GYRO_ZOUT_H GYRO_ZOUT_L
This code works on Arduino NANO and Teensy 3.2
It's difficult to describe the issue in words, so I made an illustration of it.
The following output is from the GY521_pitch_roll_yaw example after calibration. The actual pitch and roll movement was gradual and slow. From line 34 to 35, the measured pitch shifts by around -17. A similar shift occurs in the roll from line 36 to 37.
CNT PITCH ROLL YAW
30 0.772 345.005 358.791
31 0.669 344.142 358.607
32 0.797 342.071 358.438
33 0.244 338.645 358.423
34 0.171 335.321 358.668
35 343.608 341.118 357.288
36 341.322 342.920 355.539
37 342.271 2.811 354.572
38 342.297 1.450 354.143
39 342.342 2.843 353.974
I'm not sure why this behavior happens, but I assume that the problem is caused by this library, since it does the computation of pitch/roll/yaw from the raw sensor output. I'm using version 0.3.9.
added the image for future reference
Right now:
GY521_readCalibration_2 generate calibration code snippet.
User need to manually copy & paste the data numbers, e.g. into application code, e.g. GY521_pitch_roll_yaw.
It's better to move GY521_readCalibration_2 (generate calibration code snippet) into a proper calibrate()
function, as part of GY521 init, so the user can just call:
void setup()
...
sensor.calibrate(optional_n_times_counter=100); // easy init
}
See line 38
bool isConnected()
missing ;
I didn't move my chip, but:
...
CNT PITCH ROLL YAW
97940 68.228 70.984 113.046
97941 68.247 71.046 113.051
97942 68.247 71.046 113.051
97943 68.247 71.046 113.051
97944 68.247 71.046 113.051
97945 68.263 71.107 113.057
97946 68.263 71.107 113.057
97947 68.263 71.107 113.057
97948 68.263 71.107 113.057
97949 68.279 71.166 113.061
CNT PITCH ROLL YAW
97950 68.279 71.166 113.061
CNT PITCH ROLL YAW
130150 215.906 233.981 152.385
130151 215.906 233.981 152.385
130152 215.924 234.042 152.390
130153 215.924 234.042 152.390
130154 215.924 234.042 152.390
130155 215.924 234.042 152.390
130156 215.942 234.107 152.395
130157 215.942 234.107 152.395
130158 215.942 234.107 152.395
130159 215.955 234.159 152.399
it goes on and on.
int ax = sensor.getAccelX();
int ay = sensor.getAccelY();
int az = sensor.getAccelZ();
int gx = sensor.getGyroX();
int gy = sensor.getGyroY();
int gz = sensor.getGyroZ();
int t = sensor.getTemperature();
change to float would give more info about the noise.
print it with 3 decimals.
issue split of from #22
use micros() for the duration to correct pitch yaw etc.
NB with a throttle of 10 millis the accuracy of millis is typically in 2 decimals.
By using micros() one would expect one or two additional digits accuracy.
The gain will be that the duration of a force will become accurate in 0.1 or 0.01 of a millisecond.
Need to investigate how this affects the math.
Examples use GetAngle
instead of GetAccel
leading to the calibration giving NaN
for all accelerometer values
In line 90 is says "aze" and should be "gze".
Serial.print("sensor.aze = ");
to
Serial.print("sensor.gze = ");
Best regards
https://github.com/netpipe/Arduino-Projects/tree/master/libs/GY521
other than version information it should be the same with swire support. thanks.
hi,
I thought my board was broken, but if you read out the data manually, I get values back.
Unfortunately, with the test1 example, I only get zeros and short deflections when I move it strongly. only the temperature value works properly.
until I found out that you don't get the raw data but a calculated value.
I then built myself functions that give me the raw value, I think it would be good to add that.
the variables also have the name raw but do not contain the raw data.
I think that would help many and also mention it in the explanation.
otherwise a very good library and i hope this is a good suggestion.
Greetings orichienal
There are 3 hypot() calls in read(). These can be replaced by the equivalent
float a2 = a * a;
float b2 = b * b;
float c2 = c * c;
x = sqrt(a2 + b2);
y = sqrt(b2 + c2);
z = sqrt(c2 + a2);
advantage is a slightly 26 us faster read() on an UNO (163 us -> 137 us) as squares are only calculated once, and smaller size ~258 bytes ~ (number based upon test sketch).
use micros() for the duration to correct pitch yaw etc.
NB with a throttle of 10 millis the accuracy of millis is typically in 2 decimals.
By using micros() one would expect one or two additional digits accuracy.
The datasheet explained that we can write into the Interrupt Configuration Register to enable interrupts. And then read into the Interrupt Status Register.
Is that possible to make that from your library ?
Need a begin(sda, scl) function for ESP32 and ESP8266
Nice library! I just woul like to have a dedicated function to set/get the digital low pass filter mode. Something like setDLPFmode and getDLPFmode.
In the mean time, I will directly get/set the register, but a new function looks nicer.
Thanks!
Hello!
Great work on the library, very useful for getting prototypes done, however, I would like to know if there is any way to make the return of the functions getYaw, getPitch and getRoll to clamp to 360 degrees? I have a device that continuously rotates in one direction (quickly), I don't know if waiting for a float overflow to reset the counter is a good idea.
13:04:18.394 -> ACCELEROMETER GYROSCOPE TEMPERATURE
13:04:18.394 -> -8.040 2.777 -500.143 0.568 -2.084 1.113
13:04:18.394 -> axe aye aze gxe gye gze T
13:04:18.394 -> 480 -0.018 0.005 -1.042 0.019 0.041 0.013 39.77
13:04:18.584 -> 481 -0.016 0.006 -1.042 -0.029 -0.003 -0.050 39.84
13:04:18.725 -> 482 -0.017 0.006 -1.042 0.005 0.020 0.072 39.79
13:04:18.863 -> 483 -0.017 0.006 -1.042 0.042 -0.053 -0.061 39.83
13:04:19.049 -> 484 -0.017 0.006 -1.043 -0.041 0.048 0.060 39.77
13:04:19.187 -> 485 -0.017 0.007 -1.042 0.013 0.001 -0.018 39.82
13:04:19.378 -> 486 -0.017 0.006 -1.042 0.034 -0.045 -0.005 39.82
13:04:19.556 -> 487 -0.017 0.007 -1.042 -0.049 0.002 0.036 39.80
13:04:19.704 -> 488 -0.016 0.006 -1.043 0.017 0.013 -0.014 39.82
13:04:19.844 -> 489 -0.016 0.006 -1.044 0.035 -0.029 -0.034 39.77
...
13:11:07.122 -> ACCELEROMETER GYROSCOPE TEMPERATURE
13:11:07.122 -> -53.020 16.354 -3115.312 0.550 -2.084 1.194
13:11:07.122 -> axe aye aze gxe gye gze T
13:11:07.122 -> 2990 -0.022 0.004 -1.042 0.023 0.038 -0.060 39.82
13:11:07.259 -> 2991 -0.020 0.004 -1.043 0.005 0.027 -0.027 39.84
13:11:07.446 -> 2992 -0.021 0.003 -1.043 -0.006 -0.040 0.068 39.80
13:11:07.586 -> 2993 -0.020 0.004 -1.042 0.021 -0.018 -0.088 39.81
13:11:07.773 -> 2994 -0.021 0.005 -1.042 0.008 -0.003 0.047 39.85
13:11:07.915 -> 2995 -0.020 0.005 -1.043 -0.038 0.004 -0.016 39.82
13:11:08.102 -> 2996 -0.021 0.004 -1.043 0.026 0.019 0.023 39.78
13:11:08.242 -> 2997 -0.020 0.003 -1.043 0.000 -0.017 -0.040 39.82
13:11:08.430 -> 2998 -0.021 0.004 -1.042 -0.025 0.039 0.042 39.80
13:11:08.572 -> 2999 -0.021 0.003 -1.041 0.037 -0.021 -0.018 39.83
In my case, the values for the accel and gyro switched.
I like this library. But... I need to get angles from 2 GY521.. How can I do it?
0x68 & 0x69
low prio, just comment.
allow to set Wire Wire1 Wire2 etc
whith out the code bellow i am getting invalid data when starting up the sensor
Wire.write(0x6B); //make the reset (place a 0 into the 6B register)
Wire.write(0x00);
Wire.endTransmission(true); //end the transmission
we need to reset the MPU6050 before we set any other register
this is coded in your function bool GY521::wakeup()
we need to call this after begin() before we read() any data.
Please verify and include this Readme if needed !!
void GY521::setAccelSensitivity(uint8_t as)
{
if (as > 3) as = 3;
uint8_t val = getRegister(GY521_ACCEL_CONFIG);
val &= 0xE7;
val |= (as << 3);
setRegister(GY521_ACCEL_CONFIG, val);
// calculate conversion factor.
_raw2g = 16384.0;
for (uint8_t i = 0; i < _afs; i++) _raw2g *= 0.5;
_raw2g = 1.0 / _raw2g;
}
_afs is zero-defined.
the corrected version should be like this.
void GY521::setAccelSensitivity(uint8_t as)
{
_afs = as;
if (_afs > 3) _afs = 3;
uint8_t val = getRegister(GY521_ACCEL_CONFIG);
val &= 0xE7;
val |= (_afs << 3);
setRegister(GY521_ACCEL_CONFIG, val);
// calculate conversion factor.
_raw2g = 16384.0;
for (uint8_t i = 0; i < _afs; i++) _raw2g *= 0.5;
_raw2g = 1.0 / _raw2g;
}
am I right?
Needed for project.
was trying to get some mouse position movement data for the screen trying to get acceleration over time maybe someone knows a trick for this with multiple sensors perhaps ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.