NAME

    RPi::WiringPi - Perl interface to Raspberry Pi's board, GPIO, LCDs and
    other various items

SYNOPSIS

        use RPi::WiringPi;
        use RPi::Const qw(:all);
    
        my $pi = RPi::WiringPi->new;
    
        #
        # identification
        #
    
        $pi->io_led(1);  # turn green disk IO LED on full-time
        $pi->pwr_led(1); # turn red power LED off
    
        $pi->io_led;     # set green disk IO LED back to default status
        $pi->pwr_led;    # set red power LED back to default
    
        $pi->label('pi-test-01'); # set a name/label for your Pi object
    
        #
        # pin
        #
    
        my $pin = $pi->pin(5);
        $pin->mode(OUTPUT);
        $pin->write(ON);
    
        my $num = $pin->num;
        my $mode = $pin->mode;
        my $state = $pin->read;
    
        #
        # analog to digital converter (ADS1115)
        #
    
        my $adc = $pi->adc;
       
        # read channel A0 on the ADC
    
        my $v = $adc->volts(0);
        my $p = $adc->percent(0);
    
        # analog to digital converter (MCP3008)
    
        my $adc = $pi->adc(model => 'MCP3008', channel => 0);
    
        print $adc->raw(0);
        print $adc->percent(0);
    
        #
        # I2C
        #
    
        my $device_addr = 0x7c;
    
        my $i2c_device = $pi->i2c($device_addr);
    
        my $register = 0x0A;
    
        $i2c_device->write_block([55, 29, 255], $register);
    
        my $byte = $i2c_device->read;
    
        my @bytes = $i2c_device->read_block;
    
        #
        # SPI
        #
    
        my $channel = 0; # SPI channel /dev/spidev0.0
    
        my $spi = $pi->spi($channel);
    
        my $buf = [0x01, 0x02];
        my $len = scalar @$buf;
    
        my @read_bytes = $spi->rw($buf, $len);
    
        #
        # Serial
        #
    
        my $dev  = "/dev/ttyS0";
        my $baud = 115200;
    
        my $ser = $pi->serial($dev, $baud);
    
        $ser->putc(5);
    
        my $char = $ser->getc;
    
        $ser->puts("hello, world!");
    
        my $num_bytes = 12;
        my $str  = $ser->gets($num_bytes);
    
        $ser->flush;
    
        my $bytes_available = $ser->avail;
    
        #
        # digital to analog converter (DAC)
        #
    
        my $dac_cs_pin = $pi->pin(29);
        my $spi_chan = 0;
    
        my $dac = $pi->dac(
            model   => 'MCP4922',
            channel => $spi_chan,
            cs      => $dac_cs_pin
        );
    
        my ($dacA, $dacB) = (0, 1);
    
        $dac->set($dacA, 4095); # 100% output
        $dac->set($dacB, 0);    # 0% output
    
        #
        # digital potentiometer
        #
    
        my $cs = 18;     # GPIO pin connected to dpot CS pin
        my $channel = 0; # SPI channel /dev/spidev0.0
    
        my $dpot = $pi->dpot($cs, $channel);
    
        # set to 50% output
    
        $dpot->set(127);
    
        # shutdown (sleep) the potentiometer
    
        $dpot->shutdown;
    
        #
        # shift register
        #
        
        my ($base, $num_pins, $data, $clk, $latch)
          = (100, 8, 5, 6, 13);
    
        $pi->shift_register(
            $base, $num_pins, $data, $clk, $latch
        );
    
        # now we can access the new 8 pins of the
        # register commencing at new pin 100-107
    
        for (100..107){
            my $pin = $pi->pin($_);
            $pin->write(HIGH);
        }
    
        #
        # BMP180 barometric pressure sensor
        #
        
        my $base = 300; 
    
        my $bmp = $pi->bmp($base);
    
        my $farenheit = $bmp->temp;
        my $celcius   = $bmp->temp('c');
        my $pressure  = $bmp->pressure; # kPa
    
        #
        # DHT11 temperature/humidity sensor
        #
    
        my $sensor_pin = 21;
    
        my $env = $pi->hygrometer($sensor_pin);
    
        my $humidity  = $env->humidity;
        my $temp      = $env->temp; # celcius
        my $farenheit = $env->temp('f');
    
        # GPS (requires gpsd to be installed and running)
    
        my $gps = $pi->gps;
    
        print $gps->lat;
        print $gps->lon;
        print $gps->speed;
        print $gps->direction;
    
        #
        # LCD
        #
    
        my $lcd = $pi->lcd(...);
    
        # first column, first row
        
        $lcd->position(0, 0); 
        $lcd->print("hi there!");
    
        # first column, second row
        
        $lcd->position(0, 1);
        $lcd->print("pin $num... mode: $mode, state: $state");
    
        $lcd->clear;
        $lcd->display(OFF);
    
        $pi->cleanup;
    
        #
        # real time clock
        #
    
        my $rtc = $pi->rtc;
    
        my $dt_string = $rtc->date_time;
        my %dt_hash   = $rtc->dt_hash;
    
        # set an individual attribute
    
        $rtc->hour(22);
    
        # set 12/24 hour clock
    
        $rtc->clock_hours(12);
    
        # get AM or PM while in 12-hour clock mode
    
        my $meridien = $rtc->am_pm;
    
        #
        # MCP23017 GPIO expander
        #
    
        my $i2c_addr = 0x20;            # default
    
        my $exp = $pi->expander($addr); # param not required if using the default
    
        # pins are INPUT by default. Turn the first pin to OUTPUT
    
        $exp->mode(0, 0); # or MCP23017_OUTPUT if using RPi::Const
    
        # turn the pin on (HIGH)
    
        $exp->write(0, 1); # or HIGH
    
        # read the pin's status (HIGH or LOW)
    
        $exp->read(6);
    
        # turn the first bank (0) of pins (0-7) to OUTPUT, and make them live (HIGH)
    
        $exp->mode_bank(0, 0);  # bank A, OUTPUT
        $exp->write_bank(0, 1); # bank A, HIGH
    
        # enable internal pullup resistors on the entire bank A (0)
    
        $exp->pullup_bank(0, 1); # bank A, pullup enabled
    
        # put all 16 pins as OUTPUT, and put them on (HIGH)
    
        $exp->mode_all(0);  # or OUTPUT
        $exp->write_all(1); # or HIGH
    
        # cleanup all pins and reset them to default before exiting your program
    
        $exp->cleanup;
    
        # ultrasonic distance sensor
        #
    
        my $trig_pin = 23;
        my $echo_pin = 24;
    
        my $ruler = $pi->hcsr04($trig_pin, $echo_pin);
    
        my $inches = $sensor->inch;
        my $cm     = $sensor->cm;
        my $raw    = $sensor->raw;
    
        #
        # servo
        #
    
        my $pin_num = 18;
    
        my $servo = $pi->servo($pin_num);
    
        $servo->pwm(150); # centre position
        $servo->pwm(50);  # left position
        $servo->pwm(250); # right position
    
        #
        # stepper motor
        #
    
        my $sm = $pi->stepper_motor(
            pins => [12, 16, 20, 21]
        );
    
        $sm->cw(180);   # turn clockwise 180 degrees
        $sm->ccw(240);  # turn counter-clockwise 240 degrees

