not logged in | [Login]

Here we show how to control pins using the pyb.Pin interface. The programmers guide is here basic Pin, ADC, Interrupts

  • Setting the mode of a pin for a specifc use.
  • Reading a pin's digital value.
  • Writing (setting) a pin high or low.
  • Reading and writing analog values.
  • Setting a pin to trigger an interrupt when it changes.

Basic usage

Setting a pin to a digital value

import pyb
g = pyb.Pin(pin_id, mode, pull) # mode and pull are optional arguments and default to input and no-pullup
# e.g. if:
#    X1 is how the pin is labeled on the board,
#    using X1 for output to control an LED,
#    we want a pullup resistor on the output.
g = pyb.Pin('X1', pyb.Pin.OUT_PP, Pin.PULL_UP)
g.low() # sets the pin low
g.value(True) # sets it high,
g.value(False) # sets it low
Reading a digital value from a Pin
g = pyb.Pin('X1', pyb.Pin.IN)
state = g.value() # no argument to value means read.

Details

Selecting a Pin

There are several ways to identify the pin to control:

  • by name
    • 'X1' (example above) which is defined on the board
  • by board lookup
    • mypin = pyb.Pin.board.X1
  • by cpu lookup (not all pins are exposed on the edge connectors on every board)
    • mypin = pyb.Pin.cpu.C12
  • by defining your own mapping
    • pyb.Pin.dict["LeftMotorDir"] = pyb.Pin.cpu.C12
    • mypin = pyb.Pin("LeftMotorDir")

and use it like so: g = pyb.Pin(mypin, pyb.Pin.OUT_PP) or g = pyb.Pin(mypin, pyb.Pin.OUT_PP, Pin.PULL_UP)

Setting up the pin's modes

A pin can act in one of the following modes:

  • Pin.IN - configure the pin for input
  • Pin.OUT_PP - configure the pin for output, with push-pull control
  • Pin.OUT_OD - configure the pin for output, with open-drain control
  • Pin.AF_PP - configure the pin for alternate function, pull-pull
  • Pin.AF_OD - configure the pin for alternate function, open-drain
  • Pin.ANALOG - configure the pin for analog input. You may prefer to use pyb.ADC instead.

You would use push-pull control to actively drive the output high or low (use it as a current source or current sink). For example, if you connect an LED (using a resistor) between GND and the pin, the LED will light up if you drive the pin high. Since you configured the output to be push-pull, it will act as a current source here. Otherwise, if you switch an output to open-drain, it will only act as a current sink (it will drive low if you write 0 to it), but it can not deliver high level output if you switch it to its "1" state. This configuration could be used together with I2C devices, where an external pull-up resistor on SCL and SDA ensures high level and all bus nodes can only drive these bus lines to low level.

The Altenate function settings are used when the specific chipset has allocated a pin to do several functions internally, e. g. use the pin as SPI, UART, I2C, timer output etc. This alternate function is turned on by setting an internal register. This setting defines how thepPin mode will be handled if this is alternate function is active.

A pin can have the following pull-up settings:

  • Pin.PULL_NONE - no pull up or down resistors - This is the default
  • Pin.PULL_UP - enable the pull-up resistor
  • Pin.PULL_DOWN - enable the pull-down resistor

Analog values

We can use the pin directly or use the ADC. The ADC gives you more control.

Reading an analog value from a pin directly:

g = pyb.Pin('X1', pyb.Pin.ANALOG)
state = g.value() # no argument to value means read.
For more details on using the ADC see here.

Interrupts

Pins also have the ability to trigger an interrupt and do an action when the digital value of the pin changes. To do this we use Pin.ExtInt

import pyb
key_interrupt = pyb.ExtInt(pin_id, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, callback)
#E.g. if:
#   - You want to call the function count() when
#   - the pin X1 is pulled low then
key_interrupt = pyb.ExtInt('X1', pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, count)
Note:
  • You cannot register more than one callback to a pin
  • The interrupt routine must not allocate space (e.g. by creating a new variable). So it is limited to changing the values of existing variables and certain other effects. See Interrupts
  • A button might generate alot of pulses when it is contacted. You wil need to 'debounce' these triggers. One way might be to use extint.disable() in the count routine to ignore further interupts for a time.

Valid modes are:

  • pyb.ExtInt.IRQ_RISING
  • pyb.ExtInt.IRQ_FALLING
  • pyb.ExtInt.IRQ_RISING_FALLING
  • pyb.ExtInt.EVT_RISING
  • pyb.ExtInt.EVT_FALLING
  • pyb.ExtInt.EVT_RISING_FALLING

IRQ modes are used for ... EVT modes allow ...

Other useful functions for external interrupts are:

  • extint.disable() Disable the interrupt associated with the ExtInt object. This could be useful for debouncing.
  • extint.enable() Enable a disabled interrupt.
  • extint.line() Return the line number that the pin is mapped to.
  • extint.swint() Trigger the callback from software.