Skip to content

Commit

Permalink
update example / documentation (#49)
Browse files Browse the repository at this point in the history
- fix #48, use float variables in example GY521_test_1.ino
- add **void calibrate(uint16_t times)** to API
- add **GY521_performance_calibrate.ino** example
- add **GY521_raw_cooked.ino** example
- make explicit that pitch roll yaw is work in progress.
- update readme.md
  - calibrate section
  - add some tables
- minor edits in examples
  • Loading branch information
RobTillaart authored Jan 18, 2024
1 parent 4fc890a commit 1c2e645
Show file tree
Hide file tree
Showing 17 changed files with 392 additions and 55 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.5.2] - 2024-01-16
- fix #48, use float variables in example GY521_test_1.ino
- add **void calibrate(uint16_t times)** to API
- add **GY521_performance_calibrate.ino** example
- add **GY521_raw_cooked.ino** example
- make explicit that pitch roll yaw is work in progress.
- update readme.md
- calibrate section
- add some tables
- minor edits in examples


## [0.5.1] - 2023-12-11
- redo initialization order.


## [0.5.0] - 2023-12-05
- refactor API, begin()
- update readme.md
Expand Down
43 changes: 42 additions & 1 deletion GY521.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: GY521.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.5.1
// VERSION: 0.5.2
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
// URL: https://github.com/RobTillaart/GY521

Expand Down Expand Up @@ -66,6 +66,41 @@ void GY521::reset()
}


void GY521::calibrate(uint16_t times)
{
// disable throttling / caching of read values.
bool oldThrottle = _throttle;
_throttle = false;

// set errors to zero
axe = aye = aze = 0;
gxe = gye = gze = 0;

for (uint16_t i = 0; i < times; i++)
{
read();
axe -= getAccelX();
aye -= getAccelY();
aze -= getAccelZ();
gxe -= getGyroX();
gye -= getGyroY();
gze -= getGyroZ();
}

// adjust calibration errors so table should get all zero's.
float factor = 1.0 / times;
axe *= factor;
aye *= factor;
aze *= factor;
gxe *= factor;
gye *= factor;
gze *= factor;

// restore throttle state
_throttle = oldThrottle;
}


