OpenROV Firmware (Arduino) Development Guide

howto-guide
software

#1

This guide intends to serve as a starting point for people wanting to modify or extend the controller board firmware running on the ATmega2560 (OpenROV v2.5-v2.8). We are currently retooling and rethinking a lot of our development environment, so some of this may change in the next couple months, but this should give you a good understanding of how to work in the existing 2.x series environment. This guide can also be considered a living document and will evolve over time as things change and we add more information. Feel free to comment with suggestions, workflow variations, etc. and I will add them to the primary post.

Note: This guide assumes you are using the latest 30.0.3 Beaglebone Black image. If not, first follow the guide for updating your Beaglebone to the latest image before proceeding with this guide.

###Table of Contents


Hardware Requirements and Setup

If you already have a working ROV put together, your hardware setup is complete; you can just connect to the ROV normally over the tenda adapter as if you were going to pilot it.

This section will describe what developers need to do if they want to put together the minimal, barebones development setup.

What you’ll need:

Optional Goodies:
  • Prototyping breadboard
  • Wire headers and other useful breadboard components
Documentation

The Steps

####1. Bridging the J12 Jumper

This step is necessary to make sure the ROV turns on when you provide power from the battery/12V power supply. Normally, the controller board is turned on by a 5V signal on the tether, but we’re assuming you don’t have one. Find the J12 jumper pins and solder a small piece of wire to bridge them together. The pins can be found here:

####2. Attach the Beaglebone Black

Attach the Beaglebone Black’s P9 header row on the controller board’s header pins so that the ethernet port faces away from the ESCs/DB-25 Connector, as shown in the picture below.

Note: Failure to install the Beaglebone correctly (like if you have it reversed) can cause irreparable damage to the Beaglebone!

3. Connect the DB-25 header cable to the Controller Board

The pinout for the DB-25 header cable is shown in the image below:

While optional, I found it highly convenient for development purposes to break the header cable out to a prototyping breadboard so that I could easily access pins and test devices. Here is a picture of my breadboard setup:

Take note of how I broke out the 12V (PORT BATTERY +), 5V (TETHER_A), and 3.3V (3V3) power buses so that I had easy access on the breadboard.

4. Powering the board

You have a few different options for powering your board. For my dev rig, I use a 12V/2A wall power supply. I wire the 12V output to the prototyping board and wire it up to the DB25 cables as shown in the following picture:

Note, if you intend on attaching motors or other peripherals to your rig, then a wall power supply should not be used, as it will likely be unable to supply sufficient current to power everything. In this case, your best bet would be to use an actual OpenROV battery tube or other LiPo battery (a 3S LiPo battery works well).

I set my prototyping board up so that I can cycle power by just disconnecting and connecting the ground wire on the 12V bus header that I stuck in. You can get as fancy as you want with this.

Once you connect the power, the controller board should turn on, as well as the Beaglebone Black.

5. Connect the Ethernet Cable

Once the board is powered, the only thing left to do is to connect it to your development computer with an ethernet cable. You should automatically be assigned an IP address . If not, manually set up your computer’s IPV4 configuration as follows:

Address: 192.168.254.10
Netmask: 255.255.255.0


Options for Accessing the Beaglebone Black

There are a few different options for accessing the Beaglebone Black to work on the firmware. The first (and easiest) is to use the Cloud9 IDE that is installed on the Beaglebone. The other methods involve working at the command line through a terminal emulator.

Cloud9

The Cloud9 IDE can be accessed by opening your browser on your host machine and connecting to the OpenROV Dashboard by entering either “openrov.local” or “http://192.168.254.1” as your URL. Once on the dashboard, you should see an option to launch the Cloud9 IDE. Click “Cloud9” to open it in another browser tab.

Instructions for the development workflow over Cloud9 will be described in a later section.

Command line

For more advanced users who might need to access the entire Beaglebone filesystem, you have three options. You can either use the terminal window in Cloud9 (which is conveniently logged in as root!), use the web-based terminal at http://192.168.254.1:3009/, or directly SSH into the Beaglebone from your computer’s terminal. If you’re on a Linux of Mac machine, you should already have an ssh program installed. If on Windows, the easiest way to get a half-decent terminal with ssh is to just install the Git Bash client: https://git-scm.com/download/win

The command to connect over ssh is:

ssh rov@192.168.254.1
Password = OpenROV

Instructions for the development workflow over SSH will be described in a later section.


General Filesystem Structure Overview

The majority of files that will be of interest to the OpenROV firmware developer reside in the following locations:

Firmware Sketch/Source Directory:

 /opt/openrov/arduino/OpenROV/