DESCRIPTION

    This is the root module for the RPi::WiringPi system. It interfaces to
    a Raspberry Pi board, its accessories and its GPIO pins via the
    wiringPi <http://wiringpi.com> library through the Perl wrapper
    WiringPi::API <https://metacpan.org/pod/WiringPi::API> module, and
    various other custom device specific modules.

    wiringPi <http://wiringpi.com> must be installed prior to
    installing/using this module (v2.36+).

    We always and only use the GPIO pin numbering scheme.

    This module is essentially a 'manager' for the sub-modules (ie.
    components). You can use the component modules directly, but retrieving
    components through this module instead has many benefits. We maintain a
    registry of pins and other data. We also trap $SIG{__DIE__} and
    $SIG{INT}, so that in the event of a crash, we can reset the Pi back to
    default settings, so components are not left in an inconsistent state.
    Component modules do none of these things.

    There are a basic set of constants that can be imported. See
    RPi::Const.

    It's handy to have access to a pin mapping conversion chart. There's an
    excellent pin scheme map for reference at pinout.xyz
    <https://pinout.xyz/pinout/wiringpi>. You can also run the pinmap
    command that was installed by this module, or wiringPi's gpio readall
    command.

METHODS

    See RPi::WiringPi::Core for utility/helper/hardware-specific methods
    that are imported into an RPi::WiringPi object.

 new([%args])

    Returns a new RPi::WiringPi object. We exclusively use the GPIO
    (Broadcom (BCM) GPIO) pin numbering scheme.

    Parameters:

        fatal_exit => $bool

    Optional: We trap all die() calls and clean up for safety reasons. If a
    call to die() is trapped, by default, we clean up, and then exit(). Set
    fatal_exit to false (0) to perform the cleanup, and then continue
    running your script.

    We recommend only disabling this feature if you're doing unit test
    work, want to allow other exit traps to catch, allow the Pi to continue
    on working after a fatal error etc. If disabled, you will be
    responsible for doing your own cleanup of the Pi hardware configuration
    on exit.

 adc

    There are two different ADCs that you can select from. The default is
    the ADS1x15 series:

  ADS1115

    Returns a RPi::ADC::ADS object, which allows you to read the four
    analog input channels on an Adafruit ADS1xxx analog to digital
    converter.

    Parameters:

    The default (no parameters) is almost always enough, but please do
    review the documentation in the link above for further information, and
    have a look at the ADC tutorial section in this distribution.

  MCP3008

    You can also use an RPi::ADC::MCP3008 ADC.

    Parameters:

        model => 'MCP3008'

    Mandatory, String. The exact quoted string above.

        channel => $channel

    Mandatory, Integer. 0 or 1 for the Pi's onboard hardware CS/SS CE0 and
    CE1 pins, or any GPIO number above 1 in order to use an arbitrary GPIO
    pin for the CS pin, and we'll do the bit-banging of the SPI bus
    automatically.

 bmp

    Returns a RPi::BMP180 object, which allows you to return the current
    temperature in farenheit or celcius, along with the ability to retrieve
    the barometric pressure in kPa.

 dac

    Returns a RPi::DAC::MCP4922 object (supports all 49x2 series DACs).
    These chips provide analog output signals from the Pi's digital output.
    Please see the documentation of that module for further information on
    both the configuration and use of the DAC object.

    Parameters:

        model => 'MCP4922'

    Optional, String. The model of the DAC you're using. Defaults to
    MCP4922.

        channel => 0|1

    Mandatory, Bool. The SPI channel to use.

        cs => $pin

    Mandatory, Integer. A valid GPIO pin that the DAC's Chip Select is
    connected to.

    There are a handful of other parameters that aren't required. For
    those, please refer to the RPi::DAC::MCP4922 documentation.

 dpot($cs, $channel)

    Returns a RPi::DigiPot::MCP4XXXX object, which allows you to manage a
    digital potentiometer (only the MCP4XXXX versions are currently
    supported).

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for usage examples.

 gps

    Returns a GPSD::Parse object, allowing you to track your location.

    The GPS distribution requires gpsd to be installed and running. All
    parameters for the GPS can be sent in here and we'll pass them along.
    Please see the link above for the full documentation on that module.

 hcsr04($trig, $echo)

    Returns a RPi::HCSR04 ultrasonic distance measurement sensor object,
    allowing you to retrieve the distance from the sensor in inches,
    centimetres or raw data.

    Parameters:

        $trig

    Mandatory, Integer: The trigger pin number, in GPIO numbering scheme.

        $echo

    Mandatory, Integer: The echo pin number, in GPIO numbering scheme.

 hygrometer($pin)

    Returns a RPi::DHT11 temperature/humidity sensor object, allows you to
    fetch the temperature (celcius or farenheit) as well as the current
    humidity level.

    Parameters:

        $pin

    Mandatory, Integer: The GPIO pin the sensor is connected to.

 i2c($addr, [$device])

    Creates a new RPi::I2C device object which allows you to communicate
    with the devices on an I2C bus.

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for usage examples.

    Aruino note: If using I2C with an Arduino, the Pi may speak faster than
    the Arduino can. If this is the case, try lowering the I2C bus speed on
    the Pi:

        dtparam=i2c_arm_baudrate=10000

 lcd(...)

    Returns a RPi::LCD object, which allows you to fully manipulate LCD
    displays connected to your Raspberry Pi.

    Please see the linked documentation for information regarding the
    parameters required.

 pin($pin_num)

    Returns a RPi::Pin object, mapped to a specified GPIO pin, which you
    can then perform operations on. See that documentation for full usage
    details.

    Parameters:

        $pin_num

    Mandatory, Integer: The pin number to attach to.

 rtc

    Creates a new RPi::RTC::DS3231 object which provides access to the
    DS3231 or DS1307 real-time clock modules.

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for some usage examples.

    Parameters:

        $i2c_addr

    Optional, Integer: The I2C address of the RTC module. Defaults to 0x68
    for the DS3231 unit.

 expander

    Creates a new RPi::GPIOExpander::MCP23017 GPIO expander chip object.
    This adds an additional 16 pins across two banks (8 pins per bank).

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for some usage examples.

    Parameters:

        $i2c_addr

    Optional, Integer: The I2C address of the device. Defaults to 0x20.

        $expander

    Optional, String: The GPIO expander device type. Defaults to MCP23017,
    and currently, this is the only option available.

 serial($device, $baud)

    Creates a new RPi::Serial object which allows basic read/write access
    to a serial bus.

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for usage examples.

    NOTE: Bluetooth on the Pi overlays the serial pins (14, 15) on the Pi.
    To use serial, you must disable bluetooth in the /boot/config.txt file:

        dtoverlay=pi3-disable-bt-overlay

 servo($pin_num)

    This method configures PWM clock and divisor to operate a typical 50Hz
    servo, and returns a special RPi::Pin object. These servos have a left
    pulse of 50, a centre pulse of 150 and a right pulse of 250. On exit of
    the program (or a crash), we automatically clean everything up
    properly.

    Parameters:

        $pin_num

    Mandatory, Integer: The pin number (technically, this *must* be 18 on
    the Raspberry Pi 3, as that's the only hardware PWM pin.

        %pwm_config

    Optional, Hash. This parameter should only be used if you know what
    you're doing and are having very specific issues.

    Keys are clock with a value that coincides with the PWM clock speed. It
    defaults to 192. The other key is range, the value being an integer
    that sets the range of the PWM. Defaults to 2000.

    Example:

        my $servo = $pi->servo(18);
    
        $servo->pwm(50);  # all the way left
        $servo->pwm(250); # all the way right

 shift_register($base, $num_pins, $data, $clk, $latch)

    Allows you to access the output pins of up to four 74HC595 shift
    registers in series, for a total of eight new output pins per register.
    Numerous chains of four registers are permitted, each chain uses three
    GPIO pins.

    Parameters:

        $base

    Mandatory: Integer, represents the number at which you want to start
    referencing the new output pins attached to the register(s). For
    example, if you use 100 here, output pin 0 of the register will be 100,
    output 1 will be 101 etc.

        $num_pins

    Mandatory: Integer, the number of output pins on the registers you want
    to use. Each register has eight outputs, so if you have a single
    register in use, the maximum number of additional pins would be eight.

        $data

    Mandatory: Integer, the GPIO pin number attached to the DS pin (14) on
    the shift register.

        $clk

    Mandatory: Integer, the GPIO pin number attached to the SHCP pin (11)
    on the shift register.

        $latch

    Mandatory: Integer, the GPIO pin number attached to the STCP pin (12)
    on the shift register.

 spi($channel, $speed)

    Creates a new RPi::SPI object which allows you to communicate on the
    Serial Peripheral Interface (SPI) bus with attached devices.

    See the linked documentation for full documentation on usage, or the
    RPi::WiringPi::FAQ for usage examples.

 stepper_motor($pins)

    Creates a new RPi::StepperMotor object which allows you to drive a
    28BYJ-48 stepper motor with a ULN2003 driver chip.

    See the linked documentation for full usage instructions and the
    optional parameters.

    Parameters:

        pins => $aref

    Mandatory, Array Reference: The ULN2003 has four data pins, IN1, IN2,
    IN3 and IN4. Send in the GPIO pin numbers in the array reference which
    correlate to the driver pins in the listed order.

        speed => 'half'|'full'

    Optional, String: By default we run in "half speed" mode. Essentially,
    in this mode we run through all eight steps. Send in 'full' to double
    the speed of the motor. We do this by skipping every other step.

        delay => Float|Int

    Optional, Float or Int: By default, between each step, we delay by 0.01
    seconds. Send in a float or integer for the number of seconds to delay
    each step by. The smaller this number, the faster the motor will turn.

RUNNING TESTS

    Please see RUNNING TESTS in the FAQ.

TROUBLESHOOTING

    Please read through the SETUP section in the FAQ.

AUTHOR

    Steve Bertrand, <steveb@cpan.org>

COPYRIGHT AND LICENSE

    Copyright (C) 2017,2018 by Steve Bertrand

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.18.2 or, at
    your option, any later version of Perl 5 you may have available.