Dart on Pi - Getting Started

Raspberry Pi

The Raspberry Pi (aka RPi or Pi) is a great low cost platform for embedded development...

… and can be easily purchased from many suppliers:

There are many different OSs that run on the Pi. I'm using Raspbian, which appears to be the most commonly used OS on the Pi. There are many ways to set up the Raspberry Pi, but the simplest is to buy (or create) an SD card with NOOBS which hand holds you through installation.

There is a whole RPi for beginners page for configuring various aspects of your Pi. By default(?) the RPi boots with a GUI, but I only access the Pi remotely over SSH. I have setup the SSH server on the Pi and disabled desktop GUI.

Dart - Install the SDK

You can program the Pi using several different languages, but I'm interested in developing using the Dart programming language on the Raspberry Pi. Use DartPad as an easy way to try out the language, become familiar with the features, and share program snippets.

At the moment, installing the Dart is more involved than it needs to be, but I hope that can change. I would like to install and update Dart using a single apt-get command, but at the moment there are several more steps.

  • Unzip the SDK onto your pi (e.g. /home/pi/dart/dart-sdk) then add symlinks so that dart and pub can be easily run from the command line. sudo ln -s /home/pi/dart/dart-sdk/bin/dart /usr/bin/dart sudo ln -s /home/pi/dart/dart-sdk/bin/pub  /usr/bin/pub

Accessing the GPIO pins

Developing on Raspbian on Pi is the same as developing on any other Linux machine. You can use dart:io to access the file system, package:ddns_client to keeping the remote address of a Pi in sync, etc, but to do anything unique with the Pi, you need access to the hardware connected to it via the GPIO pins. There was no Dart library to do so, thus I created package:rpi_gpio. At this time, it only provides support for basic access to the GPIO pins, but over time I hope to add support for all the GPIO functionality such as SPI and I2C. It is designed so that the underlying hardware can be mocked and your application tested on any computer using the package:test.

Installing package:rpi_gpio

Start by creating a directory with a simple pubspec.yaml referencing package:rpi_gpio.

name: gpio_example
version: 0.0.1
description: a simple Dart app that reads the GPIO pins
 rpi_gpio: '<0.5.0'
 sdk: '>=1.0.0 <2.0.0'

Next, cd to the directory containing the pubspec.yaml file and run pub get from that directory. This will cache package:rpi_gpio on your Pi and print output something like this…

$ pub get
Resolving dependencies... (12.2s)
+ path 1.3.5
+ rpi_gpio 0.1.0
Downloading rpi_gpio 0.1.0...
Downloading path 1.3.5...
Changed 2 dependencies!
Precompiling executables...
Loading source assets...
Precompiled rpi_gpio:build_lib.

The rpi_gpio package needs a native library not included in the download and which must be manually built. See the rpi_gpio library setup instructions for building the native library on your RPi. When building the native library, if you see the following…

Marker file not found: /home/pi/.raspberrypi
If this is running on a Raspberry Pi, please create this file

… then create the specified file and rerun the build.

Reading the GPIO pin values

Next, create simple Dart app for reading the values of the GPIO pins.

import 'package:rpi_gpio/rpi_gpio.dart';
import 'package:rpi_gpio/rpi_hardware.dart';

/// Read current values for pins 0 - 7
main() {
 Gpio.hardware = new RpiHardware();
 var gpio = Gpio.instance;
 for (int pinNum = 0; pinNum < 8; ++pinNum) {
   var pin = gpio.pin(pinNum, input);
   print('${pin.value} => ${pin.description}');

Run this dart application from the command line…

$ sudo dart read_pins.dart
0 => Pin 0  (BMC_GPIO 17, Phys 11)
1 => Pin 1  (BMC_GPIO 18, Phys 12, PMW)
0 => Pin 2  (BMC_GPIO 27, Phys 13)
0 => Pin 3  (BMC_GPIO 22, Phys 15)
1 => Pin 4  (BMC_GPIO 23, Phys 16)
1 => Pin 5  (BMC_GPIO 24, Phys 18)
1 => Pin 6  (BMC_GPIO 25, Phys 22)
1 => Pin 7  (BMC_GPIO 4,  Phys 7,  Clock)

When you run this, if you get the following error message…

Cannot find extension library'package:rpi_gpio/rpi_hardware.dart': error: line 5 pos 1: library handler failed
import 'dart-ext:rpi_gpio_ext';

… then you need to follow the instructions above for building the native library.

Mocking the GPIO hardware

I find it useful to develop on my laptop and deploy to the RPi, but if I run the program above on the my laptop, it terminates with the "Cannot find extension library'package:...…." exception described above. One approach is to defer import package:rpi_gpio/rpi_hardware.dart as shown below and call loadLibrary() if the application is running on the RPi. If the application is not running on the RPi, then we have to supply a mock hardware class to simulate running on the RPi. Although not particularly useful here, this approach is very useful when testing larger applications.

import 'package:rpi_gpio/rpi_gpio.dart';
import 'package:rpi_gpio/rpi_hardware.dart' deferred as rpi;

/// Read current values for pins 0 - 7
main() {

 if (isRaspberryPi) {
   // Initialize the underlying hardware library
   Gpio.hardware = new rpi.RpiHardware();
 } else {
   // Mock the hardware when testing
   Gpio.hardware = new MockHardware();

 var gpio = Gpio.instance;
 for (int pinNum = 0; pinNum < 8; ++pinNum) {
   var pin = gpio.pin(pinNum, input);
   print('${pin.value} => ${pin.description}');

/// Simulate hardware when testing.
class MockHardware implements GpioHardware {

 /// Simulate all pins return value of 1 (high).
 int digitalRead(int pin) => 1;

 /// Called to set pin in input mode.
 void pinMode(int pin, int mode) {}

 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);


Popular posts from this blog

Dartino - Getting Started

Dart on Pi - Tracking Changes