Beaglebone Related Shell Scripts:

 /opt/openrov/cockpit/linux/

Arduino Related Shell Scripts:

 /opt/openrov/cockpit/linux/arduino/

Arduino Library Directory:

 /usr/share/arduino/libraries/

Firmware Files

All of the source files for the controller board firmware are located in the “/opt/openrov/arduino/OpenROV/” folder. The primary sketch file is named “OpenROV.ino”.

When modifying or extending the firmware, you will mainly be working in this directory.

Shell Scripts

There are two shell scripts that are commonly used in the firmware development process:

Build and upload firmware:

/opt/openrov/cockpit/linux/arduino/firmware-installfromsource.sh

Reset the ATmega2560 (if you need to for some reason):

/opt/openrov/cockpit/linux/reset.sh

Adding Arduino Libraries

Additional arduino libraries can be made available to the firmware build process by uploading them to the Arduino library folder:

/usr/share/arduino/libraries/

Development in Cloud9

Using Cloud9 is the easiest way to directly modify and experiment with the OpenROV software. The following sections describe a general workflow for working with the controller board firmware.

Creating a Build Configuration for Firmware

First, we’ll add a build configuration to Cloud9 so we can easily build/upload the code with a single keystroke. Here are the steps:

  1. In the Cloud9 menu, click Run->Build system->New Build System
  • Delete the contents in the new .build file that was created and replace them with:

    // Build configuration for building and flashing the OpenROV atmega2560 firmware
    {
        "cmd" : ["/opt/openrov/cockpit/linux/arduino/firmware-installfromsource.sh", "", ""],
        "env" : {},
        "info" : "Building Firmware...",
        "selector": "source.ext"
    }
    
  • Hit CTRL+S to save, and save as Firmware.build in the default location (.c9/builders/)

  • Change your selected build configuration: click run->build systems->Firmware

