OpenROV w/Raspberry Pi - not working


Hi, I have a scratch-built OpenROV that I started a couple of years ago - it’s based on OpenROV 2.4. I made the decision to use the Raspberry Pi instead of BeagleBone because back then there wasn’t a low-cost BeagleBone available. I combined the Pi with an Arduino Uno connected to the ESC’s. I managed to make the software work on the Raspberry Pi Model B, and it’s been working great, but recently I had to redo the endcap system so I took the opportunity to replace my old Model B with a brand new Raspberry Pi 2 Model B+.

The problem arises with getting the new software to work. I’m having to start from scratch due to the new CPU on the Pi 2, but for some reason I’m not able to get it to work. Here’s what I have done so far (this is, as far as I can remember, exactly the same process I followed when I did this on the Model B two years ago):

  • Loaded Ubuntu MATE on SD card
  • Log in to Pi using ssh
  • Installed mjpg_streamer and dependencies - latest version as far as I can tell
  • Installed nodejs - latest version
  • Cloned openrov-software into /opt from github - also latest version
  • Tried to run “sudo nodejs cockpit” from /opt/openrov/cockpit/src. Needs various modules to make it work (serialport,, bower, eventemitter2, etc…).
  • Installed missing node modules using npm, now “sudo nodejs cockpit” runs.

So it runs fine, no error messages, but when I log in to the pi in my browser, all I get is a black screen. What gives? While the browser is loading, the ssh terminal gives me a whole bunch of “GET … blah blah.html” messages, which makes it look like it’s working, but still no activity on the browser. I can also log in to port 8090 and see the camera output, which looks great.

I am thinking it may have something to do with the fact that my Arduino software is horribly outdated, but when I try to verify the OpenROV Arduino software in the Arduino IDE, a whole bunch of errors pop up. All I want is the bare-bones Arduino sketch for motor control only, and I can’t figure out how to do that.

It did give me an error at first - “waiting for Arduino capability response before sending command” or something, so I bypassed that in the code. No doubt something the new Arduino software has - it didn’t change the black screen, though.

I would appreciate any help from anybody who knows more about this than I do. Also, it would be really great if some support was offered on github for Raspberry Pi - perhaps an official OpenROV on Raspberry Pi image?



Using OpenRov software with the raspberry Pi
Alternative control board options for first ROV?

Collin, I do not have an answer to your question, but what camera do you use? I use the raspi cam for the video but compression is a bit poor. I am watching your post, since I am interested to make this work for model2 too. At the moment I control the raspi with a joystick, control with pygame. Could be a temporary work around ;). Good luck.


Neils: Thanks for replying to my post!
My camera is just a cheap old HP webcam. It was working fine before the hardware upgrade. I do have another brand new webcam I could experiment with though.
As far as controlling with pygame goes, it sounds intriguing- perhaps you could send your software layout so I could experiment?

I have also been partially successful in getting the older version of the software to run on Pi2 but mjpg-streamer refuses to run inside node.js; I get “Init.VideoIn failed” or something.


That is good news. All the browser does is load that same video stream. So whatever the issue is, it is the code in the browser doing something funky. Which is also completely independent of the Raspberry or BeagleBone.

Which version of the software are you using? And are you using Chrome as our browser?


Hi, thanks for replying!

I am using version 2.5.0 of the software - I think. How would I tell for sure, just poking around in the RPi terminal?

I was looking at the OpenROV site and I noticed there is a version 30.0.0 of the software - for older versions?? Would this run directly on the RPi? I tried getting the 2.5.0 image to run directly and it wouldn’t.

As far as the browser goes, I am currently using Waterfox (Firefox compiled for 64-bit). I tried straight Firefox and it didn’t work. I also tried Chrome on an iPad and that didn’t work either, but it’s an old version. I am downloading Chrome now, just to see if it works.

Here is the output of the cockpit software:

drbeep@openrov-banana:/opt/openrov/cockpit/src$ sudo nodejs cockpit
[sudo] password for drbeep:
config { debug: true,
debug_commands: true,
production: true,
sample_freq: 20,
dead_zone: 10,
video_frame_rate: 10,
video_resolution: ‘SVGA’,
video_device: ‘/dev/video0’,
video_port: 8090,
port: 8080,
serial: ‘/dev/ttyACM0’,
serial_baud: 115200,
dashboardURL: ‘’,
{ stores: { file: [Object], env: [Object], defaults: [Object] },
sources: [],
version: ‘0.7.1’,
Argv: [Getter],
Env: [Getter],
File: [Getter],
Literal: [Getter],
Memory: [Getter],
key: [Function],
path: [Function],
loadFiles: [Function],
loadFilesSync: [Function],
formats: { json: [Object], ini: [Object] },
Provider: [Function] },
savePreferences: [Function: savePreferences],
OpenROVCamera: ‘./lib/OpenROVCamera’,
OpenROVController: ‘./lib/OpenROVController’,
FirmwareInstaller: ‘./lib/FirmwareInstaller’,
Hardware: ‘./lib/Hardware’ }
Starting the script from /opt/openrov/cockpit/src/linux to setup UART1…
Sending command to arduino: start();
Send videoStarted to client 2
initiating camera on
ensure beagle is at 100% cpu for this camera
Sending command to arduino: start();
Started listening on port: 8080
spawning capture process…
emitted 'videoStarted’
sent videoStarted to client
camera started
Loading new-ui plugin.
path.existsSync is now called fs.existsSync.
New UI plugin loaded.
Loading standard plugin.
Standard UI loaded.
Loading input-controller plugin.
Loaded nodejs InputController component
Loading plugin-finder plugin.
Pugin Finder plugin loaded.
Plugin Finder loaded preferences: {}
Loading plugin-manager plugin.
Pugin Manager plugin started.
Plugin Manager loaded preferences: {}
Loading software-update-alert plugin.
Software update plugin started.
Software Update plugin loaded preferences: {“showAlerts”:{“showAlerts”:true}}
Loading arduinofirmwareupload plugin.
Loaded the Arduino Firmware upload pluign.
Loading blackbox plugin.
This is where blackbox plugin code would execute in the node process.
Loading camera-tilt plugin.
Camera tilt plugin loaded
Loading capestatus plugin.
Capestatus plugin started.
Capestatus loaded preferences: {“batteries”:[{“name”:“TrustFire”,“minVoltage”:8,“maxVoltage”:13},{“name”:“LiFePO4”,“minVoltage”:7,“maxVoltage”:10}],“selectedBattery”:“LiFePO4”}
Loading diveprofile plugin.
This is where DiveProfile plugin code would execute in the node process.
Loading example plugin.
This is where plugin code would execute in the node process.
Loading flybywire plugin.
This is where FlyByWire plugin code would execute in the node process.
Loading fpscounter plugin.
This is where fpscounter plugin code would execute in the node process.
Loading googletalk_ipregistration plugin.
This is where googletalk_ipregistraion code would execute in the node process.
Loading headsup-menu plugin.
Loading Heads-up menu plugin.
Loading lasers plugin.
Laser plugin loaded
Loading lights plugin.
Lights plugin loaded
Loading motor_diags plugin.
The motor_diags plugin.
Loading navigation-data plugin.
Navigation Data plugin loaded
Loading photocapture plugin.
This is where photocapture code would execute in the node process.
Loading ready plugin.
Loading rovpilot plugin.
The rovpilot plugin.
Loading serial-monitor plugin.
This is where serail-monitor code would execute in the node process.
Loading tankcontrol plugin.
This is where tankcontrol plugin code would execute in the node process.
Loading telemetry plugin.
This is where Telemetry code would execute in the node process.
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
at EventEmitter.addListener (events.js:160:15)
at telemetry (/opt/openrov/cockpit/src/plugins/telemetry/index.js:6:12)
at /opt/openrov/cockpit/src/lib/PluginLoader.js:33:63
at Array.forEach (native)
at /opt/openrov/cockpit/src/lib/PluginLoader.js:29:10
at Object.oncomplete (fs.js:107:15)
Loading touchcontroller plugin.
This is where touchcontroller plugin code would execute in the node process.
Loading ui-selector plugin.
loading Ui Selector plugin
Ui Selector loaded preferences: {“selectedUi”:“standard-ui”}
Loading visualisation3d plugin.
This is where plugin code would execute in the node process.
Serial port open
emitting updated photots to clients
camera: MJPG Streamer Version: svn rev: Unversioned directory
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 800 x 600
i: Frames Per Second.: 10
i: Format…: YUV
i: JPEG Quality…: 80
Adding control for Pan (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt (relative)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Pan/tilt Reset
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
Adding control for Focus (absolute)
UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device
mapping control for Pan (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt (relative)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Pan/tilt Reset
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Focus (absolute)
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Mode
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for LED1 Frequency
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Disable video processing
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
mapping control for Raw bits per pixel
UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device
o: www-folder-path…: disabled
o: HTTP TCP port…: 8090
o: username:password.: disabled
o: commands…: enabled

Sending command to arduino: throttle(0);
Sending command to arduino: yaw(0);
Sending command to arduino: lift(0);
Sending command to arduino: pitch(0);
Sending command to arduino: roll(0);
Sending command to arduino: go(1500,1500,1500);
GET / 200 111ms - 8.3kb
GET /bower_components/jquery/dist/jquery.min.js 404 10ms
GET /bower_components/jquery-ui//jquery-ui.min.js 404 4ms
GET /system-plugin/plugin-finder/css/style.css 200 57ms - 1.03kb
GET /ui-plugin/new-ui/css/style.css 200 38ms - 1.16kb
GET /system-plugin/software-update-alert/css/style.css 200 8ms - 108b
GET /plugin/arduinofirmwareupload/css/style.css 200 11ms - 39b
GET /plugin/blackbox/css/style.css 200 14ms - 72b
GET /plugin/capestatus/css/style.css 200 10ms - 28b
GET /plugin/diveprofile/css/style.css 200 7ms - 72b
GET /plugin/example/css/style.css 200 20ms - 72b
GET /plugin/flybywire/css/style.css 200 15ms - 72b
GET /plugin/fpscounter/css/style.css 200 9ms - 72b
GET /plugin/googletalk_ipregistration/css/style.css 200 36ms - 21b
GET /plugin/headsup-menu/css/style.css 200 8ms - 1.05kb
GET /plugin/motor_diags/css/style.css 200 11ms - 0b
GET /plugin/photocapture/css/style.css 200 36ms - 21b
GET /plugin/serial-monitor/css/style.css 200 41ms - 21b
GET /plugin/tankcontrol/css/style.css 200 28ms - 72b
GET /plugin/touchcontroller/css/style.css 200 23ms - 130b
GET /plugin/visualisation3d/css/style.css 200 9ms - 110b
GET /bower_components/knockoutjs/dist/knockout.js 404 2ms
GET /bower_components/knockout.validation/Dist/knockout.validation.js 404 2ms
GET /config.js 200 17ms - 3.85kb
GET /bower_components/webcomponentsjs/webcomponents.min.js 404 2ms
GET /ui-plugin/new-ui/js/0_jquery.svg.min.js 200 11ms - 18.77kb
GET /ui-plugin/new-ui/js/1_jquery.svgdom.min.js 200 18ms - 3.7kb
GET /ui-plugin/new-ui/js/2_jquery.svganim.min.js 200 32ms - 10.33kb
GET /ui-plugin/new-ui/js/new-ui.js 200 39ms - 967b
GET /ui-plugin/standard/js/standard.js 200 34ms - 516b
GET /system-plugin/input-controller/js/command.js 200 26ms - 1.33kb
GET /system-plugin/input-controller/js/gamepad-abstraction.js 200 20ms - 2.63kb
GET /system-plugin/input-controller/js/gamepad.js 200 12ms - 1.92kb
GET /system-plugin/input-controller/js/input-controller.js 200 12ms - 5.46kb
GET /system-plugin/input-controller/js/keyboard.js 200 9ms - 1.34kb
GET /system-plugin/plugin-finder/js/config.js 200 8ms - 561b
GET /system-plugin/plugin-finder/js/plugin-finder.js 200 14ms - 6.69kb
GET /system-plugin/plugin-manager/js/config.js 200 28ms - 592b
GET /system-plugin/plugin-manager/js/plugin-manager.js 200 39ms - 2.69kb
GET /system-plugin/software-update-alert/js/config.js 200 34ms - 1.08kb
GET /system-plugin/software-update-alert/js/software-update.js 200 20ms - 4.52kb
GET /system-plugin/software-update-alert/js/update-checker.js 200 25ms - 714b
GET /plugin/arduinofirmwareupload/js/ArduinoFirmwareViewModel.js 200 24ms - 2.27kb
GET /plugin/arduinofirmwareupload/js/arduinofirmwareupload.js 200 20ms - 5.04kb
GET /plugin/blackbox/js/blackbox.js 200 20ms - 7.06kb
GET /plugin/camera-tilt/js/camera-tilt.js 200 9ms - 1.38kb
GET /plugin/capestatus/js/batteryConfig.js 200 10ms - 833b
GET /plugin/capestatus/js/capestatus.js 200 15ms - 6.5kb
GET /plugin/diveprofile/js/diveprofile.js 200 7ms - 788b
GET /plugin/example/js/example.js 200 9ms - 3.04kb
GET /plugin/flybywire/js/flybywire.js 200 25ms - 2.86kb
GET /plugin/fpscounter/js/fpscounter.js 200 27ms - 2.38kb
GET /plugin/googletalk_ipregistration/js/googletalk_ipregistration.js 200 23ms - 2.21kb
GET /plugin/headsup-menu/js/headsup-menu.js 200 19ms - 4.54kb
GET /plugin/lasers/js/laser.js 200 22ms - 1.01kb
GET /plugin/lights/js/lights.js 200 26ms - 1.42kb
GET /plugin/motor_diags/js/motor_diags.js 200 35ms - 6.04kb
GET /plugin/navigation-data/js/navigation-data.js 200 29ms - 1.12kb
GET /plugin/photocapture/js/photocapture.js 200 31ms - 2.34kb
GET /plugin/rovpilot/js/rovpilot.js 200 37ms - 8.99kb
GET /plugin/serial-monitor/js/serial-monitor.js 200 34ms - 1.1kb
GET /plugin/tankcontrol/js/tankcontrol.js 200 33ms - 4.08kb
GET /plugin/telemetry/js/telemetry.js 200 12ms - 1018b
GET /plugin/touchcontroller/js/gamecontroller.js 200 12ms - 39.79kb
GET /plugin/touchcontroller/js/touchcontroller.js 200 14ms - 5.07kb
GET /plugin/ui-selector/js/ui-selector.js 200 33ms - 1.6kb
GET /plugin/visualisation3d/js/draw.js 200 51ms - 1.44kb
GET /plugin/visualisation3d/js/visualisation3d.js 200 41ms - 2.9kb
GET /bower_components/knockoutjs/dist/knockout.js 404 4ms
GET /plugin/visualisation3d/js/Babylon.js 200 114ms - 488.49kb
GET /bower_components/knockout.validation/Dist/knockout.validation.js 404 2ms
GET /bower_components/webcomponentsjs/webcomponents.min.js 404 2ms
GET /bower_components/polymer/polymer.html 404 2ms

Nothing in there tells me anything out of the ordinary, so I need someone who knows what they’re doing to look at it.



OK, so I loaded Google Chrome, and still no dice. Chrome won’t even load the 8090 port camera stream; it just dumps me and goes back to the home page.


Collin, I think I can upload my python files (I just did). But it is really ugly copy paste work: I warn you. I have no idea if it will make any sense to you. You will have to modify the script to your setup, since I control the ESC directly with the PWM of the pi (with a resistor in between). The driver I use is called pi-blaster. What I did: An USB joystick (Microsoft Sidewinder) sends axis and button data to the laptop with pygame. The data is translated into motor speeds and piblaster values and send via UDP to the raspberry. On the raspberry I listen on the port for the comma separated commands. If there is more than 0.5 seconds lag, the commands are purged and the buffer emptied. It executes the commands 4 times per second and turns lights on/off and controls the ESC-s. Top buttons control the tilt of the cam and the vertical thrusters. The vertical speed is controlled by a lever on the base. There are some bugs at the moment: after midnight the heartbeat stops the ROV (don’t play too late, it actually happened to me in my shed), if the wire is cut the ROV simply continues. These bugs I am addressing, but haven’t tested them properly yet.
JoystickSendPC7draft.txt (10.0 KB)
JoystickReceiveRP7draft.txt (3.5 KB)


Yea, latest version of chrome does not load the camera directly, but it should load it in page within the Cockpit.


Can you attach the console output from the browser?


OK, here’s the browser console output as best I can get it:

browser output.txt (20.8 KB)

Looks like some js errors - do I need to update/enable or do something else to my javascript?


Thanks, Niels- your code is commented way better than mine ever is :smile:

If I can’t get the OpenROV cockpit running I will try this, but I will definitely try this technique in my other (land-based) ROV that I am building.

What is the license on your code? Can I use it, should I credit you and where, etc.?




I did a little digging based on what I found in the browser console output. I found out that the bower package in /opt/openrov/cockpit/node_modules was broken. I fixed it by uninstalling all things node.js, reinstalling nodejs and nodejs-legacy, then it worked. I ran it in /opt/openrov/cockpit/src/static and it went crazy installing a whole bunch of packages. Afterwards, the cockpit loads in the browser! WOOOHOO!

But there’s no video feedback and I can’t click on anything. In the web console, NS_ERROR_FAILIURE on horizon.html. What does this mean?



After trying Google Chrome (duh - what was I thinking?), cockpit loads perfectly with video stream and everything - except for motor control. I am working on getting the Arduino to work right now. Here’s my problem: I can’t get the Arduino code to upload! I am using an Arduino UNO, with ATMega328, and the sketch size from github is too big. I was just barely able to whittle it down to fit in the memory, but it doesn’t work. What I need is just a bare bones sketch that fits on the UNO and works with the 2.5.0 software.


Cue fanfares…

I finally got the Arduino code working. Uploaded it, and now the cockpit works perfectly :smiley:

So I still wish there was official support for the Raspberry Pi - even if it was just an official instruction manual for setting up the software. If I find the time maybe I’ll try to write one.

Thank you all for your help! I hope to post my ROV dives on OpenExplorer when I get around to them.


Are you still seeing these kinds of messages?

“UVCIOC_CTRL_MAP - Error: Inappropriate ioctl for device”

I haven’t tried to do what you’re doing yet, but I am currently working with various sensors on the RPi2. So I’ve seen these types of messages, and often they are indicative of you trying to run some i/o (or access some peripheral bus) without having the proper owner/group privileges. In the case of i2c for instance, if you are running the program as user (non-root), you’ll need to be in the i2c group in order to access /dev/i2c-0 or /dev/i2c-1.

So I wonder if there are any more of those messages, and what might be generating them.

Very interesting though, your thread. Good luck with it–and I’ll be very curious to see how things go for you, because I plan to do the exact same thing. In fact I’ve already started to integrate some sensors with the RPi, using SMBus.



Hi tcbetka -

I am running everything as root via sudo - but I still get the messages. They’re all coming from mjpg-streamer and don’t affect me since all I need from the camera is the video feed. They’re all physical devices such as pan or tilt control which don’t exist on my camera.

My guess is the messages are coming from some general-purpose i/o library used in linux by mjpg-streamer and other programs.

I do want to have sensors on this thing - it’s just bare-bones right now. I’d like to at least have a depth sensor.

Good luck with your project!


Ah, I see…

I’ve spent the last few weeks writing C/C++ code for some i2c sensors. When you get that far, ping me if you run into issues. I have found that you definitely want to use SMBus calls (see i2ctools’ i2c.h and i2c-dev.h files), as they just work better than the standard open(), write() and read() syscalls. At least they are working much better for me anyway.



Hi cebrock
I want to make an open rov using raspberry pi 2 with pi camera. What should I do as a beginner


i will use a the raspi2+ ore the odroid with 2 cams 4 the ROV hwo has expirience ?
i wont to have 3D video ??


Hi James,
I have been using the pi-cam on my ROV for a year now and I am not very satisfied with it. It does poor light adjustments and the compression (ffmpeg) shows much artefacts when moving quickly. I am glad I have the gopro images for looking back afterwards.
@Cebrock, So you use a standard HP cam. I wonder if I can use these Genius HD widecam F100 and Logitech C930 with raspbian.