Proposal for a new Software Architecture based on cooperating modules


I've written a proposal for a new software architecture based on some of the recent discussion.

It addresses

  • Arduino vs Javascript code balancing
  • Decoupled release versioning
  • Expandability
  • Compatibility with different build formats

I'd love to hear thoughts and discussion, especially since tomorrow's build day is going to cover software design and structure.


Awesome proposal! I like how your proposed architecture would enable the Arduino and/or the JS code to provide the base services; allowing for flexible allotment of responsibility between the BB and Arduino. See you tomorrow at the build day! I'm eager to hear what others think, and how this architecture could possibly be implemented.



I want to shake your hand and give you a pat on the back for writing this- organizing these thoughts and getting a proposal for how to do things on paper is exactly what we need. THANK YOU!

Here are some of my thoughts to start the discussion:

1. To clarify, I don't think the Arduino should necessarily be responsible for more things (in fact, I think it's code should be quite basic), but I think people should be able to add code for what they want on the Arduino side without necessarily having to modify the BeagleBone code. In general, I think the BeagleBone should be used for high-level and permanent tasks (e.g. data manipulation, web connection, camera connection and configuration, etc), and the Arduino should be used for hardware interfaces (such as listening to sensors and commanding actuators like motors and servos). But people should also be able to add control functionality to the Aruduino (such as a control loop that listens to sensors to control motors) that does not incorporate BB code.

2. I think your proposal satisfies this capability.

3. I think that some types of tasking are not mutually exclusive. To use our recent throttle limit discussion as an example, I think we could have Cockpit controls that change the throttle limits using BB code (that is, the commands ranging from 0 to 255 coming out of the BB's UART connection going to the Arduino could be limited to something like 20-235 when I slider is moved in Cockpit), but if someone wanted to do the same thing in Arduino, they could program it so that inputs coming from the UART command get trimmed by 20 on each side.

4. I tend to disagree with the idea of using levels of abstraction for Arduino code (such as Firmata, or special libraries) because those things make hacking using already available Arduino code (which I think a lot of people will want to do) a lot harder.

Here are some examples of code I could see someone wanting to adapt to work with their OpenROV:

Ideally, I think the default Arduino code would be a single file with very basic and easy to understand programming. People would be able to easily write their own code directly into this file and pass data to and from the UART connection in a very intuitive or standard way.

Although I think it is unlikely we'd be able implement this, what I really fantasize about, would be something that looks like the Arduino IDE that could be brought up through Cockpit (no sw would be on the topside computer) and you could program/ bring up serial termainals/ etc the same as if you had an Arduino plugged in directly to your computer with a USB cable.

The challenging bit with all of this is that people will want to interact with the programming they've written, and that requires talking through the interface that is hosted from the BeagleBone. I don't know the right way to do that, but I like some of the ideas that have been brought up so far (such as a print function in the Arduino code which specifies that data should be displayed in cockpit and specify how it should be displayed).

These are the times I really wish I had studied programming more earlier on, because I know there are principles to designing the right architecture I just don't understand. I'm really glad there are so many of us chiming in on how we can put this together the right way!



I'm envisioning a workflow like this:

  1. User goes to (or something)
  2. User picks packages they want the install
  3. The system checks dependencies to make sure they can work together
  4. User gets code back. This feature can start simple and get more awesome
    1. User gets a zipped directory with one file that has all the Arduino code from the packages assembled together, and sub-dirs with the JS and assets by package
    2. User gets a NES-style hash to retrieve a particular config later
    3. User can sign-in and save/share multiple configurations
    4. User can save forks or customizations of packages via an online editor
    5. User clicks a button and their browser initiates a connection with and retrieves new configuration, flashes the Arduino, saves the other files, and restarts the server (this will be the bomb)
  5. The user also receives a list of hardware and configuration instructions

To Eric's specific points:

#3 - this structure has no opinions about what goes where or how much Arduino vs JS. It's just a way for components to work together. In fact, there's no reason it couldn't be expanded to include external stuff like web resources, OpenCV, Python scripts for mathy-stuff, etc.

#4 - I don't think this approach is compatible with Firmata since it's pulling together a bunch of disparate Arduino code. It does lend itself to the one-file style you describe.

I'm not sure how logging/inspecting the Arduino would work but that's mostly because I don't know the capabilities and limits of that system.



To address point 4. Custom Arduino code vs using Firmata.

Ask the question: Where is the best place to put customization for a non-programmer?

In the system as it is currently defined there are 3 compute engines available: The Arduino, the Beaglebone, and the host computer.

Current peripherals attached to the Arduino?

  • 4 servo controls
  • LEDs
  • Lasers
  • Voltage Sensors.

Consider this user story: The user has the ability to customize the hardware and software.

With this use case: The user adds a depth sensor to the system and want the ability to program the depth as well as display the depth on the host. This uses 2 analog pins on the Arduino.

In order to realize this custom change what must the user do?

  1. Modify the hardware to accommodate the new sensor. This may mean if we are out of pins, changing to a larger Arduino, or adding a second Arduino. Let’s assume for this example that it is as simple as adding the hardware to two existing pins. (may not be a true assumption)
  2. Modify the software so that the user can access this new sensor.

(You could make a case for programming the depth into the arduino with a command and then the Arduino will stay at that depth making automatic depth corrections with the vertical thrusters. I do not recommend this because, we have unnecessarily over complicated the system)

Procedure for using existing custom Arduino code:

  • Change Node.js server to be able to read the sensor data from the Arduino.
  • Change the Arduino code to match the read commands from the Node server.
  • Recompile the Arduino, download and test.

Procedure for using Firmata:

  • Change Node.js server to be able to read the sensor data from the Arduino.
  • Allocate pins in Firmata js layer to the new function.
  • Test. (No compile, no download)

The beauty of using Firmata is in the abstraction. For items that use digital in/out, analog in/out, servo out, and I2C, it is simple to access all the pins in any mode that they support. Once Firmata is in the Arduino, there is no need to compile and download. It is fully extendable, and changable, without modification.

Firmata is already tuned for sending and receiving data and has many interface layers including java script which can be found here: and here:

If you add code to the Arduino for automatic course and depth, it is a simple round-robin control loop. The more complexity that is in there, the more the system is dependent on its component parts or other non-related parts. Follow the KISS (Keep it Simple) method and have the Beaglebone do the course and speed by sending commands to the Arduino to adjust the servo’s, and read the IMU.

Abstraction is the ability to quickly realize a functional system, without knowing all the detailed parts.

If you want to see non-programmers use an arduino in this fashion, you can look at this site: down in the selected projects. This is for music controllers which have realtime needs. (you will hear any latency from button push or knob twist to sound variation)

Clear abstraction of the underlying hardware allows for the ease of programming and interfacing at a higher layer.