You can now make changes to any of the firmware source files (/openrov/arduino/OpenROV/*) and rebuild/upload them by pressing CTRL+B or going to Run->Build.

Uploading files from your computer

Sometimes it is easier to work on the firmware source from your main computer, using an IDE like Visual Studio, Atmel Studio, or the Arduino IDE. One workflow is to clone the OpenROV firmware to your development computer from github, work on it in your preferred IDE, and then upload it back to the Beaglebone. To upload your source back to the Beaglebone after working on it, in Cloud9:

  1. In the workspace explorer on the left, navigate to openrov/arduino/OpenROV/.
  • Click the OpenROV folder so it is highlighted
  • In the Cloud9 menu, click File->Upload Local Files
  • Either drag and drop in the modified source files you’d like, or use the file browser tool by clicking “Select files to upload”
  • Your files will be uploaded (see progress in the bottom left corner) and you can now rebuild the firmware with your modifications

Alternatively, you can just click the /openrov/arduino/ folder and upload your entire /OpenROV/ folder to more easily replace the entire source tree with the one from your computer.

Downloading source files from the Beaglebone to your PC:

  1. Right click the /openrov/arduino folder in the Cloud9 workspace
  • Click “Download”

The folder will be compressed to a .tar.gz archive and downloaded to your computer. This can be done with any folder or file in the Cloud9 workspace.

Using the Built-in Terminal Window

To access the built-in terminal window, you can go to “Window->New Terminal” or hit Alt+T. The terminal logs in as root by default.


Command Line Development

If you want to develop from the command line, you have a number of options:

  • Using the Cloud9 built-in terminal
  • Using the web-based terminal at: http://192.168.254.1:3009/
  • SSHing into the Beaglebone with your favourite ssh application

Once you’ve logged in in this manner, the general workflow is:

  • Modify the firmware source with whatever editor you prefer (vim, emacs, nano, etc)
  • Build and upload the firmware by running:
sudo /opt/openrov/cockpit/linux/arduino/firmware-installfromsource.sh

Getting to the Internet from the Beaglebone

If you need to install an application, library, or other package on the Beaglebone, you will need the Beaglebone to have an internet connection. Fortunately, we built a clever proxy into the Cockpit software that extends your development computer’s internet connection to the Beaglebone through the browser. All you need to do is open the Dashboard (http://192.168.254.1) in your PC’s browser, and the Beaglebone will automagically be connected to the internet. If you close the Dashboard, this connection will be lost.

Uploading and Downloading Files Over SSH

You can upload and download files to the Beaglebone via command line by using the “scp” program from your host machine. scp transfers files over ssh. It is usually easier to upload or download files through the cloud9 interface, for most users.

A typical scp upload of the source files might look like:

scp -r ./openrov-software-arduino/* rov@192.168.254.1:/opt/openrov/arduino/

A download might look like:

scp -r rov@192.168.254.1:/opt/openrov/arduino/ ~/workspace/openrov-software-arduino/

General Overview of the Code

The following is a brief overview of how the firmware is currently structured to help you get started.

####Getting the software:

Repository Location: https://github.com/OpenROV/openrov-software-arduino
Note: Be sure to checkout the 30.0.3 tag after cloning.

git clone https://github.com/OpenROV/openrov-software-arduino 
cd openrov-software-arduino
git checkout 30.0.3

Overview

The OpenROV controller board firmware is written in C++ using the Arduino core libraries. The entry point for the code resides in OpenROV.ino. Similar to any other Arduino sketch, you have a setup() function that is called once at the beginning of the program and a loop() function which is called continuously. The code is structured into five “manager” namespaces which are essentially singleton classes (without actually being classes) that group related sets of data and functions and make them available globally within the program.

  • NArduinoManager - Responsible for setting up Arduino specific things like peripherals and interrupts
  • NConfigManager - Interface to vehicle/board settings shared by multiple subsystems within the code
  • NDataManager - Interface to vehicle telemetry data. Has update loops that send data regularly to the Beaglebone Black.
  • NCommManager - Not much to it right now, just stores and updates a global CCommand object with commands coming from the Beaglebone over UART.
  • NModuleManager - Allows registration of objects derived from the CModule class and handles initialization and updating of those modules.

CModule describes a class that basically requires that any class derived from it have an Initialize() and Update( CCommand& ) function. It also has a constructor that automatically registers any CModule derived class with the Module manager. In this manner, all you have to do to create a plugin that is part of the Initialize/Update flow in the program is to create a class that inherits from CModule and implement those two functions. In order to allow for conditional compilation and keep code size down, the headers for these derived classes consist of only a very simple class definition specifying that they inherit from CModule and implement the Initialize() and Update() functions. The actual functionality of each module is implemented in a private namespace in the module’s .cpp file. This is where you define any data and functions that belong to the module.

Instances of modules are created in ModuleDefinitions.h. If you look at that file, you can see that we are conditionally including and instancing modules based on the #define settings in AConfig.h. In this manner, if you don’t use a module, it doesn’t get included in the compilation process and code size is kept down. Some of the core modules are:

  • CControllerBoard - Provides interface to the controller board (monitoring voltages, currents, etc)
  • CThrusters - Maps and mixes control inputs into PWM signals for each motor
  • CBNO055 - Interface to the 9DOF IMU sensor
  • CAutopilot_X - Provides basic depth and heading hold functionality, at the moment. Communicates commands to CThruster module
  • CLights - Control interface for lights
  • CCalibrationLaser - Control interface for lasers

There are also some other classes, utilities, and libraries included that are used by the various modules, such as CPIDController, CTimer, CPin, Utility.h/cpp, LibBNO055_X, etc.

That covers most of the code structure at a pretty high level. We are still in the process of refactoring a lot of the code to make it more generic, clean, modular, flexible, platform agnostic, and efficient. As these changes occur, this guide will be updated with better supporting documentation.


Accessing cloud 9 bbb code directly
Building arduino firmware fail!
Using openrov system for other kind of ROVer/drone
Connect OpenROV to Sensor Payload via External UART
#2

Amazing work, Charles! Thanks a lot. I will need this soon :slightly_smiling:


#3

Note, as of OpenROV Image 31.0.0, the build scripts referenced in this post have changed.

In source code, you can find them here:

On the Image, you will now find the script the builds the firmware here:
/opt/openrov/system/scripts/BuildFirmware.js
And the script the flashes the firmware to the MCU here:
/opt/openrov/system/scripts/FlashFirmware.js

Note that these are node scripts so you execute them with node /opt/openrov/system/scripts/BuildFirmware.js


#5

Hi!

First of all thanks for your post. :slight_smile:

I´m new in OpenROV and I have a lot of doubts:

  • I want to go into the OpenROV code to understand it, and configure it as I want. I have tried to do it using Cloud9 but when I try to open a .h file or a .cpp one, nothing happens. Why?

  • I have tried to use my terminal (Mac) for downloading the code to work with it but when I type " scp -r rov@192.168.254.1:/opt/openrov/arduino/ ~/workspace/openrov-software-arduino/ " appears an error:

“/Users/GonzaloM/workspace/openrov-software-arduino/: No such file or directory”

What can I do?

  • Additionally, my OpenROV´s lights doesn´t stop blinking. Why?

Thanks in advance