swift

You can do quite a bit with GPIO (general purpose input/output) pins on devices like the Raspberry Pi and Beaglebone. Here I’ll show you how to set it up to perform a couple of simple tasks, like blink an LED and read the temperature from temperature sensor called the DS1820B. If you don’t know much about electronics, that’s OK – there’s nothing major here, just a few points to follow as you go along. I’ll explain them in further detail at the right time.

Setting Up

These examples will focus on the Raspberry Pi, because that’s what I have easiest access to, but with some minor modifications they could work with a Beaglebone black. At the time of this writing, Swift is available for the Raspberry Pi 2 & 3, including package manager. You can download the Swift 3.0 binaries from Joe Bell’s Jenkins build if you don’t wish to compile Swift yourself. I personally like to keep a couple versions of Swift builds and symlink to the “current” one, with
~/swift/current/ (a symlink) listed in my bash profile’s
$PATH list. That way I can change the symlink at will.

Side note: I work with both Raspbian and Xenial (Ubuntu/ARM). At the time of this writing, there appears to be some issue getting the 1wire interface to work on Xenial, though I am able to compile swift completely, which proves difficult on Raspbian. Basic functionality, like blinking LEDs, seems to work on Xenial, but I haven’t had an opportunity to try other interfaces. On the surface level they appear available and usable.

Sanity + Smoke Test

The ribbon cable between the Raspberry Pi and the breakout board can be inserted either way (right or wrong), so it’s important to do the check first. Hook up your jumper cables from the 3.3 or 5V pin on the breakout to the breadboard row containing your 220Ω resistor. Following this diagram below. Make sure your LED is inserted properly (long let at positive). Click for full-sized view.

Sanity check. If your ribbon cable and jumpers are inserted properly, the LED should light up. This configuration connects the 3.3V pin directly to the resistor/LED. It should light up if all is connected properly.

Next, connect the jumper from 3.3V to the row corresponding to GPIO Pin 17.

It may be worthwhile to install WiringPi so you can test GPIO connections via the command line rather than compiling swift every time. In our example above with pin17 connected to the LED:

Shell

1

2

3

gpio mode17out

gpio write170

gpio write171

This should work for you, but I did run into some issues from time to time where it simply refused to work properly (I’m sure I did something wrong!).. You should see the LED turn on.

SwiftyGPIO

Check out SwiftyGPIO and see how the examples are configured. It’s quite straightforward. Using this, we’re going to build on them to read from a 1-wire digital temperature sensor (DS18B20). Let’s get started configuring the Pi to user the 1-wire interface.

First, a brief overview. You define the GPIO type by passing an enum value for your hardware. In this case the .RaspberryPi2 applies to both the Pi2 and Pi3. We’ll go with that. We’ll then keep a reference to the GPIO #17 pin, as in the above smoke test. Note that this is the actual GPIO number, not the number as it would apply to the pin number on the circuit board.

Swift

1

2

letgpios=SwiftyGPIO.GPIOs(for:.RaspberryPi2)

vargp=gpios[.P17]!

You set the direction (either IN for things like sensors, or OUT for things like LEDs)

Swift

1

gp.direction=.OUT

and finally turn on the LED,

Swift

1

gp.value=1

From the SwiftyGPIO examples, let’s look at what a continuously blinking LED program would look like, modified for our hardware example.

Swift

1

2

3

4

5

6

7

8

9

10

importGlibc

letgpios=SwiftyGPIO.GPIOs(for:.RaspberryPi2)

vargp=gpios[.P17]!

gp.direction=.OUT

repeat{

gp.value=(gp.value==0)?1:0

usleep(150*1000)

}while(true)

You can include the
SwiftyGPIO.swift file next to your main and compile the whole with
swiftc*.swift&&sudo./main

The programming really isn’t very hard, so let’s move on to our temperature sensor.

Hardware Config

First you need to enable GPIO on the Pi, and to do that you need to write some configs to the boot config file. If you’re running Raspbian (and expect to use pre-build binaries), you’ll need to edit the
/boot/config.txt file; if you’re on Xenial/Ubuntu, it’s
/boot/firmware/config.txt .

add this line to the end, if it’s not already in there:

Swift

1

dtoverlay=w1-gpio,gpiopin=4

Reboot the machine.

You’ll then need to check that everything worked just fine

Shell

1

2

3

4

5

6

7

sudomodprobew1-gpio

sudomodprobew1-therm

cd/sys/bus/w1/devices

ls

cd28-{rest_of_id_number}

ls

catw1_slave

The output will look something along these lines,

Shell

1

2

b9014b467fff0c10f2:crc=f2 YES

b9014b467fff0c10f2t=27562

That t= value is degrees C * 1000. We’ll end up parsing it in the readTemp program.