bool GY521::wakeup()
{
_wire->beginTransmission(_address);
Expand Down Expand Up @@ -138,6 +173,7 @@ int16_t GY521::read()
float _ay2 = _ay * _ay;
float _az2 = _az * _az;

// calculate angle
_aax = atan( _ay / sqrt(_ax2 + _az2)) * GY521_RAD2DEGREES;
_aay = atan(-1.0 * _ax / sqrt(_ay2 + _az2)) * GY521_RAD2DEGREES;
_aaz = atan( _az / sqrt(_ax2 + _ay2)) * GY521_RAD2DEGREES;
Expand All @@ -159,10 +195,13 @@ int16_t GY521::read()
_gy += gye;
_gz += gze;

// integrate gyroscope data
_gax += _gx * duration;
_gay += _gy * duration;
_gaz += _gz * duration;

// experimental below this line.
// Pitch Roll Yaw are work in progress
// normalize
// _gax etc might loose precision after many iterations #36
if (_normalize)
Expand Down Expand Up @@ -250,6 +289,7 @@ int16_t GY521::readAccel()
float _ay2 = _ay * _ay;
float _az2 = _az * _az;

// calculate angles.
_aax = atan( _ay / sqrt(_ax2 + _az2)) * GY521_RAD2DEGREES;
_aay = atan(-1.0 * _ax / sqrt(_ay2 + _az2)) * GY521_RAD2DEGREES;
_aaz = atan( _az / sqrt(_ax2 + _ay2)) * GY521_RAD2DEGREES;
Expand Down Expand Up @@ -318,6 +358,7 @@ int16_t GY521::readGyro()
_gaz += _gz * duration;


// experimental below this line.
// normalize
// _gax etc might loose precision after many iterations #36
if (_normalize)
Expand Down
16 changes: 12 additions & 4 deletions GY521.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: GY521.h
// AUTHOR: Rob Tillaart
// VERSION: 0.5.1
// VERSION: 0.5.2
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
// URL: https://github.com/RobTillaart/GY521

Expand All @@ -11,7 +11,7 @@
#include "Wire.h"


#define GY521_LIB_VERSION (F("0.5.1"))
#define GY521_LIB_VERSION (F("0.5.2"))


// THROTTLE TIMING
Expand All @@ -37,18 +37,23 @@
class GY521
{
public:
GY521(uint8_t address = 0x69, TwoWire *wire = &Wire); // 0x68 or 0x69
// address == 0x68 or 0x69
GY521(uint8_t address = 0x69, TwoWire *wire = &Wire);

bool begin();
bool isConnected();
void reset();

// EXPERIMENTAL
// calibrate needs to be called to compensate for errors.
// must be called after setAccelSensitivity(as); and setGyroSensitivity(gs);
void calibrate(uint16_t times);

bool wakeup();
// throttle to force delay between reads.
void setThrottle(bool throttle = true) { _throttle = throttle; };
bool getThrottle() { return _throttle; };
// 0..65535 (max milliseconds == roughly 1 minute.
// 0..65535 max milliseconds == roughly 1 minute.
void setThrottleTime(uint16_t ti ) { _throttleTime = ti; };
uint16_t getThrottleTime() { return _throttleTime; };

Expand Down Expand Up @@ -89,6 +94,9 @@ class GY521
float getGyroX() { return _gx; };
float getGyroY() { return _gy; };
float getGyroZ() { return _gz; };

// EXPERIMENTAL
// pitch, roll and yaw is work in progress.
float getPitch() { return _pitch; };
float getRoll() { return _roll; };
float getYaw() { return _yaw; };
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017-2023 Rob Tillaart
Copyright (c) 2017-2024 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
113 changes: 101 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ Arduino library for I2C GY521 accelerometer-gyroscope sensor a.k.a. MCU-6050.

## Description

Experimental library for GY521 a.k.a. MCU-6050.
**Experimental** library for GY521 a.k.a. MCU-6050.

Library is work in progress, in fact it is extracted and extended from an old project.
It needs to be tested a lot more.

See changelog.md for latest updates.


#### 0.5.0 Breaking change

Version 0.5.0 introduced a breaking change.
Expand All @@ -35,12 +36,25 @@ before calling **begin()**.
#### Examples

- **GY521_angle** read angleX, angleY, angleZ.
- **GY521_performance_calibrate.ino** determine calibration performance.
- **GY521_performance** measure performance.
- **GY521_pitch_roll_yaw** to get pitch roll yaw.
- **GY521_readCalibration_1** read calibration values / errors for a flat sensor.
- **GY521_raw_cooked** make a table of raw measurements and derived data
for analysis e.g. in a spreadsheet.
- **GY521_readCalibration_1** read calibration values / errors for a "flat" sensor.
- **GY521_readCalibration_2** generate calibration code snippet.
- **GY521_test_1** test working of the sensor.
- **GY521_test_2** test set/get functions.
- **GY521_test_2** test set/get functions (sort of unit test).
- **GY521_two_sensors** demo for two sensors.


#### Related

- https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
- https://cdn.sparkfun.com/datasheets/Sensors/Accelerometers/RM-MPU-6000A.pdf register map.
- https://github.com/RobTillaart/Angle
- https://github.com/RobTillaart/AngleConverter



## Breakout board
Expand All @@ -67,6 +81,16 @@ AD0 connected to VCC => 0x69

## Calibration (short version for now)

Since version 0.5.2 the library has a build in **void calibrate(times)** function which
can be called instead of manual calibration.
This function overwrites the values of axe aye aze gxe gye gze.
**calibrate()** must be called after **setAccelSensitivity(as)** and **setGyroSensitivity(gs)**.

Note the **calibrate()** function takes time, depending on the number of times.


#### Manual calibration

1. load and run calibration example
it shows a header containing 6 numbers and 10 lines of 8 numbers
1. wait until the middle 6 of the longer lines stabilize (should all be 0)
Expand All @@ -90,6 +114,18 @@ Note call **Wire.begin()** before **begin()**.
- **bool wakeUp()** idem.


### Calibrate

- **void calibrate(uint16_t times)** This function overwrites the values of axe aye aze gxe gye gze.
To get "quality error" offsets, the GY521 sensor should not move during the calibration.
The parameter times determines the number of measurements made.
Typical values are 100 or more.
Please note this is a time consuming function.

Ideal the function **calibrate()** should continue until it is stable (how to define) for n reads.
Drawback is that this would make the duration unpredictable.


### Throttle

- **void setThrottle(bool throttle = true)** throttle to force "delay" between reads.
Expand All @@ -112,7 +148,8 @@ Note call **Wire.begin()** before **begin()**.

#### Actual read

- **int16_t read()** returns status = GY521_OK on success.
- **int16_t read()** reads all core measurements.
returns status = GY521_OK on success.
- **int16_t readAccel()** read accelerometer only to speed up interaction. This call does update the throttle timer.
returns status = GY521_OK on success.
- **int16_t readGyro()** read gyroscope only to speed up interaction. This call does update the throttle timer.
Expand All @@ -132,7 +169,8 @@ In version 0.4.0 the normalization of pitch, roll and yaw is fixed and made cond

#### Calls after read

Note that multiple calls will return the same value. One must explicitly call **read()** to get new values.
Note that multiple calls will return the same value.
One must explicitly call **read()** to get new values.

- **float getAccelX()** idem.
- **float getAccelY()** idem.
Expand All @@ -144,6 +182,12 @@ Note that multiple calls will return the same value. One must explicitly call **
- **float getGyroX()** idem.
- **float getGyroY()** idem.
- **float getGyroZ()** idem.


#### Experimental Pitch Roll and Yaw

Pitch Roll and Yaw is work in progress and should not be used for projects yet.

- **float getPitch()** idem. May return any number.
If **setNormalize(true)** return value will be 0-359.999
- **float getRoll()** idem. May return any number.
Expand All @@ -160,34 +204,76 @@ Read the register PDF for the specific value and meaning of registers.
- **uint8_t getRegister(uint8_t reg)**


## documents
## Documents

- check details registers - MPU-6000-Register-Map1.pdf


#### Error codes

| Error code | value | notes |
|:----------------------------|:-------:|:-------:|
| GY521_OK | 0 | not an error
| GY521_THROTTLED | 1 | not an error
| GY521_ERROR_READ | -1 |
| GY521_ERROR_WRITE | -2 |
| GY521_ERROR_NOT_CONNECTED | -3 |


- check details - MPU-6000-Register-Map1.pdf
#### Sensitivity Acceleration

unit g = gravity == 9.81 m/s^2

| Acceleration | value | notes |
|:--------------|:-------:|:-------:|
| 2 g | 0 | default
| 4 g | 1 |
| 8 g | 2 |
| 16 g | 3 |


#### Sensitivity Gyroscope

unit dps = degrees per second.

| Gyroscope | value | notes |
|:--------------|:-------:|:-------:|
| 250 dps | 0 | default
| 500 dps | 1 |
| 1000 dps | 2 |
| 2000 dps | 3 |


## Operation

See examples, use with care
See examples, use with care.


## Future

#### Must

- time
- improve documentation
- add tables where appropriate
- sensitivity, error codes etc
- investigate Pitch Roll and Yaw math in detail.
- investigate math needed.
- implementation.
- when?
- test test and test ...(ESP too)

#### Should

- add performance sketch
- test **calibrate()** function for different sensitivities.

#### Could

- calibrate sketch could print code snippet to include...
- add examples
- improve unit tests?
- reorder code in read(), would that save some micros.?
- first all ax, then ay etc
- footprint / performance gain?
- make enum for sensitivity Accel?
- make enum for sensitivity Gyro?

#### Wont

Expand All @@ -196,6 +282,9 @@ See examples, use with care
- other ideas affect accuracy, so unless new ideas arise.
- calibrate function in the lib
- not as lib will grow too large.
- defaults value for functions?
- user must set function parameters explicit


## Support

Expand Down
2 changes: 1 addition & 1 deletion examples/GY521_angle/GY521_angle.ino
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void setup()
while (sensor.wakeup() == false)
{
Serial.print(millis());
Serial.println("\tCould not connect to GY521");
Serial.println("\tCould not connect to GY521: please check the GY521 address (0x68/0x69)");
delay(1000);
}
sensor.setAccelSensitivity(2); // 8g
Expand Down
Loading

0 comments on commit 1c2e645

Please sign in to comment.