All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pi4j.io.gpio.impl.GpioPinImpl Maven / Gradle / Ivy

Go to download

This bundle wraps Pi4j (http://pi4j.com) that wraps the native code Wiring Pi (http://wiringpi.com). It wraps these libraries to make them OSGi friendly and allow them to work together with the OSGi enRoute IoT circuit library (osgi.enroute.iot.circuit). The bundle will first use Pi4J to detect on what hardware it runs. If it runs on an appropriate type, it will register a component that can be configured with Metatype. The Metatype defines a full blown configuration template for all the Pi's functions. The GPIO's are registered as components for the circuit. Regardless of the success of the configuration, this bundle will also register a GpioController service, which is the main Pi4J class.

The newest version!
package com.pi4j.io.gpio.impl;

/*
 * #%L
 * **********************************************************************
 * ORGANIZATION  :  Pi4J
 * PROJECT       :  Pi4J :: Java Library (Core)
 * FILENAME      :  GpioPinImpl.java  
 * 
 * This file is part of the Pi4J project. More information about 
 * this project can be found here:  http://www.pi4j.com/
 * **********************************************************************
 * %%
 * Copyright (C) 2012 - 2015 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
 * .
 * #L%
 */

import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.event.GpioPinListener;
import com.pi4j.io.gpio.event.PinListener;
import com.pi4j.io.gpio.trigger.GpioTrigger;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;

public class GpioPinImpl implements GpioPin, 
                                    GpioPinDigitalInput, 
                                    GpioPinDigitalOutput, 
                                    GpioPinDigitalMultipurpose,
                                    GpioPinAnalogInput, 
                                    GpioPinAnalogOutput,
                                    GpioPinPwmOutput,
                                    GpioPinInput,
                                    GpioPinOutput
{
 
    @SuppressWarnings("unused")
    private String name = null;
    private Object tag = null;
    private final GpioProvider provider;
    private final Pin pin;
    private PinListener monitor;
    private final GpioPinShutdownImpl shutdownOptions;
    private final Map properties = new ConcurrentHashMap<>();
    private final List listeners = new ArrayList<>();
    private final List triggers = new ArrayList<>();
    private final Map debounce = new HashMap<>();
    protected final int NO_DEBOUCE = 0;

    @SuppressWarnings("unused")
    public GpioPinImpl(GpioController gpio, GpioProvider provider, Pin pin) {
        this.provider = provider;
        this.pin = pin;
        shutdownOptions = new GpioPinShutdownImpl();
    }

    @Override
    public Pin getPin() {
        return this.pin;
    }

    @Override
    public GpioProvider getProvider() {
        return this.provider;
    }
    
    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        if (name == null || name.length() == 0) {
            return pin.toString();
        }
        return name;
    }
    
    @Override
    public void setTag(Object tag) {
        this.tag = tag;
    }

    @Override
    public Object getTag() {
        return tag;
    }

    @Override
    public void setProperty(String key, String value) {
        properties.put(key, value);
    }

    @Override
    public boolean hasProperty(String key) {
        return properties.containsKey(key);
    }

    @Override
    public String getProperty(String key, String defaultValue) {
        if (properties.containsKey(key)) {
            if(properties.get(key) == null || properties.get(key).isEmpty())
                return defaultValue;
            else
                return properties.get(key);
        }
        return defaultValue;
    }

    @Override
    public String getProperty(String key) {
        return getProperty(key, null);
    }
    
    @Override
    public Map getProperties() {
        return properties;
    }

    @Override
    public void removeProperty(String key) {
        if (properties.containsKey(key)) {
            properties.remove(key);
        }
    }

    @Override
    public void clearProperties() {
        properties.clear();
    }

    @Override
    public void export(PinMode mode) {
        // export the pin
        provider.export(pin, mode);
    }

    @Override
    public void export(PinMode mode, PinState defaultState) {
        // export the pin
        provider.export(pin, mode, defaultState);
    }

    @Override
    public void unexport() {
        // unexport the pin
        provider.unexport(pin);
    }

    @Override
    public boolean isExported() {
        return provider.isExported(pin);
    }

    @Override
    public void setMode(PinMode mode) {
        provider.setMode(pin, mode);
    }

    @Override
    public PinMode getMode() {
        return provider.getMode(pin);
    }

    @Override
    public boolean isMode(PinMode mode) {
        return (getMode() == mode);
    }

    @Override
    public void setPullResistance(PinPullResistance resistance) {
        provider.setPullResistance(pin, resistance);
    }

    @Override
    public PinPullResistance getPullResistance() {
        return provider.getPullResistance(pin);
    }

    @Override
    public boolean isPullResistance(PinPullResistance resistance) {
        return (getPullResistance() == resistance);
    }

    @Override
    public void high() {
        setState(PinState.HIGH);
    }

    @Override
    public void low() {
        setState(PinState.LOW);
    }

    @Override
    public void toggle() {
        if (getState() == PinState.HIGH) {
            setState(PinState.LOW);
        } else {
            setState(PinState.HIGH);
        }
    }

    @Override
    public Future blink(long delay) {
        return blink(delay, PinState.HIGH);
    }

    @Override
    public Future blink(long delay, PinState blinkState) {
        // NOTE: a value of 0 milliseconds will stop the blinking
        return blink(delay, 0, blinkState);
    }

    @Override
    public Future blink(long delay, long duration) {
        return blink(delay, duration, PinState.HIGH);
    }

    @Override
    public Future blink(long delay, long duration, PinState blinkState) {
        // NOTE: a value of 0 milliseconds will stop the blinking
        return GpioScheduledExecutorImpl.blink(this, delay, duration, blinkState);
    }
    
    @Override
    public Future pulse(long duration) {
        return pulse(duration, false);
    }

    @Override
    public Future pulse(long duration, Callable callback) {
        return pulse(duration, false, callback);
    }

    @Override
    public Future pulse(long duration, PinState pulseState) {
        return pulse(duration, pulseState, false);
    }

    @Override
    public Future pulse(long duration, PinState pulseState, Callable callback) {
        return pulse(duration, pulseState, false, callback);
    }

    @Override
    public Future pulse(long duration, boolean blocking) {
        return pulse(duration, PinState.HIGH, blocking);
    }

    @Override
    public Future pulse(long duration, boolean blocking, Callable callback) {
        return pulse(duration, PinState.HIGH, blocking, callback);
    }

    @Override
    public Future pulse(long duration, PinState pulseState, boolean blocking) {
        return pulse(duration, pulseState, blocking, null);
    }

    @Override
    public Future pulse(long duration, PinState pulseState, boolean blocking, Callable callback) {
        
        // validate duration argument
        if(duration <= 0)
            throw new IllegalArgumentException("Pulse duration must be greater than 0 milliseconds.");
        
        // if this is a blocking pulse, then execute the pulse 
        // and sleep the caller's thread to block the operation 
        // until the pulse is complete
        if(blocking) {
            // start the pulse state
            setState(pulseState);
            
            // block the current thread for the pulse duration 
            try {
                Thread.sleep(duration);
            }
            catch (InterruptedException e) {
                throw new RuntimeException("Pulse blocking thread interrupted.", e);
            }

            // end the pulse state
            setState(PinState.getInverseState(pulseState));

            // invoke callback if one was defined
            if(callback != null){
                try {
                    callback.call();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            // we are done; no future is returned for blocking pulses
            return null;
        }
        else {            
            // if this is not a blocking call, then setup the pulse 
            // instruction to be completed in a background worker
            // thread pool using a scheduled executor 
            return GpioScheduledExecutorImpl.pulse(this, duration, pulseState, callback);
        }
    }
    
    @Override
    public void setState(PinState state) {
        provider.setState(pin, state);
    }

    @Override
    public void setState(boolean state) {
        provider.setState(pin, (state) ? PinState.HIGH : PinState.LOW);
    }

    @Override
    public boolean isHigh() {
        return (getState() == PinState.HIGH);
    }

    @Override
    public boolean isLow() {
        return (getState() == PinState.LOW);
    }

    @Override
    public PinState getState() {
        return provider.getState(pin);
    }

    @Override
    public boolean isState(PinState state) {
        return (getState() == state);
    }

    @Override
    public boolean hasDebounce(PinState state) {
        return (getDebounce(state) > NO_DEBOUCE);
    }

    @Override
    public int getDebounce(PinState state) {
        if(debounce.containsKey(state)){
            return debounce.get(state).intValue();
        }
        return NO_DEBOUCE;
    }

    @Override
    public void setDebounce(int debounce, PinState ... state) {
        for(PinState ps : state) {
            this.debounce.put(ps, new Integer(debounce));
        }
    }

    @Override
    public void setDebounce(int debounce) {
        setDebounce(debounce, PinState.HIGH, PinState.LOW);
    }

    @Override
    public void setValue(double value) {
        provider.setValue(pin, value);
    }
    
    @Override
    public double getValue() {
        return provider.getValue(pin);
    }    

    @Override
    public void setPwm(int value) {
        provider.setPwm(pin, value);
    }
    
    @Override
    public int getPwm() {
        return provider.getPwm(pin);
    }  
    
    private synchronized void updateInterruptListener() {
        if (listeners.size() > 0 || triggers.size() > 0) {
            if (monitor == null) { 
                // create new monitor and register for event callbacks
                monitor = new GpioEventMonitorExecutorImpl(this);
                provider.addListener(pin, monitor);
            }
        } else {
            if (monitor != null) {
                // remove monitor and unregister for event callbacks
                provider.removeListener(pin, monitor);

                // destroy monitor instance
                monitor = null;
            }
        }
    }

    /**
     * 
     * @param listener gpio pin listener interface
     */
    public synchronized void addListener(GpioPinListener... listener) {
        if (listener == null || listener.length == 0) {
            throw new IllegalArgumentException("Missing listener argument.");
        }
        Collections.addAll(listeners, listener);
        updateInterruptListener();
    }

    public synchronized void addListener(List listeners) {
        for (GpioPinListener listener : listeners) {
            addListener(listener);
        }
    }

    /**
     * 
     */
    public synchronized Collection getListeners() {
        return listeners;
    }

    @Override
    public boolean hasListener(GpioPinListener... listener) {
        if (listener == null || listener.length == 0) {
            throw new IllegalArgumentException("Missing listener argument.");
        }
        for (GpioPinListener lsnr : listener) {
            if (!listeners.contains(lsnr)) {
                return false;
            }
        }

        return true;
    }
    
    public synchronized void removeListener(GpioPinListener... listener) {
        if (listener == null || listener.length == 0) {
            throw new IllegalArgumentException("Missing listener argument.");
        }
        for (GpioPinListener lsnr : listener) {
            listeners.remove(lsnr);
        }
        
        updateInterruptListener();
    }

    public synchronized void removeListener(List listeners) {
        for (GpioPinListener listener : listeners) {
            removeListener(listener);
        }
    }
    
    public synchronized void removeAllListeners() {
        List listeners_copy = new ArrayList<>(listeners);
        for (int index = (listeners_copy.size()-1); index >= 0; index --) {
            GpioPinListener listener = listeners_copy.get(index);
            removeListener(listener);
        }
    }

    /**
     * 
     */
    public synchronized Collection getTriggers() {
        return triggers;
    }

    public synchronized void addTrigger(GpioTrigger... trigger) {
        if (trigger == null || trigger.length == 0) {
            throw new IllegalArgumentException("Missing trigger argument.");
        }
        Collections.addAll(triggers, trigger);
        updateInterruptListener();
    }

    public synchronized void addTrigger(List triggers) {
        for (GpioTrigger trigger : triggers) {
            addTrigger(trigger);
        }
    }

    /**
     * 
     * @param trigger GPIO trigger interface
     */
    public synchronized void removeTrigger(GpioTrigger... trigger) {
        if (trigger == null || trigger.length == 0) {
            throw new IllegalArgumentException("Missing trigger argument.");
        }
        for (GpioTrigger trgr : trigger) {
            triggers.remove(trgr);
        }
        
        updateInterruptListener();
    }

    public synchronized void removeTrigger(List triggers) {
        for (GpioTrigger trigger : triggers) {
            removeTrigger(trigger);
        }
    }

    public synchronized void removeAllTriggers() {
        List triggers_copy = new ArrayList<>(triggers);
        for (int index = triggers_copy.size() - 1; index >= 0; index--) {
            GpioTrigger trigger = triggers_copy.get(index);
            removeTrigger(trigger);
        }
    }

    @Override
    public String toString() {
        if (name != null && !name.isEmpty()) {
            return String.format("\"%s\" <%s>", name, pin.toString());
        } else {
            return pin.toString();
        }
    }

    @Override
    public GpioPinShutdown getShutdownOptions() {
        return shutdownOptions;
    }

    @Override
    public void setShutdownOptions(GpioPinShutdown options) {
        shutdownOptions.setUnexport(options.getUnexport());
        shutdownOptions.setState(options.getState());
        shutdownOptions.setMode(options.getMode());
        shutdownOptions.setPullResistor(options.getPullResistor());
    }

    @Override
    public void setShutdownOptions(Boolean unexport) {
        setShutdownOptions(unexport, null);
    }

    @Override
    public void setShutdownOptions(Boolean unexport, PinState state) {
        setShutdownOptions(unexport, state, null);
    }

    @Override
    public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance)
    {
        setShutdownOptions(unexport, state, resistance, null);
    }

    @Override
    public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance, PinMode mode) {
        shutdownOptions.setUnexport(unexport);
        shutdownOptions.setState(state);
        shutdownOptions.setMode(mode);
        shutdownOptions.setPullResistor(resistance);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy