Skip to content

Commit

Permalink
added PIGPIO implementation for DigitalMultipurpose
Browse files Browse the repository at this point in the history
  • Loading branch information
savageautomate committed Jul 10, 2020
1 parent bffc0f5 commit b406d7f
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ static DigitalMultipurposeConfigBuilder newConfigBuilder(Context context){
* @param mode DigitalMode (input|output)
* @return this I/O instance
*/
DigitalMultipurpose mode(DigitalMode mode);
DigitalMultipurpose mode(DigitalMode mode) throws IOException;

/**
* Set digital mode to INPUT
* @return this I/O instance
*/
default DigitalMultipurpose input(){
default DigitalMultipurpose input() throws IOException {
return this.mode(DigitalMode.INPUT);
}

Expand All @@ -107,7 +107,7 @@ default boolean isOutput(){
* Set digital mode to OUTPUT
* @return this I/O instance
*/
default DigitalMultipurpose output(){
default DigitalMultipurpose output() throws IOException {
return this.mode(DigitalMode.OUTPUT);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public DigitalMode mode(){

/** {@inheritDoc} */
@Override
public DigitalMultipurpose mode(DigitalMode mode) {
public DigitalMultipurpose mode(DigitalMode mode) throws com.pi4j.io.exception.IOException {
this.mode = mode;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.pi4j.extension.PluginService;
import com.pi4j.library.pigpio.PiGpio;
import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalInputProvider;
import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalMultipurposeProvider;
import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProvider;
import com.pi4j.plugin.pigpio.provider.i2c.PiGpioI2CProvider;
import com.pi4j.plugin.pigpio.provider.pwm.PiGpioPwmProvider;
Expand Down Expand Up @@ -68,6 +69,12 @@ public class PiGpioPlugin implements Plugin {
/** Constant <code>DIGITAL_OUTPUT_PROVIDER_ID="ID + -digital-output"</code> */
public static final String DIGITAL_OUTPUT_PROVIDER_ID = ID + "-digital-output";

// Digital Multipurpose (GPIO) Provider name and unique ID
/** Constant <code>DIGITAL_MULTIPURPOSE_PROVIDER_NAME="NAME + Digital Output (GPIO) Provider"</code> */
public static final String DIGITAL_MULTIPURPOSE_PROVIDER_NAME = NAME + " Digital Multipurpose (GPIO) Provider";
/** Constant <code>DIGITAL_MULTIPURPOSE_PROVIDER_ID="ID + -digital-output"</code> */
public static final String DIGITAL_MULTIPURPOSE_PROVIDER_ID = ID + "-digital-multi";

// PWM Provider name and unique ID
/** Constant <code>PWM_PROVIDER_NAME="NAME + PWM Provider"</code> */
public static final String PWM_PROVIDER_NAME = NAME + " PWM Provider";
Expand Down Expand Up @@ -166,6 +173,7 @@ public void initialize(PluginService service) throws IOException {
Provider providers[] = {
PiGpioDigitalInputProvider.newInstance(piGpio),
PiGpioDigitalOutputProvider.newInstance(piGpio),
PiGpioDigitalMultipurposeProvider.newInstance(piGpio),
PiGpioPwmProvider.newInstance(piGpio),
PiGpioI2CProvider.newInstance(piGpio),
PiGpioSerialProvider.newInstance(piGpio),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package com.pi4j.plugin.pigpio.provider.gpio.digital;

/*-
* #%L
* **********************************************************************
* ORGANIZATION : Pi4J
* PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers
* FILENAME : PiGpioDigitalMultipurpose.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here: https://pi4j.com/
* **********************************************************************
* %%
* Copyright (C) 2012 - 2020 Pi4J
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/


import com.pi4j.context.Context;
import com.pi4j.exception.InitializeException;
import com.pi4j.exception.ShutdownException;
import com.pi4j.io.exception.IOModeException;
import com.pi4j.io.gpio.digital.*;
import com.pi4j.library.pigpio.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
* <p>PiGpioDigitalMultipurpose class.</p>
*
* @author Robert Savage (<a href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
* @version $Id: $Id
*/
public class PiGpioDigitalMultipurpose extends DigitalMultipurposeBase implements DigitalMultipurpose {
private final PiGpio piGpio;
private final int pin;
private DigitalState state = DigitalState.LOW;
private Logger logger = LoggerFactory.getLogger(this.getClass());


/**
* Default Constructor
*
* @param piGpio a {@link PiGpio} object.
* @param provider a {@link DigitalInputProvider} object.
* @param config a {@link DigitalInputConfig} object.
* @throws IOException if any.
*/
public PiGpioDigitalMultipurpose(PiGpio piGpio, DigitalMultipurposeProvider provider, DigitalMultipurposeConfig config) throws IOException {
super(provider, config);
this.piGpio = piGpio;
this.pin = config.address().intValue();
}

/**
* PIGPIO Pin Change Event Handler
*
* This listener implementation will forward pin change events received from PIGPIO
* to registered Pi4J 'DigitalChangeEvent' event listeners on this digital pin.
*/
private PiGpioStateChangeListener piGpioPinListener =
event -> dispatch(new DigitalStateChangeEvent(PiGpioDigitalMultipurpose.this, DigitalState.getState(event.state().value())));

/** {@inheritDoc} */
@Override
public DigitalMultipurpose initialize(Context context) throws InitializeException {
try {
// configure GPIO pin as an INPUT|OUTPUT pin
PiGpioMode pgpiomode = (mode.isOutput()) ? PiGpioMode.OUTPUT : PiGpioMode.INPUT;
this.piGpio.gpioSetMode(pin, pgpiomode);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new InitializeException(e);
}

super.initialize(context);

try {
// if configured, set GPIO pin pull resistance
switch(config.pull()){
case PULL_DOWN:{
this.piGpio.gpioSetPullUpDown(pin, PiGpioPud.DOWN);
break;
}
case PULL_UP:{
this.piGpio.gpioSetPullUpDown(pin, PiGpioPud.UP);
break;
}
}

// if configured, set GPIO debounce
if(this.config.debounce() != null) {
int steadyInterval = 0;
if(this.config.debounce() > 300000){
steadyInterval = 300000;
} else{
steadyInterval = this.config.debounce().intValue();
}
this.piGpio.gpioNoiseFilter(pin, 0, 0);
this.piGpio.gpioGlitchFilter(pin, steadyInterval);
}

// add this pin listener
this.piGpio.addPinListener(pin, piGpioPinListener);

} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new InitializeException(e);
}
return this;
}

/** {@inheritDoc} */
@Override
public DigitalMultipurpose mode(DigitalMode mode) throws com.pi4j.io.exception.IOException {
try {
// configure GPIO pin as an INPUT|OUTPUT pin
PiGpioMode pgpiomode = (mode.isOutput()) ? PiGpioMode.OUTPUT : PiGpioMode.INPUT;
this.piGpio.gpioSetMode(pin, pgpiomode);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new IOModeException(e.getMessage());
}
return super.mode(mode);
}

/** {@inheritDoc} */
@Override
public DigitalMultipurpose state(DigitalState state) throws com.pi4j.io.exception.IOException {
// ensure the pin is in the OUPUT mode before attempting to set state
if(!this.isOutput()){
throw new IOModeException("Unable to set state [" + state.getName() +
"] for I/O instance [" + toString() + "]; Invalid Mode: " + mode.getName());
}
try {
this.piGpio.gpioWrite(pin, PiGpioState.from(state.value()));
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new com.pi4j.io.exception.IOException(e.getMessage(), e);
}
return super.state(state);
}

/** {@inheritDoc} */
@Override
public DigitalState state() {
try {
switch (this.piGpio.gpioRead(pin)) {
case LOW: {
this.state = DigitalState.LOW;
break;
}
case HIGH: {
this.state = DigitalState.HIGH;
break;
}
default: {
this.state = DigitalState.UNKNOWN;
break;
}
}
return this.state;
}
catch (Exception e){
logger.error(e.getMessage(), e);
return DigitalState.UNKNOWN;
}
}

/** {@inheritDoc} */
@Override
public DigitalMultipurpose shutdown(Context context) throws ShutdownException {
// remove this pin listener
this.piGpio.removePinListener(pin, piGpioPinListener);
return super.shutdown(context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.pi4j.plugin.pigpio.provider.gpio.digital;

/*
* #%L
* **********************************************************************
* ORGANIZATION : Pi4J
* PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers
* FILENAME : PiGpioDigitalMultipurposeProvider.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here: https://pi4j.com/
* **********************************************************************
* %%
* Copyright (C) 2012 - 2020 Pi4J
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/

import com.pi4j.io.gpio.digital.DigitalMultipurposeProvider;
import com.pi4j.library.pigpio.PiGpio;
import com.pi4j.plugin.pigpio.PiGpioPlugin;

/**
* <p>PiGpioDigitalMultipurposeProvider interface.</p>
*
* @author Robert Savage (<a href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
* @version $Id: $Id
*/
public interface PiGpioDigitalMultipurposeProvider extends DigitalMultipurposeProvider {
/** Constant <code>NAME="PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_NAME</code> */
String NAME = PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_NAME;
/** Constant <code>ID="PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_ID"</code> */
String ID = PiGpioPlugin.DIGITAL_MULTIPURPOSE_PROVIDER_ID;

/**
* <p>newInstance.</p>
*
* @param piGpio a {@link PiGpio} object.
* @return a {@link PiGpioDigitalMultipurposeProvider} object.
*/
static PiGpioDigitalMultipurposeProvider newInstance(PiGpio piGpio) {
return new PiGpioDigitalMultipurposeProviderImpl(piGpio);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.pi4j.plugin.pigpio.provider.gpio.digital;

/*
* #%L
* **********************************************************************
* ORGANIZATION : Pi4J
* PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers
* FILENAME : PiGpioDigitalMultipurposeProviderImpl.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here: https://pi4j.com/
* **********************************************************************
* %%
* Copyright (C) 2012 - 2020 Pi4J
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/

import com.pi4j.io.gpio.digital.DigitalMultipurpose;
import com.pi4j.io.gpio.digital.DigitalMultipurposeConfig;
import com.pi4j.io.gpio.digital.DigitalMultipurposeProviderBase;
import com.pi4j.library.pigpio.PiGpio;

/**
* <p>PiGpioDigitalMultipurposeProviderImpl class.</p>
*
* @author Robert Savage (<a href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
* @version $Id: $Id
*/
public class PiGpioDigitalMultipurposeProviderImpl extends DigitalMultipurposeProviderBase implements PiGpioDigitalMultipurposeProvider {

protected final PiGpio piGpio;

/**
* <p>Constructor for PiGpioDigitalOutputProviderImpl.</p>
*
* @param piGpio a {@link PiGpio} object.
*/
public PiGpioDigitalMultipurposeProviderImpl(PiGpio piGpio){
this.id = ID;
this.name = NAME;
this.piGpio = piGpio;
}

/** {@inheritDoc} */
@Override
public DigitalMultipurpose create(DigitalMultipurposeConfig config) throws Exception {
// initialize the PIGPIO library
if(!piGpio.isInitialized()) piGpio.initialize();

// create new I/O instance based on I/O config
return new PiGpioDigitalMultipurpose(piGpio,this, config);
}
}

0 comments on commit b406d7f

Please sign in to comment.