[Flutter App Dev] – Read a Barcode

This tutorial demonstrates how to use the camera plugin in combination with Firebase’s vision library to read any type of barcode. The example below is demonstrated using the Android emulator with the virtual scene option selected as the camera emulator.

Using the Android Emulator Virtual Scene

For those who do not wish to use the virtual scene, as shown above, please skip this section. Otherwise, start by creating an Android Emulator and select the virtual scene option for the camera of your choice.

Download any barcode image you can find on Google image search, run the emulator and click the ellipsis menu as shown below.

Finally, under the Camera option on the left nav, set the Wall image to point to this barcode file.

Project Setup

I’m not going to detail the steps to create a Flutter project. Instead, I will assume you already have your project ready and running. However, you will need to set up a Firebase Project and add it to your Flutter application project.

You may wonder why Firebase is used? Firebase has a service called ML Kit which we can pass an image to, and retrieve the values of any barcodes read. We can also rest assured that ML Kit has been trained to read all types of barcodes!

Setup Camera Preview

Luckily, there is a flutter plugin conveniently called Camera that allows us to have a camera preview along with the ability to acquire an image and pass it to Firebase ML Vision for barcode results.

Simply add the Camera plugin (with the current version) to your pubspec.yaml

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  camera: 0.3.0+3
pubspec.yaml

We’ll take the camera code example straight from there as a basis to work with.

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

List<CameraDescription> cameras;

Future<void> main() async {
  cameras = await availableCameras();
  runApp(App());
}

class App extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraApp(),
    );
  }
}

class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController controller;
	
  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }

    return Stack(
      alignment: Alignment.center,
      children: <Widget>[
        AspectRatio(
          aspectRatio:
          controller.value.aspectRatio,
          child: CameraPreview(controller)
        )
      ],       
    );
  }
}
Full screen camera preview example

** For those using the Android virtual scene for the camera preview, you can hold Alt + WSAD keys to move around (the wall is in the room behind you) **

Read a Barcode

Now we have a camera preview to work with, we can start taking an image and passing it to Firebase’s vision detection API. As the camera plugin is still in preview, there is currently no way to stream the camera’s preview into ML Kit. Although there is now the functionality to acquire the byte buffer of the preview, the pixel data is not in the correct format that the VisionImage class expects. Converting this to the expected format is out of scope for this tutorial.

Instead, we will create a timer that runs every 3 seconds that takes an image, saves it, and have ML Kit load and read this.

First, let us setup the timer code.

class _CameraAppState extends State<CameraApp> {
  CameraController controller;
  Timer _timer;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    controller.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});

      _startTimer();
    });
  }

  void _startTimer() {
    _timer = new Timer(Duration(seconds: 3), _timerElapsed);
  }

  void _stopTimer() {
    if(_timer != null) {
      _timer.cancel();
      _timer = null;
    }
  }

  Future<void> _timerElapsed() async{
    _stopTimer();

	// Code to capture image and read barcode here...

    _startTimer();
  }
}
Adding a callback timer

Now that we have the callback function ticking every 3 seconds (safeguarded incase the barcode detection overruns by stopping it during the callback tick) let’s take an image!

Future<void> _timerElapsed() async{
    _stopTimer();

    File file = await _takePicture();

    _startTimer();
  }

  Future<File> _takePicture() async {
    final Directory extDir = await getApplicationDocumentsDirectory();
    final String dirPath = '${extDir.path}/Pictures/barcode';
    await Directory(dirPath).create(recursive: true);
    final File file = new File('$dirPath/barcode.jpg');
    
    if(await file.exists())
      await file.delete();
    
    await controller.takePicture(file.path);
    return file;
  }
Take and save photo example

Every 3 seconds the image will be overridden and passed to the ML Kit API as described below:

class _CameraAppState extends State<CameraApp> {
  CameraController controller;
  Timer _timer;
  String _barcodeRead = "";  // Add this ...
	
  // Rest of CameraAppState's methods ...
	
  Future<void> _timerElapsed() async{
    _stopTimer();

    File file = await _takePicture();

    await _readBarcode(file);

    _startTimer();
  }
	
  Future _readBarcode(File file) async {
    FirebaseVisionImage firebaseImage = FirebaseVisionImage.fromFile(file);
    final BarcodeDetector barcodeDetector = FirebaseVision.instance.barcodeDetector();
    
    final List<Barcode> barcodes = await barcodeDetector.detectInImage(firebaseImage);
    
    _barcodeRead = "";
    for(Barcode barcode in barcodes) {
      _barcodeRead += barcode.rawValue + ", ";
    }
  }
}
Read the barcode example

