Skip to content

Commit

Permalink
Add readAccell(), readGyro and readTemperature() (#35)
Browse files Browse the repository at this point in the history
* add readAccel() readGyro() readTemperature()
* update readme.md
* rename examples
  • Loading branch information
RobTillaart authored Jul 27, 2022
1 parent d85def3 commit 39b52fb
Show file tree
Hide file tree
Showing 13 changed files with 423 additions and 35 deletions.
153 changes: 152 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.3.6
// VERSION: 0.3.7
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
// URL: https://github.com/RobTillaart/GY521
//
Expand All @@ -12,18 +12,23 @@
// 0.1.3 2020-08-07 fix ESP support + pitch roll yaw demo
// 0.1.4 2020-09-29 fix #5 missing ;
// 0.1.5 2020-09-29 fix #6 fix maths for Teensy
//
// 0.2.0 2020-11-03 improve error handling
// 0.2.1 2020-12-24 Arduino-CI + unit tests
// 0.2.2 2021-01-24 add interface part to readme.md
// add GY521_registers.h
// 0.2.3 2021-01-26 align version numbers (oops)
//
// 0.3.0 2021-04-07 fix #18 acceleration error correction (kudo's to Merkxic)
// 0.3.1 2021-06-13 added more unit test + some initialization
// 0.3.2 2021-07-05 fix #20 support multiWire
// 0.3.3 2021-07-05 fix #22 improve maths
// 0.3.4 2021-07-12 fix #24 improve precision
// 0.3.5 2021-10-20 update build-CI, badges + #28 add wakeup to begin().
// 0.3.6 2021-12-18 update library.json, license, minor edits
// 0.3.7 2022-07-26 add partial reads readAccel(),
// readGyro() and readTemperature()
// rename + add GY521_LIB_VERSION to examples.


#include "GY521.h"
Expand Down Expand Up @@ -198,6 +203,152 @@ int16_t GY521::read()
}


int16_t GY521::readAccel()
{
uint32_t now = millis();
if (_throttle)
{
if ((now - _lastTime) < _throttleTime)
{
// not an error.
return GY521_THROTTLED;
}
}
_lastTime = now;

// Connected ?
_wire->beginTransmission(_address);
_wire->write(GY521_ACCEL_XOUT_H);
if (_wire->endTransmission() != 0)
{
_error = GY521_ERROR_WRITE;
return _error;
}

// Get the data
int8_t n = _wire->requestFrom(_address, (uint8_t)6);
if (n != 6)
{
_error = GY521_ERROR_READ;
return _error;
}
// ACCELEROMETER
_ax = _WireRead2(); // ACCEL_XOUT_H ACCEL_XOUT_L
_ay = _WireRead2(); // ACCEL_YOUT_H ACCEL_YOUT_L
_az = _WireRead2(); // ACCEL_ZOUT_H ACCEL_ZOUT_L

// next lines might be merged per axis.

// Convert raw acceleration to g's
_ax *= _raw2g;
_ay *= _raw2g;
_az *= _raw2g;

// Error correct raw acceleration (in g) measurements // #18 kudos to Merkxic
_ax += axe;
_ay += aye;
_az += aze;

// prepare for Pitch Roll Yaw
float _ax2 = _ax * _ax;
float _ay2 = _ay * _ay;
float _az2 = _az * _az;

_aax = atan( _ay / sqrt(_ax2 + _az2)) * RAD2DEGREES;
_aay = atan(-1.0 * _ax / sqrt(_ay2 + _az2)) * RAD2DEGREES;
_aaz = atan( _az / sqrt(_ax2 + _ay2)) * RAD2DEGREES;
// optimize #22
// _aax = atan(_ay / hypot(_ax, _az)) * RAD2DEGREES;
// _aay = atan(-1.0 * _ax / hypot(_ay, _az)) * RAD2DEGREES;
// _aaz = atan(_az / hypot(_ax, _ay)) * RAD2DEGREES;

return GY521_OK;
}


