Working with open source developers worldwide is a fun and rewarding experience. As the cost of computing devices and broadband Internet continues to fall and bring new technologies to people around the globe, developers of all stripes from different cultures and backgrounds come together to collaborate and build awesome things.
Since Apple open sourced the Swift programming language late last year enthusiasts have created Ubuntu packages, ported it to ARM devices such as the Raspberry Pi 2, built web development frameworks, and now Umberto Raimondi has released SwiftyGPIO, a Swift library for interacting with GPIO pins on ARM devices such as the Raspberry Pi and BeagleBone Black.
The SwiftyGPIO README covers all the bases explaining how to use the module. As Umberto notes the Swift Package Manager is currently unavailable in the ARM builds (I’ve been working on getting it to compile but something always preempts me) so we turn to downloading the SwiftyGPIO.swift
file with wget
and using swiftc
to compile and link everything together.
Rock Chalk
Last year I was working with Arduino programming with Xcode and wrote up some Arduino code for blinking LEDs. Let’s do the same with a Raspberry Pi 2 and Swift.
If you’re coming into this cold you’re going to need:
- a Raspberry Pi 2
- a couple of LEDs
- wires for wiring
- Swift installed on your Pi 2
We’re going to use GPIO4 and GPIO27 since they are close to each other on the Pi 2 GPIO header.
Here is our main.swift
to blink the two lights back and forth:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import Glibc let gpios = SwiftyGPIO.getGPIOsForBoard(.RaspberryPiPlus2Zero) // GPIO4 and GPIO27 let leds = [gpios[.P4]!, gpios[.P27]!] // Initialize our GPIOs for led in leds { led.direction = .OUT led.value = 0 } // Blink while true { for led in leds { led.value = 1 sleep(1) led.value = 0 } } |
To compile and run this code, until SwiftPM for ARM is fixed, we do this:
# wget https://raw.githubusercontent.com/uraimo/SwiftyGPIO/master/Sources/SwiftyGPIO.swift # swiftc main.swift SwiftyGPIO.swift # ./main
If you wired your LEDs up properly they should be flashing back and forth!
Pick Your Color
I had a Linrose Tricolor LED lying around so I decided to put it to good use with Swift. In this code example we’ve written a command line application that lets you set the color of the LED (or to turn it off). I’ve marked the code with // 1
, // 2
to describe each section.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import Glibc // 1 let gpiodefs = SwiftyGPIO.getGPIOsForBoard(.RaspberryPiPlus2Zero) // 2 enum GPIOState:Int { case Off = 0 case On } // 3 struct LedColor { static let Off = (GPIOState.Off, GPIOState.Off) static let Green = (GPIOState.On, GPIOState.Off) static let Orange = (GPIOState.On, GPIOState.On) static let Red = (GPIOState.Off, GPIOState.On) } // 4 let gpios = [gpiodefs[.P4]!, gpiodefs[.P27]!] for gpio in gpios { gpio.direction = .OUT gpio.value = GPIOState.Off.rawValue } // 5 func setLedColor(color:(GPIOState,GPIOState), gpios:[GPIO]) { gpios[0].value = color.0.rawValue gpios[1].value = color.1.rawValue } // 6 guard Process.arguments.count == 2 else { print("Usage: ./main off|green|orange|red") exit(0) } let color = Process.arguments[1] // 7 switch color { case "off": setLedColor(LedColor.Off, gpios:gpios) case "green": setLedColor(LedColor.Green, gpios:gpios) case "orange": setLedColor(LedColor.Orange, gpios:gpios) case "red": setLedColor(LedColor.Red, gpios:gpios) default: print("Invalid color") } |
1. SwiftyGPIO
provides canned GPIO definitions for popular board types. In our case we’re using a Raspberry Pi 2.
2. This is purely syntactic sugar to describe GPIO states as On
or Off
. The code would probably look less cluttered if we removed this.
3. LedColor
is a structure to “namespace” definitions for Off
, Green
, Orange
, and Red
.
4. The tricolor LED has two anode pins; we will attach one pin to GPIO4 and the other to GPIO27. The application always starts by setting the pin direction to .OUT
and Off
. Again, because of the way we created an enum
for the GPIOState
we have to use the .rawValue
nonsense.
5. setLedColor
takes a tuple of (GPIOState,GPIOState)
and [GPIO]
array to set the pair of GPIO pins to a certain state.
6. Our application takes a single argument so we guard
that we have two (one is the application name). Our color is the second.
7. A switch on the color and a call is made to setLedColor
with the appropriate color tuple and GPIO set.
Closing Remarks
SwiftyGPIO is a great API to get started with GPIO manipulation on ARM boards with Swift. Each passing day Swift makes inroads into the maker community and stands a great chance to be the language of choice for single board computer development projects.