For the above code to compile, you will need to add the Firebase ML Vision plugin to the pubspec.yaml (along with path_provider, to get folder locations on the system).

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  camera: 0.3.0+3
  firebase_ml_vision: 0.5.0+1
  path_provider: 0.5.0+1
MLKit added to firebase pubspec.yaml

And add the necessary includes at the top of the main.dart file

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:path_provider/path_provider.dart';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';

So… Now the app can take the photo, read all the barcodes detected in the image and store them in the member variable “_barcodeRead” string, all that is left is to display it!

Display the Barcodes

Add the Text element to the Stack inside of the “Build” method – we can wrap it in a container so that it can be anchored to the bottom of the screen.

@override
  Widget build(BuildContext context) {
    if (!controller.value.isInitialized) {
      return Container();
    }

    return Stack(
      alignment: Alignment.center,
      children: <Widget>[
        AspectRatio(
          aspectRatio:
          controller.value.aspectRatio,
          child: CameraPreview(controller)
        ),
        
        Container(
          alignment: Alignment.bottomCenter,
          child: Text(
            _barcodeRead.length > 0 ? _barcodeRead : "No Barcode",
            textAlign: TextAlign.center
          ),
        )
      ],       
    );
  }
Display barcode string

Finally,  we need to ‘redraw’ the widget whenever we update the barcode variable. To do this in Flutter, all we need to do is call “setState”.

Future _readBarcode(File file) async {
    FirebaseVisionImage firebaseImage = FirebaseVisionImage.fromFile(file);
    final BarcodeDetector barcodeDetector = FirebaseVision.instance.barcodeDetector();
    
    final List<Barcode> barcodes = await barcodeDetector.detectInImage(firebaseImage);
    
    _barcodeRead = "";
    for(Barcode barcode in barcodes) {
      _barcodeRead += barcode.rawValue + ", ";
    }
    
    setState(() {});
  }
Update the widget to display barcode

[Flutter App Dev] – Setting Up Firebase

If you are just getting into mobile development with Flutter (or mobile development in general) let me introduce you to Firebase. It is a service that offers a tonne of features such as free push notifications, analytics, Authentication etc. It even has some paid services (free tier is still quite impressive) for database hosting, file storage, and SMS service for phone authentication etc.

In this post, I will show you how to set this up for a flutter project. To keep this post short and to the point, I will assume you have already created your flutter project.

Firebase Setup

As a prerequisite, all you need to do is go to the Firebase Website and sign up for an account and log in.

Step 1 – Add a Firebase Project

Go to the Firebase Console and click “Add Project”

Step 2 – Give the Firebase Project a Name

The name you enter here is used to identify your project on Firebase. You can optionally edit the “Project ID” field, as this is used to reference your Firebase endpoint.

Accept the terms and then press “Create Project”

Step 3 – Create Application Projects in Firebase

This step is broken up into two sections: Android project setup and iOS Project Setup.

Setup a Firebase Android Project

On your Firebase Console, click the Android button to start the process of adding an Android application to your project.

Step 1 of this process is the most important, your “Android package name” must match the identifier you set on your Android project and is normally in the format of com.companyname.applicationname.

The app nickname is once again only used to identify your android project within your Firebase project.

Please refer to this post on how to find the SHA-1 fingerprint of your debug key. It is not so important for now, but when you come to release your application, you will need to add the SHA-1 fingerprint of the keystore file you use to sign and distribute your app.

Once you click “Register App” you will be taken to step 2. Simply download this file (google-services.json) and place within the Android -> app folder of your Flutter Application.

google-services.json file placed in the correct location for a Flutter app.

Step 3 is where you add the dependencies for your Android application. This step on the Firebase example is a bit miss-leading as the line for including Firebase core is not needed. This is because, when you add one of the Firebase libraries it will manage this include for you. Including this line manually will just cause compiler errors.

Therefore, setup is as follows:

Of course, use the version number for google-services as described by the Firebase project setup wizard that is on your screen.

Now refer to “Add Firebase to the Flutter Application” below or continue to “Setup a Firebase iOS Project”.

Setup a Firebase iOS Project