int16_t GY521::readGyro()
{
uint32_t now = millis();
if (_throttle)
{
if ((now - _lastTime) < _throttleTime)
{
// not an error.
return GY521_THROTTLED;
}
}
_lastTime = now;

// Connected ?
_wire->beginTransmission(_address);
_wire->write(GY521_GYRO_XOUT_H);
if (_wire->endTransmission() != 0)
{
_error = GY521_ERROR_WRITE;
return _error;
}

// Get the data
int8_t n = _wire->requestFrom(_address, (uint8_t)6);
if (n != 6)
{
_error = GY521_ERROR_READ;
return _error;
}
// GYROSCOPE
_gx = _WireRead2(); // GYRO_XOUT_H GYRO_XOUT_L
_gy = _WireRead2(); // GYRO_YOUT_H GYRO_YOUT_L
_gz = _WireRead2(); // GYRO_ZOUT_H GYRO_ZOUT_L

// duration interval
now = micros();
float duration = (now - _lastMicros) * 1e-6; // duration in seconds.
_lastMicros = now;

// next lines might be merged per axis.

// Convert raw Gyro to degrees/seconds
_gx *= _raw2dps;
_gy *= _raw2dps;
_gz *= _raw2dps;

// Error correct raw gyro measurements.
_gx += gxe;
_gy += gye;
_gz += gze;

_gax += _gx * duration;
_gay += _gy * duration;
_gaz += _gz * duration;

return GY521_OK;
}


int16_t GY521::readTemperature()
{
// DO NOT THROTTLE
_wire->beginTransmission(_address);
_wire->write(GY521_TEMP_OUT_H);
if (_wire->endTransmission() != 0)
{
_error = GY521_ERROR_WRITE;
return _error;
}

// Get the data
int8_t n = _wire->requestFrom(_address, (uint8_t)2);
if (n != 2)
{
_error = GY521_ERROR_READ;
return _error;
}
// TEMPERATURE
_temperature = _WireRead2(); // TEMP_OUT_H TEMP_OUT_L
return GY521_OK;
}


