1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#########################################################################################
# Package HiPi::Interface::MCP3ADC
# Description : Control MCP3xxx Analog 2 Digital ICs
# Copyright : Copyright (c) 2013-2017 Mark Dootson
# License : This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
#########################################################################################
package HiPi::Interface::MCP3ADC;
#########################################################################################
use strict;
use warnings;
use parent qw( HiPi::Interface );
use Carp;
use HiPi qw( :spi :mcp3adc );
use HiPi::Device::SPI;
__PACKAGE__->create_ro_accessors( qw( devicename hsb_mask max_channel ic devbits ) );
our $VERSION ='0.81';
sub new {
my( $class, %userparams ) = @_;
my %params = (
devicename => '/dev/spidev0.0',
speed => SPI_SPEED_MHZ_1,
bitsperword => 8,
delay => 0,
device => undef,
ic => MCP3008,
);
foreach my $key (sort keys(%userparams)) {
$params{$key} = $userparams{$key};
}
unless( defined($params{device}) ) {
my $dev = HiPi::Device::SPI->new(
speed => $params{speed},
bitsperword => $params{bitsperword},
delay => $params{delay},
devicename => $params{devicename},
);
$params{device} = $dev;
}
$params{max_channel} = ( $params{ic} >> 8 ) -1;
$params{hsb_mask} = $params{ic} & 0xFF;
$params{devbits} = ( $params{hsb_mask} == 0xF ) ? 12 : 10;
my $self = $class->SUPER::new(%params);
# MCP3xxx may need a dummy read on first use after boot
# as the chip needs the CS line to transition low/hi at
# least once if it is booted when CS is low
$self->single_read(0);
return $self;
}
sub read {
my($self, $mode) = @_;
my @buffers = ( $self->devbits == 12 )
? ( 4 + ( $mode >> 2 ), ( $mode & 0x3 ) << 6, 0 ) # 12 bit
: ( 1, $mode << 4 , 0 ); # 10 bit
my @result = unpack('C3', $self->device->transfer( pack('C3', @buffers) ));
return ( ($result[1] & $self->hsb_mask ) << 8 ) + $result[2];
}
sub single_read {
my($self, $channel) = @_;
$channel //= 0;
die qq(bad channel number $channel) if( $channel < 0 || $channel > $self->max_channel);
$channel &= 0x7;
return $self->read( 8 + $channel );
}
sub diff_read {
my($self, $channel) = @_;
#channel must be below max channels
die qq(bad channel number $channel) if($channel !~ /^\d$/ || $channel > $self->max_channel);
return $self->read( $channel );
}
sub percent_read {
my($self, $channel) = @_;
my $raw = $self->single_read( $channel );
return $raw if !$raw;
my $div = ( $self->devbits == 12 ) ? 4095 : 1023;
my $float = ( $raw / $div ) * 100;
my $result = sprintf('%.0f', $float);
return $result;
}
1;
__END__
|