Click the iOS icon or the “Add App” button (if you followed the above Android steps). In my case, I have the Add App button (be sure to select the iOS option that appears.)

Fill out the details for step 1. Note that the “iOS bundle ID” must match exactly what you set in your iOS project. Your “App Store ID” requires you to have enrolled in the Apple Developer Program 
(which has a cost!) and have your app uploaded on iTunes connect.

However, this is optional for now, but remember to add it to your project’s settings before you release your application.

Next, in step 2, download the GoogleService-info.plist file and place it in the iOS project of your Flutter project. Below is an example of where I placed mine (in the ios -> Runner folder).

Placement of the GoogleService-info.plist file for a Flutter iOS App.

You can skip step 3, as including a FlutterFire library into your flutter application will already do this.

Follow instructions for step 4 as described by the Firebase steps precisely for your chosen language (Objective-C / swift).

Now refer to “Add Firebase to the Flutter Application” below.

Step 4 – Add a Firebase library to the Flutter Application

Providing you followed the steps for placement of the Google service files in the previous two sections, all you need to do for this is add any FlutterFire plugin to your Flutter project’s “pubspec.yaml” file.

FlutterFire plugin “firebase_ml_vision” included in the “dependencies” section of the pubspec.yaml file example.

Finally, deploy and run your application to the device and you should see the successful message stating your app has communicated with the Firebase servers. Note, that this message appears on the last step of each application setup of your Firebase project, within the Firebase
Console.

[Flutter App Dev] – Camera Plugin – Dark Preview Fix

As promised… This blog is moving direction to focus on Flutter Development… First up is how to fix flutter’s dark camera plugin (that can be used in any Android project utilising the Camera2 API)!

When developing my (Xamarin) app Prog I ran into a rather complex bug on Android with the Camera2 API. Upon starting the camera preview, it would appear correctly lit for a split second and promptly become dark. This rendered the camera preview useless, as seen below.

Dark Camera Preview Example with Flutter Camera Plugin

I spent a good month reading over endless Stackoverflow posts, and attempting to translate the Android documentation into Xamarins C# wrapper equivalent. Just as I was about to give up, I gave it one last attempt, and I got it!

It turned out, the camera FPS was too high for the auto exposure to keep up. This resulted in the auto exposure failing miserably and seemingly ‘giving up’. Note, that on high end devices this didn’t seem to be a huge problem. Although, I tested on a “Samsung Galaxy Tab A” which is seemingly low end – but should still be way more than capable of running Prog.

The solution turned out to be pretty simple… You can query the list of available FPS ranges that the auto exposure can handle via the CameraCharacteristics API. A range in this instance has a lower and upper bound – the lower end meaning slower FPS and the upper meaning faster FPS.

The list of ranges returned can come in two forms (x, x) where the lower and upper range is the same (i.e. constant FPS). Or a (x, y) form where x < y but there is variation on the FPS. From personal experience, the (x, y) range appears to use the lower FPS when the exposure is struggling but remain high FPS on high end device. Thus, finding the FPS range with the biggest difference between X and Y components resulted in the ‘sweet spot’ when choosing the FPS range.

Enough Background… This is For Flutter!

Or more specifically… The Flutter’s Camera Plugin. I have already created a Pull Request to fix this – but have been told they’re favouring quality over features before approving the pull request (it’s became a ‘feature’ as choosing a slower FPS in favour of better exposure may not be required by all apps, therefore an option is required to be implemented).

I’m sharing this a work around for those running into this problem and require a useable camera preview in all scenarios.

Within the Android native class of the camera plugin source code (CameraPlugin.java) create a method called “setBestAERange” as shown below. This will get all fpsRanges, check for the range with the biggest difference between lower and upper bound and assign to the member variable “aeFPSRange”.

private void setBestAERange(CameraCharacteristics characteristics) {
	      Range<Integer>[] fpsRanges =
	          characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
	
	      if (fpsRanges.length <= 0) {
	        return;
	      }
	
	      Integer idx = 0;
	      Integer biggestDiference = 0;
	
	      for (Integer i = 0; i < fpsRanges.length; i++) {
	        Integer currentDifference = fpsRanges[i].getUpper() - fpsRanges[i].getLower();
	
	        if (currentDifference > biggestDiference) {
	          idx = i;
	          biggestDiference = currentDifference;
	        }
	      }
	
	      aeFPSRange = fpsRanges[idx];
	    }

