File Coverage

blib/lib/Device/Chip/ADS1115.pm
Criterion Covered Total %
statement 62 62 100.0
branch 1 2 50.0
condition 2 6 33.3
subroutine 14 14 100.0
pod 5 6 83.3
total 84 90 93.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2017-2022 -- leonerd@leonerd.org.uk
5              
6 2     2   106578 use v5.26;
  2         15  
7 2     2   11 use Object::Pad 0.57;
  2         23  
  2         10  
8              
9             package Device::Chip::ADS1115 0.13;
10             class Device::Chip::ADS1115
11 2     2   1129 :isa(Device::Chip::Base::RegisteredI2C);
  2         6198  
  2         101  
12              
13             Device::Chip::Base::RegisteredI2C->VERSION( '0.10' );
14              
15 2     2   443 use Future::AsyncAwait 0.13; # list-context bugfix
  2         38  
  2         11  
16              
17 2     2   730 use Data::Bitfield 0.02 qw( bitfield boolfield enumfield );
  2         2150  
  2         181  
18              
19 2     2   15 use constant REG_DATA_SIZE => 16;
  2         6  
  2         159  
20              
21             =head1 NAME
22              
23             C - chip driver for F
24              
25             =head1 SYNOPSIS
26              
27             use Device::Chip::ADS1115;
28             use Future::AsyncAwait;
29              
30             my $chip = Device::Chip::ADS1115->new;
31             await $chip->mount( Device::Chip::Adapter::...->new );
32              
33             await $chip->change_config( MUX => "0" );
34             await $chip->trigger;
35              
36             printf "The voltage is %.2fV\n", await $chip->read_adc_voltage;
37              
38             =head1 DESCRIPTION
39              
40             This L subclass provides specific communications to a chip in
41             the F F family, such as the F, F
42             or F. Due to similarities in hardware, it also works for the
43             F family, consisting of F, F and F.
44              
45             The reader is presumed to be familiar with the general operation of this chip;
46             the documentation here will not attempt to explain or define chip-specific
47             concepts or features, only the use of this module to access them.
48              
49             =cut
50              
51             use constant {
52 2         2342 REG_RESULT => 0,
53             REG_CONFIG => 1,
54             # TODO: threshold config
55 2     2   10 };
  2         4  
56              
57             sub I2C_options
58             {
59             return (
60 1     1 0 403 addr => 0x48,
61             max_bitrate => 400E3,
62             );
63             }
64              
65             =head1 METHODS
66              
67             The following methods documented in an C expression return L
68             instances.
69              
70             =cut
71              
72             =head2 read_config
73              
74             $config = await $chip->read_config;
75              
76             Returns a C reference containing the chip's current configuration.
77              
78             OS => 0 | 1
79             MUX => "0" | "1" | "2" | "3" # single-ended
80             | "0-1" | "0-3" | "1-3" | "2-3" # bipolar
81             PGA => "6.144V" | "4.096V" | "2.048V" | "1.024V" | "0.512V" | "0.256V"
82             MODE => "CONT" | "SINGLE"
83             DR => 8 | 16 | 32 | 64 | 128 | 250 | 475 | 860
84              
85             COMP_MODE => "TRAD" | "WINDOW"
86             COMP_POL => "LOW" | "HIGH"
87             COMP_LAT => 0 | 1
88             COMP_QUE => 1 | 2 | 4 | "DIS"
89              
90             =cut
91              
92             bitfield { format => "integer" }, CONFIG =>
93             OS => boolfield(15),
94             MUX => enumfield(12, qw( 0-1 0-3 1-3 2-3 0 1 2 3 )),
95             PGA => enumfield( 9, qw( 6.144V 4.096V 2.048V 1.024V 0.512V 0.256V )),
96             MODE => enumfield( 8, qw( CONT SINGLE )),
97             DR => enumfield( 5, qw( 8 16 32 64 128 250 475 860 )),
98             COMP_MODE => enumfield(4, qw( TRAD WINDOW )),
99             COMP_POL => enumfield(3, qw( LOW HIGH )),
100             COMP_LAT => boolfield(2),
101             COMP_QUE => enumfield(0, qw( 1 2 4 DIS ));
102              
103             has $_config;
104             has $_fullscale_f;
105              
106 3         8 async method read_config ()
  3         5  
107 3         22 {
108 3         24 my $bytes = await $self->cached_read_reg( REG_CONFIG, 1 );
109              
110 3         9822 return $_config = { unpack_CONFIG( unpack "S>", $bytes ) };
111 3     3 1 229 }
112              
113             =head2 change_config
114              
115             await $chip->change_config( %changes );
116              
117             Changes the configuration. Any field names not mentioned will be preserved at
118             their existing values.
119              
120             =cut
121              
122 1         3 async method change_config ( %changes )
  1         3  
  1         2  
123 1         6 {
124 1   33     6 my $config = $_config // await $self->read_config;
125              
126 1         15 %$config = ( %$config, %changes );
127              
128 1 50       4 undef $_fullscale_f if exists $changes{PGA};
129              
130 1         9 await $self->cached_write_reg( REG_CONFIG, pack "S>", pack_CONFIG( %$config ) );
131 1     1 1 3855 }
132              
133             =head2 trigger
134              
135             await $chip->trigger;
136              
137             Set the C bit configuration bit, which will cause the chip to take a new
138             reading of the currently-selected input channel when in single-shot mode.
139              
140             =cut
141              
142 1         3 async method trigger ()
  1         2  
143 1         5 {
144 1         5 my $config = await $self->read_config;
145              
146             # Not "cached" as OS is a volatile bit
147 1         171 await $self->write_reg( REG_CONFIG, pack "S>", pack_CONFIG( %$config, OS => 1 ) );
148 1     1 1 5006 }
149              
150             =head2 read_adc
151              
152             $value = await $chip->read_adc;
153              
154             Reads the most recent reading from the result register on the chip. This
155             method should be called after a suitable delay after the L method
156             when in single-shot mode, or at any time when in continuous mode.
157              
158             The reading is returned directly from the chip as a plain 16-bit signed
159             integer. To convert this into voltage use the L method.
160              
161             =cut
162              
163 2         5 async method read_adc ()
  2         4  
164 2         11 {
165 2         13 my $bytes = await $self->read_reg( REG_RESULT, 1 );
166              
167 2         1386 return unpack "S>", $bytes;
168 2     2 1 1796 }
169              
170 1         2 async method _fullscale ()
  1         2  
171 1         4 {
172 1   33     4 return $_fullscale_f //= do {
173 1         5 my $config = await $self->read_config;
174 1         175 ( $config->{PGA} =~ m/(\d\.\d+)V/ )[0];
175             };
176 1     1   3 }
177              
178             =head2 read_adc_voltage
179              
180             $voltage = await $chip->read_adc_voltage;
181              
182             Reads the most recent reading as per L and converts it into a
183             voltage level by taking into account the current setting of the C
184             configuration option to scale it.
185              
186             =cut
187              
188 1         2 async method read_adc_voltage ()
  1         3  
189 1         6 {
190 1         5 my $f = Future->needs_all( $self->_fullscale, $self->read_adc );
191 1         1347 my ( $fullscale, $reading ) = await $f;
192              
193 1         107 return ( $reading * $fullscale ) / ( 1 << 15 );
194 1     1 1 3641 }
195              
196             =head1 AUTHOR
197              
198             Paul Evans
199              
200             =cut
201              
202             0x55AA;