Basic GPIO with PICO APL3 part 2

From AAEON Community Wiki
Revision as of 19:29, 18 December 2018 by Filippo (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Introduction

In the previous post we learned how to configure and control the four GPIO signals available in the AAEON PICO-APL3 board using standard shell commands, and a shell script was presented showing how to automate the control of one digital output based on time.

In this article, we will demonstrate how to expand the shell script so that it can also read the state of an external signal (generated by a pushbutton) and use this information to control an output.

This will require the use of a command that didn’t appear in the previous script, although it was mentioned in the general GPIO control description. For the sake of clarity we will briefly repeat here the steps needed to read the state of a GPIO input (number 2 in this example):

     • Configuration:	# echo 2 > /sys/class/gpio/export
		        # echo “in” > /sys/class/gpio2/direction
     • Input read:	# cat /sys/class/gpio/gpio2
		        # 1                                       # or 0
     • Release:	        # echo 2 > /sys/class/gpio/unexport	  # when done

Example Script: button.sh

In this case we will use two GPIOs: one digital input to read the position of the button and one digital output to control an LED (we could also use a buzzer, a motor, a relay… it wouldn’t require any code modifications, only maybe some electronic tweaks depending on the characteristics of the chosen device). Therefore the script will need to be called with to numeric parameters, the GPIO numbers of the input and the output. For example, to use GPIO 3 as input and GPIO 0 as output:

# ./button.sh 3 0

Also remember that due to the commands used in the script, it needs to be run as root. The next listing shows the contents of the script:

#!/bin/bash
# button.sh – Read GPIO input and set GPIO output to the inverted value

GPIO_PATH=/sys/class/gpio
ON="1"
OFF="0"
INPIN=$1
OUTPIN=$2
IN="in"
OUT="out"
READVAL=9999
LASTVAL=9999

exportPin()
{
        if [ ! -e $GPIO_PATH/gpio$1 ]; then
                echo "$1" > $GPIO_PATH/export
        fi
}

unexportPin()
{
        if [ -e $GPIO_PATH/gpio$1 ]; then
                echo "$1" > $GPIO_PATH/unexport
        fi
}

setDirection()
{
        echo $2 > $GPIO_PATH/gpio$1/direction
}

getInState()
{
        READVAL=`cat $GPIO_PATH/gpio$1/value`
}

setOutState()
{
        echo $2 > $GPIO_PATH/gpio$1/value
}

shutDown()
{
        setOutState $OUTPIN $OFF
        unexportPin $INPIN
        unexportPin $OUTPIN
        echo
        echo "Shutting down $0..."
        exit 0
}

trap shutDown SIGINT

# Setup output pin
exportPin $INPIN
exportPin $OUTPIN
setDirection $INPIN $IN
setDirection $OUTPIN $OUT
setOutState $OUTPIN $OFF

# Loop until the user hits Ctrl-C
while [ 1 ]
do
        getInState $INPIN
        if [ ! $READVAL = $LASTVAL ]; then
                echo "Input has changed"
                LASTVAL=$READVAL
                if [ "$READVAL" = "0" ]; then
                        echo "Button is PRESSED"
                        setOutState $OUTPIN $ON
                else
                        echo "Button is RELEASED"
                        setOutState $OUTPIN $OFF
                fi
        fi
        sleep 0.1
done

If you may have noticed that the GPIO output is set to ON when the input value is 0, and to OFF when the input is 1. This might seem odd at first sight, but there is an explanation: the digital input is wired to the button using what is called a pull-up resistor, so when the button is not pressed this resistor ‘pulls’ the input to high level, and when the button is pressed the input is connected directly to ground (i.e. low level) through the button contact.

Demo Circuit

We can reuse most of the circuit of the blink demo since we only need to add a push-button (and pull-up resistor) and wire them properly. This is shown in the next picture:

GPIO2.png

GPIO2 is used for the input (yellow wire) and GPIO0 for the output (green wire), so the script should be run as follows:

# ./button.sh 2 0