http://qs1969.pair.com?node_id=1179406

Over the last few months, I've been writing Perl modules/distributions to interact with a Raspberry Pi, its GPIO, and external hardware/devices. My primary objective is to create a complete indoor grow room automation system.

The past week and a half, I have been focusing on writing a distribution that provides Perl users a way to interact with Adafruit's ADS1xxx Analog to Digital Converters (ADC), so that I could communicate with analog devices via the Pi which does not have any analog inputs. Hence, RPi::ADC::ADS was born.

The vast majority of functionality specified in the unit's datasheet has been incorporated into this XS-based module, and the documentation outlays all of the critical pieces from the hardware docs.

Features:

** - single-ended mode is the measurement of voltage of a single input relative to ground. Differential mode retrieves the voltage difference between two separate inputs.

Here's a basic example, and for the most part, exactly how I use the software. Say I have a moisture sensor connected to analog input A0 (0 as far as the software is concerned) and I want to get the moisture level from it:

use warnings; use strict; use RPi::ADC::ADS; my $adc = RPi::ADC::ADS->new; my $v = $adc->volts; my $p = $adc->percent; my $r = $adc->raw;

Volts is a floating point number, percent is a float chopped at .2f and raw is the raw 16-bit unsigned int.

If you have more than one channel active at a time, specify which channel you want to fetch from:

# A0, A1 and A3 input channels for (0, 1, 3){ print $adc->percent($_) ."\n"; }

All configuration register options can be changed on the fly, as they each have their own setter/getter. Say you are using two inputs (eg: A0 and A3) as single-ended inputs and at one point in code, you need to retrieve the value of the difference in levels between them. The documentation has a map for parameter value to hardware functionality for all settings. All fetch methods allow you to send in the channel to retrieve on the fly, so we don't have to do anything special here. Per the map in the docs above, either of these will work:

my $diff_a0_a3 = $adc->percent(5); # or $adc->channel(5); my $diff_a0_a3 = $adc->percent;

The software is quite complete, and I have tested the vast majority of the configuration settings. I'm about 85% test coverage so there's a bit more work to do there, but I digress.

My next project is to write a Perl distribution for a BMP 180 barometric and altimiter sensor which I just bought and soldered yesterday, and an MCP3008 analog-digital converter. The 3008 has 10 input channels whereby the ADS only has four, but the ADS has 12-bit or 16-bit of resolution accuracy, where the MCP3008 only has 10-bit, so I decided I'd write code for both.

See also:

WiringPi::API, my original and nearly feature complete wrapper for the WiringPi libraries.

RPi::WiringPi, OO interface for the above wrapper with error detection, safe exit on unexpected terminations, and more.

RPi::DHT11, module to access the DHT11 temperature and humidity sensor.

App::RPi::EnvUI, my Dancer2 and jQuery one-page app for indoor grow room control (not yet fully completed).

RPi::WiringPi::Constant, module that contains commonly used names in the Raspberry Pi/electrical/electronics realm.