Skip to content

Commit 5621101

Browse files
committed
0.3.7 GY521
1 parent bca8166 commit 5621101

File tree

13 files changed

+423
-35
lines changed

13 files changed

+423
-35
lines changed

libraries/GY521/GY521.cpp

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: GY521.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.3.6
4+
// VERSION: 0.3.7
55
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
66
// URL: https://github.com/RobTillaart/GY521
77
//
@@ -12,18 +12,23 @@
1212
// 0.1.3 2020-08-07 fix ESP support + pitch roll yaw demo
1313
// 0.1.4 2020-09-29 fix #5 missing ;
1414
// 0.1.5 2020-09-29 fix #6 fix maths for Teensy
15+
//
1516
// 0.2.0 2020-11-03 improve error handling
1617
// 0.2.1 2020-12-24 Arduino-CI + unit tests
1718
// 0.2.2 2021-01-24 add interface part to readme.md
1819
// add GY521_registers.h
1920
// 0.2.3 2021-01-26 align version numbers (oops)
21+
//
2022
// 0.3.0 2021-04-07 fix #18 acceleration error correction (kudo's to Merkxic)
2123
// 0.3.1 2021-06-13 added more unit test + some initialization
2224
// 0.3.2 2021-07-05 fix #20 support multiWire
2325
// 0.3.3 2021-07-05 fix #22 improve maths
2426
// 0.3.4 2021-07-12 fix #24 improve precision
2527
// 0.3.5 2021-10-20 update build-CI, badges + #28 add wakeup to begin().
2628
// 0.3.6 2021-12-18 update library.json, license, minor edits
29+
// 0.3.7 2022-07-26 add partial reads readAccel(),
30+
// readGyro() and readTemperature()
31+
// rename + add GY521_LIB_VERSION to examples.
2732

2833

2934
#include "GY521.h"
@@ -198,6 +203,152 @@ int16_t GY521::read()
198203
}
199204

200205

206+
int16_t GY521::readAccel()
207+
{
208+
uint32_t now = millis();
209+
if (_throttle)
210+
{
211+
if ((now - _lastTime) < _throttleTime)
212+
{
213+
// not an error.
214+
return GY521_THROTTLED;
215+
}
216+
}
217+
_lastTime = now;
218+
219+
// Connected ?
220+
_wire->beginTransmission(_address);
221+
_wire->write(GY521_ACCEL_XOUT_H);
222+
if (_wire->endTransmission() != 0)
223+
{
224+
_error = GY521_ERROR_WRITE;
225+
return _error;
226+
}
227+
228+
// Get the data
229+
int8_t n = _wire->requestFrom(_address, (uint8_t)6);
230+
if (n != 6)
231+
{
232+
_error = GY521_ERROR_READ;
233+
return _error;
234+
}
235+
// ACCELEROMETER
236+
_ax = _WireRead2(); // ACCEL_XOUT_H ACCEL_XOUT_L
237+
_ay = _WireRead2(); // ACCEL_YOUT_H ACCEL_YOUT_L
238+
_az = _WireRead2(); // ACCEL_ZOUT_H ACCEL_ZOUT_L
239+
240+
// next lines might be merged per axis.
241+
242+
// Convert raw acceleration to g's
243+
_ax *= _raw2g;
244+
_ay *= _raw2g;
245+
_az *= _raw2g;
246+
247+
// Error correct raw acceleration (in g) measurements // #18 kudos to Merkxic
248+
_ax += axe;
249+
_ay += aye;
250+
_az += aze;
251+
252+
// prepare for Pitch Roll Yaw
253+
float _ax2 = _ax * _ax;
254+
float _ay2 = _ay * _ay;
255+
float _az2 = _az * _az;
256+
257+
_aax = atan( _ay / sqrt(_ax2 + _az2)) * RAD2DEGREES;
258+
_aay = atan(-1.0 * _ax / sqrt(_ay2 + _az2)) * RAD2DEGREES;
259+
_aaz = atan( _az / sqrt(_ax2 + _ay2)) * RAD2DEGREES;
260+
// optimize #22
261+
// _aax = atan(_ay / hypot(_ax, _az)) * RAD2DEGREES;
262+
// _aay = atan(-1.0 * _ax / hypot(_ay, _az)) * RAD2DEGREES;
263+
// _aaz = atan(_az / hypot(_ax, _ay)) * RAD2DEGREES;
264+
265+
return GY521_OK;
266+
}
267+
268+
269+
int16_t GY521::readGyro()
270+
{
271+
uint32_t now = millis();
272+
if (_throttle)
273+
{
274+
if ((now - _lastTime) < _throttleTime)
275+
{
276+
// not an error.
277+
return GY521_THROTTLED;
278+
}
279+
}
280+
_lastTime = now;
281+
282+
// Connected ?
283+
_wire->beginTransmission(_address);
284+
_wire->write(GY521_GYRO_XOUT_H);
285+
if (_wire->endTransmission() != 0)
286+
{
287+
_error = GY521_ERROR_WRITE;
288+
return _error;
289+
}
290+
291+
// Get the data
292+
int8_t n = _wire->requestFrom(_address, (uint8_t)6);
293+
if (n != 6)
294+
{
295+
_error = GY521_ERROR_READ;
296+
return _error;
297+
}
298+
// GYROSCOPE
299+
_gx = _WireRead2(); // GYRO_XOUT_H GYRO_XOUT_L
300+
_gy = _WireRead2(); // GYRO_YOUT_H GYRO_YOUT_L
301+
_gz = _WireRead2(); // GYRO_ZOUT_H GYRO_ZOUT_L
302+
303+
// duration interval
304+
now = micros();
305+
float duration = (now - _lastMicros) * 1e-6; // duration in seconds.
306+
_lastMicros = now;
307+
308+
// next lines might be merged per axis.
309+
310+
// Convert raw Gyro to degrees/seconds
311+
_gx *= _raw2dps;
312+
_gy *= _raw2dps;
313+
_gz *= _raw2dps;
314+
315+
// Error correct raw gyro measurements.
316+
_gx += gxe;
317+
_gy += gye;
318+
_gz += gze;
319+
320+
_gax += _gx * duration;
321+
_gay += _gy * duration;
322+
_gaz += _gz * duration;
323+
324+
return GY521_OK;
325+
}
326+
327+
328+
int16_t GY521::readTemperature()
329+
{
330+
// DO NOT THROTTLE
331+
_wire->beginTransmission(_address);
332+
_wire->write(GY521_TEMP_OUT_H);
333+
if (_wire->endTransmission() != 0)
334+
{
335+
_error = GY521_ERROR_WRITE;
336+
return _error;
337+
}
338+
339+
// Get the data
340+
int8_t n = _wire->requestFrom(_address, (uint8_t)2);
341+
if (n != 2)
342+
{
343+
_error = GY521_ERROR_READ;
344+
return _error;
345+
}
346+
// TEMPERATURE
347+
_temperature = _WireRead2(); // TEMP_OUT_H TEMP_OUT_L
348+
return GY521_OK;
349+
}
350+
351+
201352
bool GY521::setAccelSensitivity(uint8_t as)
202353
{
203354
_afs = as;

libraries/GY521/GY521.h

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: GY521.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.3.6
5+
// VERSION: 0.3.7
66
// PURPOSE: Arduino library for I2C GY521 accelerometer-gyroscope sensor
77
// URL: https://github.com/RobTillaart/GY521
88
//
@@ -15,15 +15,15 @@
1515
#include "Wire.h"
1616

1717

18-
#define GY521_LIB_VERSION (F("0.3.6"))
18+
#define GY521_LIB_VERSION (F("0.3.7"))
1919

2020

2121
#ifndef GY521_THROTTLE_TIME
2222
#define GY521_THROTTLE_TIME 10 // milliseconds
2323
#endif
2424

2525

26-
// ERROR CODES
26+
// ERROR CODES
2727
#define GY521_OK 0
2828
#define GY521_THROTTLED 1
2929
#define GY521_ERROR_READ -1
@@ -46,26 +46,35 @@ class GY521
4646

4747

4848
bool wakeup();
49-
// throttle to force delay between reads.
49+
// throttle to force delay between reads.
5050
void setThrottle(bool throttle = true) { _throttle = throttle; };
5151
bool getThrottle() { return _throttle; };
52-
// 0..65535 (max milliseconds == roughly 1 minute.
52+
// 0..65535 (max milliseconds == roughly 1 minute.
5353
void setThrottleTime(uint16_t ti ) { _throttleTime = ti; };
5454
uint16_t getThrottleTime() { return _throttleTime; };
5555

5656

57-
// returns GY521_OK or one of the error codes above.
57+
// READ THE SENSOR
58+
// returns GY521_OK or one of the error codes above.
5859
int16_t read();
59-
60-
// SET BEFORE READ
61-
// as = 0,1,2,3 ==> 2g 4g 8g 16g
60+
// optimized partial reading
61+
// read accelerometer only
62+
int16_t readAccel();
63+
// read gyroscope only can be done too
64+
// however for pitch roll yaw you need all.
65+
int16_t readGyro();
66+
// read temperature only, does not affect throttle.
67+
int16_t readTemperature();
68+
69+
// SET BEFORE READ
70+
// as = 0,1,2,3 ==> 2g 4g 8g 16g
6271
bool setAccelSensitivity(uint8_t as);
6372
uint8_t getAccelSensitivity(); // returns 0,1,2,3
64-
// gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
73+
// gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
6574
bool setGyroSensitivity(uint8_t gs);
6675
uint8_t getGyroSensitivity(); // returns 0,1,2,3
6776

68-
// CALL AFTER READ
77+
// CALL AFTER READ
6978
float getAccelX() { return _ax; };
7079
float getAccelY() { return _ay; };
7180
float getAccelZ() { return _az; };
@@ -81,20 +90,20 @@ class GY521
8190
float getYaw() { return _yaw; };
8291

8392

84-
// last time sensor is actually read.
93+
// last time sensor is actually read.
8594
uint32_t lastTime() { return _lastTime; };
8695

8796

88-
// generic worker to get access to all functionality
97+
// generic worker to get access to all functionality
8998
uint8_t setRegister(uint8_t reg, uint8_t value);
9099
uint8_t getRegister(uint8_t reg);
91100

92101

93-
// get last error and reset error to OK.
102+
// get last error and reset error to OK.
94103
int16_t getError() { return _error; _error = GY521_OK; };
95104

96105

97-
// calibration errors
106+
// calibration errors
98107
float axe = 0, aye = 0, aze = 0; // accelerometer errors
99108
float gxe = 0, gye = 0, gze = 0; // gyro errors
100109

libraries/GY521/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,20 @@ AD0 connected to VCC => 0x69
8787
- **bool setAccelSensitivity(uint8_t as)** as = 0, 1, 2, 3 ==> 2g 4g 8g 16g
8888
- **uint8_t getAccelSensitivity()** returns 0, 1, 2, 3
8989
- **bool setGyroSensitivity(uint8_t gs)** gs = 0,1,2,3 ==> 250, 500, 1000, 2000 degrees/second
90-
- **uint8_t getGyroSensitivity()** returns 0, 1, 2, 3
90+
- **uint8_t getGyroSensitivity()** returns 0, 1, 2, 3
9191

9292

9393
#### Actual read
9494

95-
- **int16_t read()** returns ...
96-
- **uint32_t lastTime()** last time sensor is actually read. In milliseconds.
95+
- **int16_t read()** returns status = GY521_OK on success.
96+
- **int16_t readAccel()** read accelerometer only to speed up interaction. This call does update the throttle timer.
97+
returns status = GY521_OK on success.
98+
- **int16_t readGyro()** read gyroscope only to speed up interaction. This call does update the throttle timer.
99+
returns status = GY521_OK on success.
100+
Note: for pitch roll yaw you need to call **read()**.
101+
- **int16_t readTemperature()** read temperature only, does **not** update the throttle timer.
102+
returns status = GY521_OK on success.
103+
- **uint32_t lastTime()** last time sensor is actually read. In milliseconds. Not updated by readTemperature().
97104

98105

99106
#### Call after read
@@ -144,5 +151,4 @@ See examples, use with care
144151
**Could**
145152
- calibrate function in the lib ? (think not as lib might grow?)
146153
- calibrate sketch could print code snippet to include...
147-
- option to read only Accel?
148-
- option to read only Gyro?
154+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// FILE: GY521_angle.ino
3+
// AUTHOR: Rob Tillaart
4+
// PURPOSE: demo pitch roll yaw
5+
// DATE: 2022-06-06
6+
7+
8+
#include "GY521.h"
9+
10+
GY521 sensor(0x68);
11+
12+
uint32_t counter = 0;
13+
14+
15+
void setup()
16+
{
17+
Serial.begin(115200);
18+
Serial.println();
19+
Serial.println(__FILE__);
20+
Serial.print("GY521_LIB_VERSION: ");
21+
Serial.println(GY521_LIB_VERSION);
22+
23+
Wire.begin();
24+
25+
delay(100);
26+
while (sensor.wakeup() == false)
27+
{
28+
Serial.print(millis());
29+
Serial.println("\tCould not connect to GY521");
30+
delay(1000);
31+
}
32+
sensor.setAccelSensitivity(2); // 8g
33+
sensor.setGyroSensitivity(1); // 500 degrees/s
34+
35+
sensor.setThrottle();
36+
Serial.println("start...");
37+
38+
// set calibration values from calibration sketch.
39+
sensor.axe = 0.574;
40+
sensor.aye = -0.002;
41+
sensor.aze = -1.043;
42+
sensor.gxe = 10.702;
43+
sensor.gye = -6.436;
44+
sensor.gze = -0.676;
45+
}
46+
47+
48+
void loop()
49+
{
50+
sensor.read();
51+
float x = sensor.getAngleX();
52+
float y = sensor.getAngleY();
53+
float z = sensor.getAngleZ();
54+
55+
if (counter % 10 == 0)
56+
{
57+
// Serial.println("\nCNT\tX\tY\tZ");
58+
}
59+
60+
//Serial.print(counter);
61+
//Serial.print('\t');
62+
Serial.print(x, 1);
63+
Serial.print('\t');
64+
Serial.print(y, 1);
65+
Serial.print('\t');
66+
Serial.print(z, 1);
67+
Serial.println();
68+
69+
counter++;
70+
}
71+
72+
73+
// -- END OF FILE --
74+

libraries/GY521/examples/GY521_performance/GY521_performance.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ uint32_t counter = 0;
1616
void setup()
1717
{
1818
Serial.begin(115200);
19+
Serial.println();
1920
Serial.println(__FILE__);
21+
Serial.print("GY521_LIB_VERSION: ");
22+
Serial.println(GY521_LIB_VERSION);
2023

2124
Wire.begin();
2225

0 commit comments

Comments
 (0)