I started a small hobby project to develop a simple web-controllable digital I/O card for controlling and monitoring various kinds of peripheral devices. As a hardware platform I selected Arduino Uno micro-controller board with W5100 Ethernet Shield for network access. Arduino was selected as hardware platform due its simplicity and low price point (Arduino Uno compatible board + Ethernet shield cost under $15 with home delivery). To follow-up agile and TDD development practices I decided to setup a continuous integration environment for automated building and testing of the control software in the embedded hardware.
In general setting up of the continuous integration for embedded system projects is quite similar as for any other project, but you need to take into consideration some additional issues such:
Uploading and flashing the software binary into the embedded hardware.
Wiring and triggering (or simulating) of physical interfaces of embedded hardware.
Gathering of logs and debug traces from the embedded system.
This example shows how to setup Arduino-based project to build and run on Jenkins continuous integration server. In this example the Jenkins CI is running in Ubuntu server and tests are implemented in Java (JUnit + Selenium) with Maven project configuration.
The example Arduino project is simple web-controllable digital I/O board with 4 inputs and 4 outputs. The state of I/O ports can be monitored and controlled via simple web-UI shown below.
Arduino Web-UI for controlling I/O ports.
For the build and test environment the Arduino is connected to build server via USB and LAN connections. The USB connection is used to upload new software binaries for testing. The LAN connection is used to to test the web-UI of the software. In the setup the Arduino input pins 1-4 are connected to the corresponding output pins 1-4, enabling testing of both (1) reading input values and (2) writing output values. The system produces system log for test purposes via serial communication over USB. The test setup is illustrated in Figure below.
Build and test environment configuration.
First we need to setup the test and development environments. The tools used in this example are:
Arduino IDE, development environment for Arduino development.
Ino, command line tools for Arduino to integrate it with Jenkins CI *
Picocom, terminal emulation for serial communication (used by Ino).
Jenkins CI, continuous integration environment.
*) Since Arduino version 1.5.0 there is also native command-line support in Arduino, which can be also used for Jenkins CI integration. More information about Arduino CLI options can be found here.
After installation of the toolkit, we create the Arduino project using Ino tools
The ino init command creates project structure with src and lib folders and a src/sketch.ino file as a base sketch to implement the application code.
Create maven test project
Next we create a simple Maven project for tests. First we add maven pom.xml to configure the JUnit tests using maven-surefire-plugin.
In the pom.xml we define dependencies for selenium-java for web application testing with Selenium. In addition, we define dependency for phantomjsdriver to use the PhantomJS and GhostDriver to execute our Selenium tests in headless PhantomJS browser.
Next we add the JUnit test (WebIOTest.java in folder src/main/test/fi/jperala/webio) to test changing the output pin state and verifying that the both input and output pin states were changed correctly. The test is parameterized and it takes as input the pin index under test.
In the end, we have a project folder with ino and maven project that is now ready to be committed in to version control system of your choice and to be configured for Jenkins continuous integration. The resulted project folder structure is following:
In this example the BitBucket was used as Git version control repository. You may want to add a .gitignore (or svn:ignore in case of Subversion) file to avoid any build artifacts (e.g., target and lib/.holder folders) to be committed in the repository.
Setup Jenkins project
Create new project
First, we create a new free-style Jenkins project:
Next, we configure the created project:
Project name and description. Name and description of the project.
Handling of old builds. We keep max. 10 builds from last 7 days.
Source Code Management. We configure Jenkins to get the code from BitBucket.
Build. We configure the Jenkins to carry out the build and test steps:
Ino Build. Build the Arduino project.
Ino Upload. Upload the build binary to Arduino hardware.
Maven clean test. Execute maven tests against the embedded system.
Post-build. We configure the Jenkins to publish the JUnit test results.
Finally, we are ready execute the Jenkins project. Once launched, the Jenkins fetches the project from version control, builds and uploads the binary to embedded system, and executes the JUnit/Selenium tests. The build process can be monitored from the Jenkins Console Outptut.