def event_detected(channel): """ This function is designed to be used in a loop with other things, but unlike polling it is not going to miss the change in state of an input while the CPU is busy working on other things. This could be useful when using something like Pygame or PyQt where there is a main loop listening and responding to GUI events in a timely basis. .. code:: python GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel do_something() if GPIO.event_detected(channel): print('Button pressed') Note that you can detect events for :py:attr:`GPIO.RISING`, :py:attr:`GPIO.FALLING` or :py:attr:`GPIO.BOTH`. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :returns: :py:attr:`True` if an edge event was detected, else :py:attr:`False`. """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) return event.edge_detected(pin)
def output(channel, state): """ Set the output state of a GPIO pin. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param state: can be :py:attr:`0` / :py:attr:`GPIO.LOW` / :py:attr:`False` or :py:attr:`1` / :py:attr:`GPIO.HIGH` / :py:attr:`True`. **Output to several channels:** You can output to many channels in the same call. For example: .. code:: python chan_list = [11,12] # also works with tuples GPIO.output(chan_list, GPIO.LOW) # sets all to GPIO.LOW GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW)) # sets first HIGH and second LOW """ if isinstance(channel, list): for ch in channel: output(ch, state) else: _check_configured(channel, direction=OUT) pin = get_gpio_pin(_mode, channel) return sysfs.output(pin, state)
def add_event_detect(channel, trigger, callback=None, bouncetime=None): """ This function is designed to be used in a loop with other things, but unlike polling it is not going to miss the change in state of an input while the CPU is busy working on other things. This could be useful when using something like Pygame or PyQt where there is a main loop listening and responding to GUI events in a timely basis. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param trigger: The event to detect, one of: :py:attr:`GPIO.RISING`, :py:attr:`GPIO.FALLING` or :py:attr:`GPIO.BOTH`. :param callback: (optional) TODO :param bouncetime: (optional) TODO .. code: python GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel do_something() if GPIO.event_detected(channel): print('Button pressed') """ _check_configured(channel, direction=IN) if bouncetime is not None: if _gpio_warnings: warnings.warn( "bouncetime is not (yet) fully supported, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", stacklevel=2) pin = get_gpio_pin(_mode, channel) event.add_edge_detect(pin, trigger, __wrap(callback, channel))
def remove_event_detect(channel): """ :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) event.remove_edge_detect(pin)
def event_detected(channel): """ TODO :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :returns: :py:attr:`True` if an edge event was detected, else :py:attr:`False`. """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) return event.edge_detected(pin)
def remove_event_detect(channel): """ If for some reason, your program no longer wishes to detect edge events, this function will stop and remove the event detection thread. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) event.remove_edge_detect(pin)
def input(channel): """ Read the value of a GPIO pin. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :returns: This will return either :py:attr:`0` / :py:attr:`GPIO.LOW` / :py:attr:`False` or :py:attr:`1` / :py:attr:`GPIO.HIGH` / :py:attr:`True`). """ _check_configured(channel) # Can read from a pin configured for output pin = get_gpio_pin(_mode, channel) return sysfs.input(pin)
def add_event_callback(channel, callback, bouncetime=None): """ :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param callback: TODO :param bouncetime: (optional) TODO """ _check_configured(channel, direction=IN) if bouncetime is not None: if _gpio_warnings: warnings.warn("bouncetime is not (yet) fully supported, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", stacklevel=2) pin = get_gpio_pin(_mode, channel) event.add_edge_callback(pin, __wrap(callback, channel))
def add_event_callback(channel, callback): """ OPi.GPIO manages a number of secondary threads for callback functions. This means that callback functions can be run at the same time as your main program, in immediate response to an edge. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param callback: TODO For example: .. code:: python def my_callback(channel): print('This is a edge event callback function!') print('Edge detected on channel %s'%channel) print('This is run in a different thread to your main program') GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # add rising edge detection on a channel #...the rest of your program... If you wanted more than one callback function: .. code:: python def my_callback_one(channel): print('Callback one') def my_callback_two(channel): print('Callback two') GPIO.add_event_detect(channel, GPIO.RISING) GPIO.add_event_callback(channel, my_callback_one) GPIO.add_event_callback(channel, my_callback_two) Note that in this case, the callback functions are run sequentially, not concurrently. This is because there is only one thread used for callbacks, in which every callback is run, in the order in which they have been defined. """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) event.add_edge_callback(pin, __wrap(callback, channel))
def cleanup(channel=None): """ At the end any program, it is good practice to clean up any resources you might have used. This is no different with OPi.GPIO. By returning all channels you have used back to inputs with no pull up/down, you can avoid accidental damage to your Orange Pi by shorting out the pins. Note that this will only clean up GPIO channels that your script has used. Note that GPIO.cleanup() also clears the pin numbering system in use. To clean up at the end of your script: .. code:: python GPIO.cleanup() It is possible that don't want to clean up every channel leaving some set up when your program exits. You can clean up individual channels, a list or a tuple of channels: .. code:: python GPIO.cleanup(channel) GPIO.cleanup( (channel1, channel2) ) GPIO.cleanup( [channel1, channel2] ) """ if channel is None: cleanup(list(_exports.keys())) setwarnings(True) global _mode _mode = None elif isinstance(channel, list): for ch in channel: cleanup(ch) else: _check_configured(channel) pin = get_gpio_pin(_mode, channel) event.cleanup(pin) sysfs.unexport(pin) del _exports[channel]
def wait_for_edge(channel, trigger, timeout=-1): """ This function is designed to block execution of your program until an edge is detected. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param trigger: The event to detect, one of: :py:attr:`GPIO.RISING`, :py:attr:`GPIO.FALLING` or :py:attr:`GPIO.BOTH`. :param timeout: TODO In other words, the polling example above that waits for a button press could be rewritten as: .. code:: python GPIO.wait_for_edge(channel, GPIO.RISING) Note that you can detect edges of type :py:attr:`GPIO.RISING`, :py:attr`GPIO.FALLING` or :py:attr:`GPIO.BOTH`. The advantage of doing it this way is that it uses a negligible amount of CPU, so there is plenty left for other tasks. If you only want to wait for a certain length of time, you can use the timeout parameter: .. code:: python # wait for up to 5 seconds for a rising edge (timeout is in milliseconds) channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000) if channel is None: print('Timeout occurred') else: print('Edge detected on channel', channel) """ _check_configured(channel, direction=IN) pin = get_gpio_pin(_mode, channel) if event.blocking_wait_for_edge(pin, trigger, timeout) is not None: return channel
def setup(channel, direction, initial=None): """ You need to set up every channel you are using as an input or an output. :param channel: the channel based on the numbering system you have specified (:py:attr:`GPIO.BOARD`, :py:attr:`GPIO.BCM` or :py:attr:`GPIO.SUNXI`). :param direction: whether to treat the GPIO pin as input or output (use only :py:attr:`GPIO.IN` or :py:attr:`GPIO.OUT`). :param initial: When supplied and setting up an output pin, resets the pin to the value given (can be :py:attr:`0` / :py:attr:`GPIO.LOW` / :py:attr:`False` or :py:attr:`1` / :py:attr:`GPIO.HIGH` / :py:attr:`True`). To configure a channel as an input: .. code:: python GPIO.setup(channel, GPIO.IN) To set up a channel as an output: .. code:: python GPIO.setup(channel, GPIO.OUT) You can also specify an initial value for your output channel: .. code:: python GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH) **Setup more than one channel:** You can set up more than one channel per call. For example: .. code:: python chan_list = [11,12] # add as many channels as you want! # you can tuples instead i.e.: # chan_list = (11,12) GPIO.setup(chan_list, GPIO.OUT) """ if _mode is None: raise RuntimeError("Mode has not been set") if isinstance(channel, list): for ch in channel: setup(ch, direction, initial) else: if channel in _exports: raise RuntimeError("Channel {0} is already configured".format(channel)) pin = get_gpio_pin(_mode, channel) try: sysfs.export(pin) except (OSError, IOError) as e: if e.errno == 16: # Device or resource busy if _gpio_warnings: warnings.warn("This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.", stacklevel=2) sysfs.unexport(pin) sysfs.export(pin) else: raise e sysfs.direction(pin, direction) _exports[channel] = direction if direction == OUT and initial is not None: sysfs.output(pin, initial)