line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
4
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
27
|
|
2
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
71
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Device::Accelerometer::LSM303DLHC; |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# PODNAME: Device::Accelerometer::LSM303DLHC |
7
|
|
|
|
|
|
|
# ABSTRACT: I2C interface to Accelerometer on the LSM303DLHC 3 axis magnetometer(compass) and accelerometer using Device::SMBus |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# This file is part of Device-LSM303DLHC |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# This software is copyright (c) 2016 by Shantanu Bhadoria. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# This is free software; you can redistribute it and/or modify it under |
14
|
|
|
|
|
|
|
# the same terms as the Perl 5 programming language system itself. |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
our $VERSION = '0.014'; # VERSION |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Dependencies |
19
|
1
|
|
|
1
|
|
31
|
use 5.010; |
|
1
|
|
|
|
|
2
|
|
20
|
1
|
|
|
1
|
|
4
|
use POSIX; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
21
|
|
|
|
|
|
|
|
22
|
1
|
|
|
1
|
|
1780
|
use Moose; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
6
|
|
23
|
|
|
|
|
|
|
extends 'Device::SMBus'; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has '+I2CDeviceAddress' => ( |
27
|
|
|
|
|
|
|
is => 'ro', |
28
|
|
|
|
|
|
|
default => 0x19, |
29
|
|
|
|
|
|
|
); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
1
|
|
|
1
|
|
5224
|
use constant { PI => 3.14159265359, }; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
66
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Registers for the Accelerometer |
36
|
|
|
|
|
|
|
use constant { |
37
|
1
|
|
|
|
|
57
|
CTRL_REG1_A => 0x20, |
38
|
|
|
|
|
|
|
CTRL_REG4_A => 0x23, |
39
|
1
|
|
|
1
|
|
4
|
}; |
|
1
|
|
|
|
|
1
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# X, Y and Z Axis magnetic Field Data value in 2's complement |
43
|
|
|
|
|
|
|
use constant { |
44
|
1
|
|
|
|
|
162
|
OUT_X_H_A => 0x29, |
45
|
|
|
|
|
|
|
OUT_X_L_A => 0x28, |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
OUT_Y_H_A => 0x2b, |
48
|
|
|
|
|
|
|
OUT_Y_L_A => 0x2a, |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
OUT_Z_H_A => 0x2d, |
51
|
|
|
|
|
|
|
OUT_Z_L_A => 0x2c, |
52
|
1
|
|
|
1
|
|
4
|
}; |
|
1
|
|
|
|
|
1
|
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
has 'gCorrectionFactor' => ( |
56
|
|
|
|
|
|
|
is => 'ro', |
57
|
|
|
|
|
|
|
default => 256 |
58
|
|
|
|
|
|
|
); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
has 'gravitationalAcceleration' => ( |
62
|
|
|
|
|
|
|
is => 'ro', |
63
|
|
|
|
|
|
|
default => 9.8 |
64
|
|
|
|
|
|
|
); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
has 'mssCorrectionFactor' => ( |
68
|
|
|
|
|
|
|
is => 'ro', |
69
|
|
|
|
|
|
|
lazy_build => 1, |
70
|
|
|
|
|
|
|
); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub _build_mssCorrectionFactor { |
73
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
74
|
0
|
|
|
|
|
|
$self->gCorrectionFactor / $self->gravitationalAcceleration; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub enable { |
79
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
80
|
0
|
|
|
|
|
|
$self->writeByteData( CTRL_REG1_A, 0b01000111 ); |
81
|
0
|
|
|
|
|
|
$self->writeByteData( CTRL_REG4_A, 0b00101000 ); |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub getRawReading { |
86
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
use integer |
89
|
1
|
|
|
1
|
|
454
|
; # Use arithmetic right shift instead of unsigned binary right shift with >> 4 |
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
5
|
|
90
|
0
|
|
|
|
|
|
my $retval = { |
91
|
|
|
|
|
|
|
x => ( |
92
|
|
|
|
|
|
|
$self->_typecast_int_to_int16( |
93
|
|
|
|
|
|
|
( $self->readByteData(OUT_X_H_A) << 8 ) | |
94
|
|
|
|
|
|
|
$self->readByteData(OUT_X_L_A) |
95
|
|
|
|
|
|
|
) |
96
|
|
|
|
|
|
|
) >> 4, |
97
|
|
|
|
|
|
|
y => ( |
98
|
|
|
|
|
|
|
$self->_typecast_int_to_int16( |
99
|
|
|
|
|
|
|
( $self->readByteData(OUT_Y_H_A) << 8 ) | |
100
|
|
|
|
|
|
|
$self->readByteData(OUT_Y_L_A) |
101
|
|
|
|
|
|
|
) |
102
|
|
|
|
|
|
|
) >> 4, |
103
|
|
|
|
|
|
|
z => ( |
104
|
|
|
|
|
|
|
$self->_typecast_int_to_int16( |
105
|
|
|
|
|
|
|
( $self->readByteData(OUT_Z_H_A) << 8 ) | |
106
|
|
|
|
|
|
|
$self->readByteData(OUT_Z_L_A) |
107
|
|
|
|
|
|
|
) |
108
|
|
|
|
|
|
|
) >> 4, |
109
|
|
|
|
|
|
|
}; |
110
|
1
|
|
|
1
|
|
72
|
no integer; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2
|
|
111
|
|
|
|
|
|
|
|
112
|
0
|
|
|
|
|
|
return $retval; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub getAccelerationVectorInG { |
117
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
my $raw = $self->getRawReading; |
120
|
|
|
|
|
|
|
return { |
121
|
|
|
|
|
|
|
x => ( $raw->{x} ) / $self->gCorrectionFactor, |
122
|
|
|
|
|
|
|
y => ( $raw->{y} ) / $self->gCorrectionFactor, |
123
|
0
|
|
|
|
|
|
z => ( $raw->{z} ) / $self->gCorrectionFactor, |
124
|
|
|
|
|
|
|
}; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub getAccelerationVectorInMSS { |
129
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
my $raw = $self->getRawReading; |
132
|
|
|
|
|
|
|
return { |
133
|
|
|
|
|
|
|
x => ( $raw->{x} ) / $self->mssCorrectionFactor, |
134
|
|
|
|
|
|
|
y => ( $raw->{y} ) / $self->mssCorrectionFactor, |
135
|
0
|
|
|
|
|
|
z => ( $raw->{z} ) / $self->mssCorrectionFactor, |
136
|
|
|
|
|
|
|
}; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub getAccelerationVectorAngles { |
141
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
142
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
my $raw = $self->getRawReading; |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
my $rawR = |
146
|
0
|
|
|
|
|
|
sqrt( $raw->{x}**2 + $raw->{y}**2 + $raw->{z}**2 ); #Pythagoras theorem |
147
|
|
|
|
|
|
|
return { |
148
|
|
|
|
|
|
|
Axr => _acos( $raw->{x} / $rawR ), |
149
|
|
|
|
|
|
|
Ayr => _acos( $raw->{y} / $rawR ), |
150
|
0
|
|
|
|
|
|
Azr => _acos( $raw->{z} / $rawR ), |
151
|
|
|
|
|
|
|
}; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub getRollPitch { |
156
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
157
|
|
|
|
|
|
|
|
158
|
0
|
|
|
|
|
|
my $raw = $self->getRawReading; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
return { |
161
|
|
|
|
|
|
|
Roll => atan2( $raw->{x}, $raw->{z} ) + PI, |
162
|
0
|
|
|
|
|
|
Pitch => atan2( $raw->{y}, $raw->{z} ) + PI, |
163
|
|
|
|
|
|
|
}; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub _acos { |
167
|
0
|
|
|
0
|
|
|
atan2( sqrt( 1 - $_[0] * $_[0] ), $_[0] ); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub _typecast_int_to_int16 { |
171
|
0
|
|
|
0
|
|
|
return unpack 's' => pack 'S' => $_[1]; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub calibrate { |
176
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
1; |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
__END__ |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=pod |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head1 NAME |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
Device::Accelerometer::LSM303DLHC - I2C interface to Accelerometer on the LSM303DLHC 3 axis magnetometer(compass) and accelerometer using Device::SMBus |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head1 VERSION |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
version 0.014 |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=head2 I2CDeviceAddress |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
Contains the I2CDevice Address for the bus on which your Accelerometer is connected. It would look like 0x6b. Default is 0x19. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=head2 gCorrectionFactor |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
This is a correction factor for converting raw values of acceleration in units of g or gravitational acceleration. It depends on the sensitivity set in the registers. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=head2 gravitationalAcceleration |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
This is the acceleration due to gravity in meters per second square usually represented as g. default on earth is around 9.8 although it differs from 9.832 near the poles to 9.780 at equator. This might also be different if you are on a different planet or in space. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head2 mssCorrectionFactor |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
This attribute is built from the above two attributes automatically. This is usually gCorrectionFactor divided by gravitationalAcceleration. This is the inverse of relation between raw accelerometer values and its value in meters per seconds. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head1 METHODS |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=head2 enable |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
$self->enable() |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Initializes the device, Call this before you start using the device. This function sets up the appropriate default registers. |
219
|
|
|
|
|
|
|
The Device will not work properly unless you call this function |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head2 getRawReading |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
$self->getRawReading() |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Return raw readings from accelerometer registers |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head2 getAccelerationVectorInG |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
returns four acceleration vectors with accelerations in multiples of g - (9.8 meters per second square) |
230
|
|
|
|
|
|
|
note that even when stationary on the surface of earth(or a earth like planet) there is a acceleration vector g that applies perpendicular to the surface of the earth pointing opposite of the surface. |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=head2 getAccelerationVectorInMSS |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
returns four acceleration vectors with accelerations in meters per second square |
235
|
|
|
|
|
|
|
note that even when stationary on the surface of earth(or a earth like planet) there is a acceleration vector g that applies perpendicular to the surface of the earth pointing opposite of the surface. |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head2 getAccelerationVectorAngles |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
returns coordinate angles between the acceleration vector(R) and the cartesian Coordinates(x,y,z). |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head2 getRollPitch |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
returns Roll and Pitch from the accelerometer. This is a bare reading from accelerometer and it assumes gravity is the only force on the accelerometer, which means it will be quiet inaccurate for a accelerating accelerometer. |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 calibrate |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
placeholder for calibration function |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head1 REGISTERS |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head2 CTRL_REG1_A |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=head2 CTRL_REG4_A |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=head2 OUT_X_H_A |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=head2 OUT_X_L_A |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=head2 OUT_Y_H_A |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=head2 OUT_Y_L_A |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=head2 OUT_Z_H_A |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=head2 OUT_Z_L_A |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=head1 CONSTANTS |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=head2 PI |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=head1 AUTHOR |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
Shantanu Bhadoria <shantanu at cpan dott org> |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
This software is copyright (c) 2016 by Shantanu Bhadoria. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
280
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=cut |