bool GY521::setAccelSensitivity(uint8_t as)
{
_afs = as;
Expand Down
39 changes: 24 additions & 15 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.3.6
// VERSION: 0.3.7
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
// URL: https://github.com/RobTillaart/GY521
//
Expand All @@ -15,15 +15,15 @@
#include "Wire.h"


#define GY521_LIB_VERSION (F("0.3.6"))
#define GY521_LIB_VERSION (F("0.3.7"))


#ifndef GY521_THROTTLE_TIME
#define GY521_THROTTLE_TIME 10 // milliseconds
#endif


// ERROR CODES
// ERROR CODES
#define GY521_OK 0
#define GY521_THROTTLED 1
#define GY521_ERROR_READ -1
Expand All @@ -46,26 +46,35 @@ class GY521


bool wakeup();
// throttle to force delay between reads.
// 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; };


// returns GY521_OK or one of the error codes above.
// READ THE SENSOR
// returns GY521_OK or one of the error codes above.
int16_t read();

// SET BEFORE READ
// as = 0,1,2,3 ==> 2g 4g 8g 16g
// optimized partial reading
// read accelerometer only
int16_t readAccel();
// read gyroscope only can be done too
// however for pitch roll yaw you need all.
int16_t readGyro();
// read temperature only, does not affect throttle.
int16_t readTemperature();

// SET BEFORE READ
// as = 0,1,2,3 ==> 2g 4g 8g 16g
bool setAccelSensitivity(uint8_t as);
uint8_t getAccelSensitivity(); // returns 0,1,2,3
// gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
// gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
bool setGyroSensitivity(uint8_t gs);
uint8_t getGyroSensitivity(); // returns 0,1,2,3

// CALL AFTER READ
// CALL AFTER READ
float getAccelX() { return _ax; };
float getAccelY() { return _ay; };
float getAccelZ() { return _az; };
Expand All @@ -81,20 +90,20 @@ class GY521
float getYaw() { return _yaw; };


// last time sensor is actually read.
// last time sensor is actually read.
uint32_t lastTime() { return _lastTime; };


// generic worker to get access to all functionality
// generic worker to get access to all functionality
uint8_t setRegister(uint8_t reg, uint8_t value);
uint8_t getRegister(uint8_t reg);


// get last error and reset error to OK.
// get last error and reset error to OK.
int16_t getError() { return _error; _error = GY521_OK; };


// calibration errors
// calibration errors
float axe = 0, aye = 0, aze = 0; // accelerometer errors
float gxe = 0, gye = 0, gze = 0; // gyro errors

Expand Down
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,20 @@ AD0 connected to VCC => 0x69
- **bool setAccelSensitivity(uint8_t as)** as = 0, 1, 2, 3 ==> 2g 4g 8g 16g
- **uint8_t getAccelSensitivity()** returns 0, 1, 2, 3
- **bool setGyroSensitivity(uint8_t gs)** gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
- **uint8_t getGyroSensitivity()** returns 0, 1, 2, 3
- **uint8_t getGyroSensitivity()** returns 0, 1, 2, 3


#### Actual read

- **int16_t read()** returns ...
- **uint32_t lastTime()** last time sensor is actually read. In milliseconds.
- **int16_t read()** 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.
returns status = GY521_OK on success.
Note: for pitch roll yaw you need to call **read()**.
- **int16_t readTemperature()** read temperature only, does **not** update the throttle timer.
returns status = GY521_OK on success.
- **uint32_t lastTime()** last time sensor is actually read. In milliseconds. Not updated by readTemperature().


#### Call after read
Expand Down Expand Up @@ -144,5 +151,4 @@ See examples, use with care
**Could**
- calibrate function in the lib ? (think not as lib might grow?)
- calibrate sketch could print code snippet to include...
- option to read only Accel?
- option to read only Gyro?

74 changes: 74 additions & 0 deletions examples/GY521_angle/GY521_angle.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// FILE: GY521_angle.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo pitch roll yaw
// DATE: 2022-06-06


#include "GY521.h"

GY521 sensor(0x68);

uint32_t counter = 0;


void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("GY521_LIB_VERSION: ");
Serial.println(GY521_LIB_VERSION);

Wire.begin();

delay(100);
while (sensor.wakeup() == false)
{
Serial.print(millis());
Serial.println("\tCould not connect to GY521");
delay(1000);
}
sensor.setAccelSensitivity(2); // 8g
sensor.setGyroSensitivity(1); // 500 degrees/s

sensor.setThrottle();
Serial.println("start...");

// set calibration values from calibration sketch.
sensor.axe = 0.574;
sensor.aye = -0.002;
sensor.aze = -1.043;
sensor.gxe = 10.702;
sensor.gye = -6.436;
sensor.gze = -0.676;
}


void loop()
{
sensor.read();
float x = sensor.getAngleX();
float y = sensor.getAngleY();
float z = sensor.getAngleZ();

if (counter % 10 == 0)
{
// Serial.println("\nCNT\tX\tY\tZ");
}

//Serial.print(counter);
//Serial.print('\t');
Serial.print(x, 1);
Serial.print('\t');
Serial.print(y, 1);
Serial.print('\t');
Serial.print(z, 1);
Serial.println();

counter++;
}


// -- END OF FILE --

3 changes: 3 additions & 0 deletions examples/GY521_performance/GY521_performance.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ uint32_t counter = 0;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("GY521_LIB_VERSION: ");
Serial.println(GY521_LIB_VERSION);

Wire.begin();

Expand Down
Loading

0 comments on commit 39b52fb

Please sign in to comment.