Temperature Sensor

Here’s a little program (http://github.com/iamcam/swiftyArm/readTemp) with 1-wire temp sensor (DS18B20) and two status LEDs. Follow the wiring diagram below. I’ve included the Pin numbers on labels because sometimes the Fritzing pin numbering can be a bit blurry. The gist of this little project is to perform a temperature reading whilst making an LED blink on a separate thread

Assuming you have a functioning Swift build on your Pi, you should be able to download the repo, build the readTemp project with package manager, and run the output.

Shell

1

2

3

4

5

6

7

$swift build

Cloning https://github.com/uraimo/SwiftyGPIO.git

HEADisnow atd6fd508 Updated packagename,newrelease

Resolved version:0.8.2

Compile Swift Module'SwiftyGPIO'(4sources)

Compile Swift Module'readTemp'(3sources)

Linking.build/debug/readTemp

Then execute it:

Shell

1

$sudo.build/debug/readTemp

Some lights will blink and partway through, the read status LED will illuminate and the temperature will print out to the command line,

27.562°C/81.6116°F

And that’s about it. Besides getting a stable Swift working, this project wasn’t very hard. Getting the wiring set up properly is probably the most difficult. Surely in a few months time we’ll have a stable Swift that’s less of a moving target.

I often write these blog posts in part to remind my future self how I did something as well as for the benefit others. Today I’m looking at what’s involved with compiling Swift for ARM devices, namely the popular Raspberry Pi. While these are meant for the RPi, they should also apply generally to devices like the BeagleBone Black. Before you get started, you should be reminded that Swift3 is very much an alpha-level project, especially on ARM devices. There are times when swift won’t even compile properly, or even if it does compile, there could be issues running it smoothly. armv7 devices (BeagleBone Black, Raspberry Pi2, and others) seem to be most reliable; armv8 (Raspberry Pi3) are in the weeds, so to speak, because there’s been little effort toward that architecture due to resources. It will probably work in the future, just not as well in June, 2016. Now that you’ve been adequately warned, let’s begin.

Contents

Making a Swapfile

Installing required components

Getting and building the source

Cross compiling

Conclusion

Make a Big Ol’ Swapfile

You’ll need to have a lot of memory to compile swift, and while the Raspberry Pi has 1GB, it’s not enough. Let’s start with increasing the swapfile size by following the from over here. (Paraphrased below)

Edit the configuration file at
/etc/dphys-swapfile

Shell

1

sudo nano/etc/dphys-swapfile

Find
CONF_SWAPSIZE and set the value to 2048 :

Shell

1

CONF_SWAPSIZE=2048

Reboot or stop/start the dphys-swapfile service

Shell

1

2

sudo/etc/init.d/dphys-swapfile stop

sudo/etc/init.d/dphys-swapfile start

It may take several minutes, so be patient.

One point some have noted is that having a large swapfile as this lends to decreasing the lifespan of the memory card due to the large amount of writes you’d expect in a swapfile. It’s a risk you run, but 32GB memory cards are inexpensive. Keep backups if it concerns you

Just one note – notice the tee command at the end. That takes the input and write it to a file. Since the Swift build process doesn’t output build logs, we pipe the build output to tee so we can save it, in case there was an error along the way. Sometimes these errors are minor and occur after the swift binaries successfully build. It’s important to know.

Now, it’s time to wait several hours for first build. You remember to enter a screen session, right?

When it’s all said and done, you should be able to run swiftc on a simple helloWorld.swift

Shell

1

~/swift/usr/bin/swiftc helloWorld.swift&&./helloWorld

Cross-Compiling

Attempting to build Swift on these low-powered devices is a noble effort, but it takes a very long time. I personally don’t like having to wait several hours to find out the build failed. That’s where cross-compiling comes in. This process means you build binaries on one platform (for example, a Mac/Intel) that work on another (Linux/armv7). Usually takes less than an hour. The following instructions are meant to be executed on a Mac.

First, you need to install dpkg so the build system can create a proper debian package

Download all the appropriate repos and branches using
./crosscompile_get.sh

Next, it’s time to build:
./crosscompile_build.sh-tlinux-armv7

When the build is complete, copy it over to your Pi. If all went well, you should have functioning Swift binaries*.

*Of course, there may still be issues with Swift on ARM itself – it’s still alpha.

Conclusion

I hope this tutorial was helpful. At the time of this writing, there were still several considerable issues with Swift on ARM devices, but it is possible to compile it yourself. If you continue to run into issues, it may be worthwhile to check back at Joe’s Website for updates and downloadable binaries.

I’m working on a series in conjunction with some talks I’m giving this spring/summer at the All Things Swift meetup here in San Diego. As one might expect, many Swift developers don’t have much linux experience. That’s perfectly fine – it doesn’t take a much to get started. I even come back to this setup process every time I set up new Raspberry Pis. Everything here assumes a Raspberry Pi 3 with Raspbian Jessie. Otherwise YMMV.

Before we get started, I’ll add this one note – Swift is under heavy development right now. Joe Bell has created a Swift-2.2 Debian package (below), and a number of people are working hard on Swift-3.0 for ARM devices. Development on Swift-2.2 has ceased in favor of bringing Swift-3.0 up to speed. Only recently has anyone been able to compile Swift on a somewhat consistent basis. There’s a good chance that within a few months many of the issues will be worked out.

Connecting

First, let’s make connecting our Pi a bit easier – install VNC and Bonjour (netatalk + avahi). The former enables screen sharing, and the latter allows you to connect to your Pi at an address such as
vnc://pi.local/ on your local network – much easier than remembering an IP address. Contributor fguillen posted a concise set of instructions on StackOverflow. Rather than re-hash his instructions, head over there. Remember to reboot the Pi when you’re finished (sometimes VNC doesn’t work properly without it).

If during setup, you did not change the default hostname, you can now connect to your Pi at
vnc://pi@raspberrypi . If you’d like to change it, as I did, you can run the raspi-config tool (via the GUI or command line). By running raspi-config, all the necessary config file changes are made for you.

At this point there’s little reason to keep the Pi connected to a monitor or TV. My next step is to stash it away somewhere out of the way so I can clear up some desk space. From now on, I’m connecting to the pi at ssh pi@pi.local .
.

Cut the Fat

If you plan on compiling Swift on your Pi (more on that another day), you’ll need at least a 16GB memory card. If you’re on the lower end, you may need to remove some extra cruft. Let’s start with LibreOffice, Mathematica, and Wolfram.

Shell

1

sudo apt-getautoremove mathematica*libreoffice*wolfram*

Swift via apt-get

The easiest way to get swift running on your RPi is to install Swift 2.2 via apt-get. There are several steps involved, but Joe Bell laid them out well. Follow them, but with a few important changes:

Go ahead and complete his instructions. When you’re finished, you’ll have a working Swift-2.2 installation.

There’s something important you need to know – the Swift REPL doesn’t work (yet). Neither does the Swift Package Manager. While you won’t be able to use any libraries that come via SwiftPM, you can still write some simple apps using Foundation and Glibc.

Let’s try a very simple Hello World…

Swift

1

print("Hello 🌍")

Compile and run…

Shell

1

swiftc helloWorld.swift&&./helloWorld

Finally! Doesn’t it feel great to see something familiar running outside the Walled Garden?

I mentioned compiling Swift from source above. That will come another time – certainly more involved than I intended for this post.

I’ve taken recent interest in working on the Raspberry Pi now that Swift is open source. Given the amount of products built specifically for the Pi, there’s a huge potential for new, fun projects. DIY electronics have been gaining momentum over the last few years and there’s a lot of information to help you get started. Depending on how things go in the coming months, I may be able to start pitching physical computing devices for client projects.

At the time of this writing (April 2016), there’s not much to be said about getting Swift working properly on devices like the Raspberry Pi. While a few individuals have made great headway into making swift compile for linux arm7, the work isn’t complete and a few critical pieces are missing. Even now, not a lot of progress has been made since January, when it all started to work.

To put it simply this is what does and does not work. Set your expectations accordingly.

A build of Swift 2.2 “works” – you can compile and link to Foundation + Glibc

That build is from February, 2016

The Swift REPL doesn’t work – crashes with a memory bug

Full set of Swift3 tools don’t compile (yet)

Getting Started

I’m using a Raspberry Pi3 running the latest Raspbian Jessie. Head over to Joe Bell’s instructions for the Raspberry Pi and follow them exactly. This will give you a workable Swift 2.2 install via apt-get. I’m sorry there aren’t more exciting instructions here, but that’s really the crux of our predicament – that seems to be the only reliable way to get swift running on the Pi for now.

Once you have Swift properly installed, give some examples a try (scroll down) – using Foundation and Glibc. It feels good to see Swift running on something other than an iPhone or Mac.

Next Steps

I’m currently working with (I use that word loosely – I don’t have the knowledge to be a productive contributor) with Joe Bell, Will Dillon, and Morris Cornell-Morgan to see if we can figure out what how we can get builds working for the Pi and other armv7 devices.

I had the most success attempting to compile Swift on the Pi in over a month last night – this happened to be within just a day or so of the main Swift repo switching over to swift-3.0 development. Most of the tools appeared to compile fine, but package manager failed, and there were some issues with linking (this could be a build config issue). I remain hopeful.

I’ll continue to post progress as it comes. In the meantime, I’m preparing a talk on this subject at the All Things Swift meetup in May.