Hopefully this should indicate that you need to add a Range<Integer> type member variable to the “Camera” class. Then call this method inside the Camera constructor, just above “computeBestCaptureSize” making sure you pass in the characteristics variable.

Camera(final String cameraName, final String resolutionPreset, @NonNull final Result result) {
    ...

    setBestAERange(characteristics);
    computeBestCaptureSize(streamConfigurationMap);
    
    ...
}

The final piece of the puzzle is to set this FPS range on the capture request for the camera preview. Add the following code to the “createCaptureSession” method, just before the call to “setRepeatingRequest” on the capture request.

if (Camera.this.aeFPSRange != null) {
    captureRequestBuilder.set(                                CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,   Camera.this.aeFPSRange);
}
Fixed camera preview for flutter camera plugin

Happy usable camera preview!

New Blog Direction – Flutter Mobile Development

It has been ~10 months since my last post… In that time I have started a new job, bought a house, learned great amount of new skills at my new job (one of which is mobile development), I’ve created and released my own Xamarin app called Prog and finally… Contributed (currently an open pull request) to my first open source project ever – Flutter Camera Plugin.

It’s safe to say that this last year (2018) has been quite the roller-coaster, and has led me away from Raspberry Pi development. I believe my interest in this technology had peaked when I saw my code interacting with live machinery via the Pi in my previous employment. Since then, I have not had any project worth investing time into with regards to the Raspberry Pi. Therefore, this blog is taking a new direction – Mobile Development.

Flutter

My first entry into mobile development was using Xamarin Forms 3.0. While I did battle through and eventually release my own app, I don’t think I will be using it again. The eco system on Windows was broken. As an example: making a small change would result in a 5 minute wait for a compile and deployment to take place. If the compile didn’t fail and you didn’t have to restart Visual Studio, clean and rebuild you would just find out that the small change you made didn’t work and you had to repeat the process until it finally ‘worked’.

Flutter is a game changer I mean really… It has hot reload out of the box and works on all major platforms! It can even hot restart when you make logic changes. On my machine, a hot reload will take 800ms, and a hot restart will take 1.2s.

The layout and widget system makes perfect sense and the documentation is great. Animations – something developers usually shy away from – is so simple I can’t wait to post about it. Native Functionality integration is super easy also (until you get to the objective-C / Swift code – but that isn’t Flutter’s issue). And finally, it comes with amazing integration with Visual Studio Code.

Anyhow – I just wanted to make a post to say that there will likely never be anymore Raspberry Pi stuff here. I’m likely going to post solutions to problems I encounter and solve during my time developing mobiles apps with Flutter.

[ Raspberry Pi C ++ ] Push Buttons (Reading GPIO Input)

This post has been long overdue and will bring the GPIO tutorial to a close. We focus here on how to read input from external devices. This tutorial will keep things as basic as possible by using a simple push button.  

Previous Post: Our First LED


The push button used in this tutorial has four prongs/legs and looks as follows: 

Image of push Button
Example of a Push Button

Setup

Before we begin, there are two other components we require to complete our circuit… 1x 10kOhm resister and 1x 1kOhm resister 

The 1kOhm resister is simply used to dampen the voltage going from the 3.3V pin directly into the GPIO pin when the button is pressed.  

The 10kOhm resister plays a much more important role and is known as a “pull-down” resistor. It sits between an open (un-pressed) button and ground (GND). A pull-down resister is used to prevent erroneous reading from a GPIO pin on an open circuit. I would recommend to learn more about resistors.

A button in this un-pressed state (with a valid pull-down resister) will yield an input reading of 0 (LOW). 

Then when the button is pushed down, the voltage will flow from the 3.3V pin into the INPUT GPIO pin (whilst continuing through the 1kOhm resister) to give us a reading of 1 (HIGH).  

This is how your circuit should look: 

circuit diagram
Complete circuit diagram of push button with valid resistors

Code

The code for this example is very simple (even more so than lighting up our first LED)

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    // Intialize the wiringPi Library
    wiringPiSetup();

	const int INPUT_PIN = 12;
	
    // Read input on this pin
    pinMode(INPUT_PIN, INPUT);

    while(true)
    {
        // As soon as we dedect an input, log and quit.
        if(digitalRead(INPUT_PIN) == HIGH)
		{
			printf("Button is pressed!\n");	
			break;
		}
    }

    // Exit program
    return 0;
}
Reading GPIO Input with C++ and wiringPi

As always, see here on how to compile and run this code.

The code starts by flagging the pin to be used as an input. Later on we detect it’s reading via the digitalRead() function. This will return HIGH / LOW depending on the buttons pressed state.

The program will exit as soon as a HIGH input is received, shortly after printing that the button was pressed. The circuit between the GPIO pin and the 3.3V pin is compete when you press the button thus resulting in a HIGH read.

Earlier on in this post we talked about a pull-down resistor, and without it we may get erroneous reads through the GPIO pin.

I will leave this as a task to the reader, but I would suggest removing the pull-down resistor and tweaking the code to infinitely check the value of the input and see what happens.


Previous Post: Our First LED

[Programming Design Patterns & Practice] – Introduction

Design Patterns

Programming design patterns is something I’ve wanted to blog about for a while. They are fundamental to being a programmer. Knowing a multitude of design patterns and knowing when to apply them separates the true developers from the “code monkeys.”

For example, I have inherited a project in the past where the initial developer had no concept of architectural patterns. 10 years on and a few more developers later, the underlying codebase had become a mess of different developers doing things ‘their way’. This was more than likely due to a lack of a fundamental structure which should of been in place from the get-go.

Having experienced the work place that the developer had previously been at, deadlines were indeed tight. To make things worse, there was usually more than one project going on at a time. However, It is common place for deadlines to be tight in the Software Development industry, so getting the job done is a key part of the job to keep your employer happy.

This does not mean that all care should be dropped from the code you are writing to ‘get it done’ as getting it done and doing it right are very dissimilar. This is where knowing programming design patterns is key. They really don’t take that much more of your time initially and they will save you and future developers time in the future!

If the initial developer put a system in place for managing the database, front end and business logic (MVC springs to mind); all future developers would likely follow the framework. Thus resulting in a unified codebase with a clear indication of what is going on behind the scenes.

Model View Controller Design Pattern Overview
Model View Controller Design Pattern Overview

Programming Practice

This topic is more of a by-product of knowing your design patterns. Knowing when implementing ‘pattern X’ solves ‘problem Y’ is likely going to lead you to down the path of good programming practice.

However, there are some key principles that should resonate in your head as a programmer, off the top of my head they are:

  • Don’t Repeat Yourself (DRY) – Not duplicating code, reuse code by breaking it up into functions/objects.
  • SOLID – An OOP principle used to help define responsibility for classes. It can be seen as the most fundamental practice a programmer should know when working in an object based language.
  • KISS – Keep It Simple, Stupid – Is a funny one by all means but a very good principle. Don’t over-complicate your classes & functions. Break them down into bitesize pieces and chances are you’ll separate your logic and dependencies in the process.

In the project described earlier, it basically broke all of the above rules. Just to give an indication on how bad things were… There was a .txt file named “code to paste.txt”. Inside of it were about 4 different sections of code that had indeed been copied and pasted around the codebase in numerous locations.

Breaking up code into reusable functions is programming 101 – Don’t Repeat Yourself (DRY)!!


I have not got a set list of the patterns I am intending on blogging about, instead I am just going to write about ones I feel like writing at the time.

Suggested: Raspberry Pi Development in C++

[ Raspberry Pi C ++] Our First LED (Controlling GPIO Output)

For this demonstration we will use an LED and have it blink. This post will not present anything new programming wise, rather it will get you familiar with connecting the GPIO pins to something physical.

Previous Post: Compiling, Linking & Using WiringPi

Next Post: Reading Input With Push Buttons


Connecting the GPIO Pins

The connection is rather simple, all we require is one wire going from an I/O Pin to the negative (-) end of the LED, and another wire from the positive (+) leg of the LED to the ground (GND) pin on the Pi.

If you would like to test that your LED is working before this point, instead of connecting to the GPIO pin, connect it to the 5V pin and your LED should illuminate. 

The following image demonstrates the setup with colour co-ordinated wires.

GPIO connection of single LED and GPIO pins
GPIO Connection of a single LED for the Raspberry Pi

As shown above, the green wire is connected to the negative connection of the LED (A.K.A the Cathode). This green wire is also plugged into GPIO pin number 3. This can become quite confusing as it is known as GPIO2 in the header table but the physical pin number is 3. These references matter in whatever way your code initialises wiringPi. Luckily, by default, wiringPi uses the pin numbers.

Finally, the positive leg of the LED (A.K.A the Anode) is connected to the ground pin to ensure a complete circuit.

Writing the Code

Now that we have the connection setup, we need to write the code to make the LED blink. In the previous tutorial we already looked at writing output to the GPIO pins. We will expand on this with a little additional Linux C++ code to delay the on/off state of the pin to make it blink.

#include <stdio.h>
#include <wiringPi.h>

#include <unistd.h> // Required for Sleep();

int main(int argc, char** argv)
{
    // Intialize the wiringPi Library
    wiringPiSetup();

    // LED is connected on pin 3. Ensure
    // this pin is set to be an Output.
    pinMode(3, OUTPUT);

    // Ensure the LED is ON initialitial
    int state = HIGH;

    for(int i = 0; i < 10; i++)
    {
        // Turn on or off depending on state
        digitalWrite(3, state);

        // Toggle to HIGH/LOW output
        state = (state == HIGH) ? LOW : HIGH;

        // Wait 1 second
        sleep(1);
    }

    // Ensure we turn LED off
    digitalWrite(3, LOW);
    
    // Exit program
    return 0;
}
Blinking LED in C++

As this is a very straight forward example, each line in the code is commented accordingly.

Please refer to previous posts on how to compile the code and run it on the Raspberry Pi:

Once your circuit is complete and code compiled, run the program and watch the LED blink 10 times!

All code for these tutorials can be found here over at Github


Previous Post: Compiling, Linking & Using WiringPi

Next Post: Reading Input With Push Buttons

[ Raspberry Pi C ++] GPIO Access : Compiling, Linking & Using WiringPi

Previous Post: Using CMake

Next Post: Our First LED


To allow us access to the GPIO pins of the Raspberry Pi in C++ code, we will use a library known as “WiringPi”. What is nice about this library is that the functions we call are similar to those found in the usual Python examples. This should hopefully make it easier for those coming from Python programming on the Raspberry Pi.

As stated in my overview of C++, third party code usually comes in the form of a shared/static library which you link into your projects code. This is the case for WiringPi!

To acquire the use of a third party library, you normally get it in the form of precompiled binaries or downloading and compiling the source code yourself. What “precompiled binaries” mean, is that someone else has compiled the source code on their Pi/machine and distributed the .a/.so (static/shared library) file via a download medium. Precompiled binaries are usually the go-to way of using libraries on Windows machines. In this example however, we will be download the WiringPi source code and compile it ourselves.

Compiling WiringPi

The first thing you want to do is download the WiringPi source code. To retrieve the latest working copy of Wiring Pi, we will use git to clone the repository. If you are unsure if git is installed, you can run the following:

> sudo apt-get install git

Once git is installed, clone the repository by entering the following

> git clone git://git.drogon.net/wiringPi

After a few seconds git will have finished downloading. If you list the contents of the current directory (“ls” command) you will notice a folder named “wiringPi”. Simply change into this directory.

> cd wiringPi

If you list the contents of this directory, there will be a lot of files. The one that we are most interested in is the “build” script. Upon running this script, the compilation of the library will begin and its binaries and header files will be automatically installed into the appropriate /usr/local folders on our system.

> ./build

You should see the words “all done.” at the end of the build process once the binaries are compiled and installed.

Linking WiringPi

When linking a third party library into your C++ project, you usually have to tell the compiler where to find the libraries header and binary files. Thankfully, the build script executed in the compilation process installed these files into our /usr/local/include and /usr/local/lib folders. What is special about these folders is that they are on the system PATH variable, this means that compilers will look for files here by default!

Although we don’t have to tell the compiler where to look, we still have to tell it what to link. Luckily, this is only a one liner with CMake! I have commented each command and highlighted the line which links the wiringPi library. Here is the contents of the complete CMake file (notice I have changed the executable and project name)

# Minimum CMake version required to generate
# our build system
cmake_minimum_required(VERSION 3.0)

# Name of our Project
project(MyProject)

# add_executable creates an executable with
# The given name.
add_executable(MyEXE main.cpp)

# Make sure the executable links to the wiringPi lib
target_link_libraries(MyEXE wiringPi)
CMakeLists.txt

And finally, the code to run to see if the build system will link, compile and run our code:

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    wiringPiSetup();

    printf("wiringPi is working!\n");

    return 0;
}
main.cpp

In the above code, we simply include the wiringPi’s declared functions using the include statement and we are calling the wiringPiSetup function.

To generate the make files, make sure you have a subdirectory called build and make it the working direcotry

> mkdir Build && cd Build

Genreate the makefiles using CMake

> cmake ..

Compile the code

> make

If all goes well, you should be able to execute the program via its executable name and see the line “wiringPi is working!” appear in your terminal.

> ./MyEXE

If you see this, then you are ready to get started with programming in C++ for the Raspberry Pi!

Using WiringPi

Now that we have our program successfully linking and compiling WiringPi, we can now look at preparing the GPIO pins for use in our projects.

If you have come across some of the Python GPIO examples for the Raspberry Pi, the usual procedure is to:

  1. Initialise the GPIO Library
  2. Setup the I/O mode on each GPIO pin you intend to use
  3. Set/Read the pins state dependant on the mode you initiated it as (i.e. input / output)

Luckily, WiringPi is no different! And we’ve already seen from the code above how we initialise the GPIO library.

Just as an example of the functions we will be using in future posts, here is some code (commented on each line) which will set the output & read input from the GPIO pins.

#include <stdio.h>
#include <wiringPi.h>

int main(int argc, char** argv)
{
    // Intialize the wiringPi Library
    wiringPiSetup();

    // Set the I/O state of the given pins
    pinMode(0, OUTPUT);
    pinMode(1, INPUT);

    // Turn pin 0 on then off
    digitalWrite(0, HIGH);
    digitalWrite(0, LOW);

    // Read input from pin 1
    int status = digitalRead(1);
    printf("Pin Input = %d\n", status);

    // Exit program
    return 0;
}
main.cpp

If you copy the above into your main.cpp file from earlier, and recompile the program you should see the line “pin input = 0” when executing. The status will be 0 until there is an input going into the pin… which we will look at when I get to push buttons 🙂

As a quick overall reminder, the full steps to generate your makefiles and compile your code is as follows (don’t execute the contents in brackets):

> cd Build (If not already in Build directory)
> cmake .. (If you have not yet generated makefile / added new files) 
> make     
> ./MyEXE

In the next post I will cover how to setup and make an LED flash using C++. If you want to give this a shot in the meantime though… Use the appropriate GPIO header table for your Pi and setup a GPIO pin in output mode to light up an LED.


Previous Post: Using CMake

Next Post: Our First LED

[ Raspberry Pi C ++] Using CMake

Previous Post: Setting Up The Compiler

Next Post: Compiling and Linking WiringPi for GPIO Access


In a previous post I talked about setting up a compiler on the Raspberry Pi and using g++ on the command line. This is all well and good as a small example with one file, but when you (rightly so) have your code broken up into many files, compiling them via the command line is no longer viable.

To get around this problem, programmers using GCC would create files known as “makefiles”.

Makefiles

Makefiles are GCCs way of passing to the compiler what source files need to be compiled and what they should be compiled into. A downside to using makefiles is that the syntax for them can get extremely cryptic and hard to read/understand when your code base grows.

When you start creating makefiles, you are creating what is known as a “build system” for your project. The more code files you have to manage, the more fundamental your build system becomes.

Different platforms/compilers have different ways of managing build systems for C++ projects. For example, the GCC default is with makefiles whereas Windows uses its own Visual Studio project solution files to manage build types. Technically, there are Windows ports of GCC compilers included in software such as MinGW or Cygwin but this isn’t the norm with regards to Windows programming.

This means that if you want to compile your code on multiple platforms you will have to create and maintain multiple build systems for your project.

For these reasons, programmers tend to look elsewhere for managing their build systems. One such tool is CMake

CMake

Note: I just want to make it clear here that CMake does not compile your code! CMake is one level higher than a native build system; infact, it abstracts the underlying build system completely with it’s own syntax and using what it calls “Generators“.

For example, you create your CMake files (described later) as you would your makefiles / Visual Studio files, but you will use a CMake generator to generate your build system files which can range from Makefiles to Visual Studio and Xcode projects. You will then use this generated build system to compile your code. Here is a list of CMake generators readily available.

It’s best to show the process with an example.

CMake Example on Raspberry Pi C ++

Installing CMake

Installing CMake on your Raspberry Pi is made easy by using the apt package manager.

First thing you want to do is SSH into your Pi and at the terminal/command line enter the following

> sudo apt-get install cmake

