File Coverage

blib/lib/Device/Accelerometer/LSM303DLHC.pm
Criterion Covered Total %
statement 29 53 54.7
branch n/a
condition n/a
subroutine 10 20 50.0
pod 7 7 100.0
total 46 80 57.5


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