Digital In/Out

micropython___circuitpython_photo-1515930478261-eddcc07befd1.jpg
By Grahame Jenkins, license free via UnSplash

Part of programming microcontrontrollers is working with I/O. The most basic form of I/O is digital I/O pins. These are known as GPIO pins (General Purpose Input Output)

Quick Reference

Configuring a pin for output

Arduino

pinMode(13, OUTPUT);

CircuitPython

import digitalio
import board
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT

Configuring a pin for input without pullup

Arduino

pinMode(13, INPUT);

CircuitPython

import digitalio
import board
button_a = digitalio.DigitalInOut(board.BUTTON_A)
button_a.direction = digitalio.Direction.INPUT

Configuring a pin for input with a pullup

Arduino

pinMode(13, INPUT_PULLUP);

CircuitPython

import digitalio
import board
button_a = digitalio.DigitalInOut(board.BUTTON_A)
button_a.direction = digitalio.Direction.INPUT
button_a.pull = digitalio.Pull.UP

Reading from a pin

Arduino

int pinValue = digitalRead(inputPin);

CircuitPython

pinValue = button_a.value

Writing to a pin

Arduino

digitalWrite(13, HIGH);
digitalWrite(13, LOW);

CircuitPython

led.value = True
led.value = False

Discussion

Configuring a Digital I/O Pin

Before you can use a pin for input or output, it must be configured. That involves setting it to be input or output, as well as attaching a pullup or pulldown if required.

Arduino

The Arduino framework provides the pinMode function for this. It takes two arguments:

  1. the pin number being configured. You use this same pin number later to use the I/O line
  2. the mode: INPUT, OUTPUT, or INPUT_PULLUP.

To set the standard pin 13 onboard LED to be usable, you would use:

Download: file
pinMode(13, OUTPUT);

CircuitPython

In CircuitPython, it's a little more work. You need create a DigitalInOut instance. To do this you must first import the digitalio module. As in the Arduino example, you give it the pin number to use.

In the above Arduino example, how did we know what pin number to use? The short answer is that we just did. In this example, its a convention that the onboard LED is on pin 13. For other GPIO pins you need to check the board you're using to see what pins are available and what one you connected your circuit to.

In Arduino, there's no compile-time check that the pin you've selected is valid or exists. CircuitPython will only let you use pins that the board knows about, which keeps you from making typos.

 (If you import the board module (more on importing later) you can use it to list the pins available.)

Download: file
>>> import digitalio
>>> import board
>>> led = digitalio.DigitalInOut(board.D13)
>>> led.direction = digitalio.Direction.OUTPUT

If we needed an input we would use digitalio.Direction.INPUT and if we needed to set a pullup we do that separately.

Download: file
>>> import digitalio
>>> import board
>>> button_a = digitalio.DigitalInOut(board.BUTTON_A)
>>> button_a.direction = digitalio.Direction.INPUT
>>> button_a.pull = digitalio.Pull.UP

The SAMD boards that CircuitPython runs on also support setting a pulldown on input pins. For that you'd use

Download: file
>>> pin.pull = digitalio.Pull.DOWN

Using a Digital I/O Pin

Now that you have a pin set up, how do you read and write values?

Arduino

The framework provides the digitalRead function that takes the pin number as an argument.

Download: file
int pinValue = digitalRead(inputPin);

The value returned from digitalRead is of type int and will be one of the constants HIGH or LOW.

The digitalWrite function is used to set the pin value. Its arguments are the pin number and the value to set it to: HIGH or LOW. For example to turn on the LED connected to pin 13, assuming it has been set as an output as above, you use:

Download: file
digitalWrite(13, HIGH);

And to turn it off:

Download: file
digitalWrite(13, LOW);

The example here shows using a digital output pin to blink the builtin LED: the defacto Hello World of microcontroller programming.

Download: file
void setup()
{
  pinMode(13, OUTPUT);          // sets the digital pin 13 as output
}

void loop()
{
  digitalWrite(13, HIGH);       // sets the digital pin 13 on
  delay(1000);                  // waits for a second
  digitalWrite(13, LOW);        // sets the digital pin 13 off
  delay(1000);                  // waits for a second
}

Putting digital input and output together, here's an example that reads from a switch and controls an LED in response.

Download: file
int ledPin = 13;   // LED connected to digital pin 13
int inPin = 7;     // pushbutton connected to digital pin 7
int val = 0;       // variable to store the read value

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin 13 as output
  pinMode(inPin, INPUT);        // sets the digital pin 7 as input
}

void loop()
{
  val = digitalRead(inPin);     // read the input pin
  digitalWrite(ledPin, val);    // sets the LED to the button's value
}

CircuitPython

Assume led and switch are set up as above.

Input pins can be read by querying their value property:

Download: file
>>> button_a.value

We can turn the led on and off by setting its value property of the DigitalInOut object to a boolean value:

Download: file
>>> led.value = True
>>> led.value = False

To implement the blinking demo in CircuitPython we would do somethign like:

Download: file
>>> import time
>>> import digitalio
>>> import board
>>> led = digitalio.DigitalInOut(board.D13)
>>> led.direction = digitalio.Direction.OUTPUT
>>> while True:
...    led.value = True
...    time.sleep(0.5)
...    led.value = False
...    time.sleep(0.5)
This guide was first published on Oct 22, 2018. It was last updated on Oct 22, 2018. This page (Digital In/Out) was last updated on May 26, 2019.