After a few seconds you should be able to enter the “cmake” command in the terminal and you will see a list of generators available.

Using CMake

For CMake to work, there should be a file named “CMakeLists.txt” in the root directory of your C++ project. In this example, I will have one CMakeLists.txt file and one Hello.cpp file from the previous tutorial.

Your folder structure should look like so:

- Root Folder/
| - CMakeLists.txt
| - Hello.cpp

To create the files enter the following command

> touch <filename.ext>

The contents for each file is as follows (notice each CMake command has a comment describing what it is doing)

#include <stdio.h>

int main(int argc, char** argv)
{
        printf("Hello, World!\n");
        return 0;
}
Hello.cpp

# Minimum CMake version required to generate
# our build system
cmake_minimum_required(VERSION 3.0)

# Name of our Project
project(hello)

# add_executable creates an executable with
# The given name. In our case it is "Hello"
# Source files are given as parameters. In our
# Case we only have one source file Hello.cpp
add_executable(Hello Hello.cpp)
CMakeLists.txt

Generating Our Makefiles

Now that we have our CMake file setup with our single source file Hello.cpp, we next need to generate the build system files. CMake will generate quite a lot of files and folders, so it is best not to run the CMake command in the project root directory. Instead we will create a sub folder called “Build” and run the generation in here.

> mkdir Build && cd Build

This will make the directory called “Build” and also change into the directory. This is how your folder structure should look now:

- Root Folder/ 
| - CMakeLists.txt 
| - Hello.cpp
| - Build/

To run the CMake Generator we need to use the “cmake” command and tell it where the root CMakeLists.txt file is. As we are in a sub directory we will use the parent directory alias “..”. If no generator is specified it will default to the platforms native build system (in the Pi’s case, this will be GCC makefiles)

> cmake ..

Once complete you can list the contents of the directory (using the “ls” command) and notice there is now a “MakeFile” present!

Compiling the Code

This bit is easy now that CMake has generated our MakeFile for us!

Simply enter the following into the terminal (make sure you are still in the Build directory)

> make

Provided you copied the code as is above, you should see the line “Built target Hello”. To execute the application enter the following:

./Hello

You should see the line “Hello, World!”


Previous Post: Setting Up The Compiler

Next Post: Compiling and Linking WiringPi for GPIO Access

[ Raspberry Pi C ++] Setting Up A Compiler (g++)

Previous Post: A Brief Overview of C++

Next Post: Using CMake


In the previous post I talked about how C++ code gets compiled from its source files into an application exe or library. This post will demonstrate setting up a C++ compiler on the Raspberry Pi. More specifically, using g++ which is the C++ compiler in the GNU Compiler Collection (GCC).

Installing G++

The first thing you want to do is log into your Pi via SSH from your main computer. We will install GCC via the apt-get package manager. Open up the terminal and enter the following:

> sudo apt-get install g++

After a few seconds the process will finish, typing “g++” into the terminal should yield the following:

g++: fatal error: no input files
compilation terminated

Testing the Compiler

Now that we have the compiler installed, let’s create a simple C++ program. Using your terminal, create a file called “hello.cpp” with the following command:

> touch hello.cpp

The touch command will create the file if it doesn’t exist, it will also leave the file untouched if it did exist in the first place.

With our file created, let’s enter some simple C++ code. I won’t go over the code here, as it’s only to test the compiler.

Open up the file in your favourite editor (I suggest setting up Visual Studio Code for use with your Pi) and enter the following few lines of code:

#include <stdio.h>

int main(int argc, char** argv)
{
        printf("Hello, World!\n");
        return 0;
}
C++ Hello World Example

After saving the file, we must run it through the compiler. You will see in the next tutorial, we will abstract this process using CMAKE, but for the purpose of this tutorial we will pass the file straight to g++ via the terminal/command line.

The g++ CLI requires two parts, the input file(s) to be compiled and the output file these source files will be compiled into. In our case, we have one file to go in and one file to come out (an application executable). The command to do this is:

> g++ hello.cpp -o hello

After a few seconds you should notice another file called “hello” appear in the same directory (those of you using the terminal, you can list all files in the current directory by entering the “ls” command).

This file is the application executable that was compiled from the hello.cpp source file! You can execute it by entering the following:

> ./hello

If you see the words “Hello, World!” appear in your terminal, you can safely say that g++ is set up and ready to go!


Previous Post: A Brief Overview of C++

Next Post: Using CMake