With “Semi-Wireless” Communication, Video, and Sensors
Three Camosun College students tell us how they repurposed an underwater remote-operated vehicle to observe the natural wonders beneath the waters around Vancouver Island. They equipped the submersible with a “semi-wireless” communications system, as well as a camera, light, temperature and pressure sensor, and inertial measurement unit.
Vancouver Island hosts a variety of beautiful lakes and Pacific shores that attract tourists from all over the world (Figure 1). What we find even more alluring, however, is the mysterious depths hidden beneath these cool, clear waters of the Pacific Northwest. When the opportunity arose to develop an underwater remote-operated vehicle (ROV) capable of observing this alien territory, we eagerly charged into it.
The final semester for an electronics technology student at Camosun College consists of a 14-week “capstone” group project, encompassing all aspects of the two-and-a-half-year diploma. We decided to indulge our love of the ocean by developing an underwater ROV system that appeals to the everyday electronics hobbyist.
Being humble electronics students, we did not want to get lost in the realm of waterproofing, buoyancy, balancing, and other mechanical principles. For this reason, we opted to develop our electronics for the mechanical hull of an ROV from an earlier student capstone project, which was gathering dust in a garage. This previous behemoth of a submersible is constructed almost entirely out of parts manufactured by Blue Robotics . Equipped with six Blue Robotics T200 thrusters, the ROV is capable of huge bursts of speed, and in fact, student lore holds that it can launch out of the water like a dolphin. Is this amount of power massive overkill for our desire to observe the natural wonders of the aquatic realm? Yes. But who said observation can’t be fun?
So what exactly did we aim to achieve, technologically, with our project? ROVs are a mature technology, so we weren’t trying to reinvent the wheel; but one thing we wanted to deviate from was having the ROV directly tethered to the user control station. Instead, we tethered our ROV to a communication buoy, which floats on the surface and transmits and receives data between the submersible and the user, making our system “semi-wireless” in a sense. This isn’t a new idea, but it isn’t as common as the classic setup of directly connecting the user to the ROV.
In addition to the semi-wireless comms system, our ROV is equipped with a camera, a light, a pressure/temperature sensor, and an inertial measurement unit (IMU) for understanding the ROV’s orientation in the water. Our user control station is equipped with a TV for viewing live camera data, and a small LCD screen for displaying sensor data.
The main components of the system are shown in Figure 2. Code for the project is available on the Circuit Cellar Article Materials and Resources webpage.
MOVING THE ROV
Moving the ROV means having a system for commanding our T200 thrusters based on input from the user. To achieve this, we used electronic speed controllers (ESCs). If you aren’t familiar with what an ESC is, think of it as a translator between a controller and a motor. In simple terms, an ESC accepts a control signal—usually a pulse width modulation signal (PWM)—and adjusts its power output to vary the speed of the motor. For our six motors, we used six of HobbyKing’s Afro 30A Multi-Rotor ESCs, sold by Blue Robotics with custom firmware, which take 400Hz PWM inputs as a control signal.
A wide range of microcontrollers can generate PWM signals that we can use to control our ESCs. We opted to use the STM32F407ZGT6 (STMicroelectronics), since we were already familiar with the very similar STM32F407 Discovery board that we had used for early testing. Choice of control chip really came down to personal preference. An Arduino or PIC would have worked just the same, as long as the chip had all the features we needed for our project. Our ST chip is capable of generating PWM signals on at least 6 of its 144 pins. Perfect. Now we just need a way to control the duty cycle of these PWMs, based on a user input.
The control input to our system is a repurposed PlayStation 3 (PS3) controller. PS3 controllers have resistive potentiometer joysticks and triggers, allowing fine user control—perfect for an ROV. The PS3 controller outputs its button, joystick, and trigger data digitally through its mini USB connection. We retrieve this data via a USB host shield connected to an Arduino UNO, combined with a USB host shield library by Kristian Lauszus . This library fully handles the process of communicating with the PS3 controller in just a few lines of code.
After the data is read into variables on the Arduino, we created a packet containing each control value. The joysticks produce a value from 0-255 for both the X and Y axes, depending on the joystick’s position. The triggers produce a value from 0-255, based on how far they are pushed in; and the buttons produce a value of either 0 or 1, depending on whether they are pressed down or not. Our packet contains these values in ASCII format, along with a preamble, packet counter, and checksum.
At this point, it is worth mentioning how the thrusters are configured on the ROV. As shown in Figure 3, two thrusters on each side of the ROV control horizontal movement, and two thrusters on the top control vertical movement. We decided that the best way to handle control would be similar to how a tank is controlled: pushing the right stick forward turns on the right two thrusters, rotating the ROV left. Pushing the left stick forward turns on the left two thrusters, rotating the ROV right. And pushing both sticks forward turns on all four thrusters, propelling the ROV forward. The right trigger turns on the top thrusters to go up, and the left trigger turns on the top thrusters in reverse to go down. Using this control scheme, we don’t actually need the X axis of the joysticks—which simplifies our control algorithm quite a bit.
In their home position, the joysticks read a value of about 128 for both axes (half of 255). Moving a joystick to its lowest position reads a 0 on the Y axis, and the highest position reads 255 on the Y axis.
How do we associate these control values with control for the ESCs? By default, our ESC’s “stop” duty cycle is 59%, its “full forward” duty cycle is 74%, and its “full reverse” duty cycle is 42%. There is a linear relationship between thruster power and duty cycle. This means that halfway between 59% and 74% duty cycle, the thruster will be delivered half of its maximum forward power. In code, we have our STM32 chip output these duty cycles based on the values read from our PS3 controller.
For example, we program the STM32 chip to output a 59% duty cycle PWM when the joystick reads between 125 and 131, because we know that the joystick is close to its home position and therefore the thruster should be off. This idea is extended to forward and reverse motion as well. If a joystick is reading a 0, we know that it’s in its bottom position, and therefore, the duty cycle should be 42% for full reverse. If a joystick is at the top, it will read as 255 and so the duty cycle should be set to 74% for full forward thrust.
The top thrusters controlled by the triggers are programmed exactly the same way; we map the left trigger’s 0-255 value from 59% down to 42% duty cycle, and we map the right trigger’s 0-255 value from 59% up to 74% duty cycle. This is very easy to implement in code, using the common “map” function along with some “if” statements.
Because we wanted the two pairs of horizontal motors to be controlled by each stick, and the pair of vertical thrusters controlled by the triggers, we send the same PWM to both motors of each pair. This effectively links the thrusters together, so that each pair will move as one unit.
We now had a way of reading user control data into a microcontroller, and we had a way of using this control data to turn on our thrusters and create smooth, reliable motion in the water. But wait a minute—how did we actually get this control data from our control station on the shore to our ROV underwater?
Communicating with our ROV means transmitting and receiving data to and from the user—not only control data from the user, but also video and sensor data from the ROV. Our system needed to reliably and quickly carry this data wirelessly over RF, while also successfully making it down our 100’ tether. Figure 4 is a block diagram of the ROV showing the relationships of the communication components.
Wireless Communication: There are several routes we could have taken to achieve wireless communication. In the interest of keeping things relatively simple, we opted to use an out-of-the-box system for video transmission and reception—AKK Technology’s TS832+RC832 video transmitter and receiver . Originally intended for drone cameras, these modules proved to be a reliable and cost-effective way of communicating video data. Video transmission actually ended up being one of the easiest parts of the project; we simply plugged our camera’s composite video signal into the transmitter, and as long as both modules are powered up, we automatically received the same composite video signal output from the receiver. A TV mounted in our control station accepted the composite video signal via an RCA connector and now we had live video from our camera.
Even going all the way through the tether, this setup created no noticeable latency, which is necessary for a good remote control system. Another benefit to this transmitter and receiver is its advertised 2km range, which is more than enough for our ROV. We haven’t tested its full range in real conditions, but it has operated reliably up to 200m away, and we simply haven’t had an opportunity or need to go farther than this.
For transmitting control data and receiving sensor data, we again wanted a convenient module that didn’t require tremendous amounts of setup. We decided to use two nRF24L01+ 2.4GHz wireless transceivers sold by Wayin , utilizing Nordic Semiconductor’s nRF chip . Put simply, these modules receive serial data via SPI and wirelessly communicate the data over the 2.4GHz ISM band—the same band that Wi-Fi uses.
To make things even easier, we implemented the use of Owen Edwards’ “nRF24l01P” library for Mbed to integrate the nRF modules with our STM chip . The library simplifies the operation of the nRF. It involves sending SPI commands to various registers aboard the module each time you want to transmit data, into ready-to-use functions such as “nrf.write.”
This is where our data packet mentioned earlier comes in. We send the packet to the nRF, utilizing the nrf.write command, the nRF transmits our packet out onto the 2.4GHz band, and our other nRF receives, decodes, and communicates the data to our other STM32 chip. This process actually occurs simultaneously (or at least perceptibly simultaneously) in both directions, since we are sending control data to the ROV while receiving sensor data from it. Our preamble, packet count, and checksum help with identifying where one packet ends and another begins, while also ensuring that the data has not been corrupted. The nRF modules have an advertised range of 1.1km, and so far they have reliably functioned without latency.
Wired Communication: Although the nRFs function well for transceiving wireless data, we still had the issue of communicating SPI data to the nRF on board our communication buoy (Figure 5). You see, SPI has a maximum range of about 30’ before significant attenuation occurs. So, although our STM32F407 chip is capable of communicating SPI, we couldn’t actually get the signal all the way up the tether to our buoy and transceiver.
Our solution to this problem was to convert our serial data (packets) coming in and out of the ROV to a communication standard that can travel the whole length of our tether. For bi-directional communication, we used two RS-422 drivers and two RS-422 receiver chips from Motorola—the MC3487 and MC3486. Note: The Motorola MC3846 and MC3847 seem to have been out of production for a very long time, and almost no information can be found online. However, a virtually identical part is still being manufactured by Texas Instruments. We used the TI datasheets  for implementing these modules.
The driver chips convert a TTL serial input into a -6V – +6V differential pair signal, which has a range in the thousands of feet, and the receiver chips convert this signal back into TTL serial. With two receivers and two drivers on either side of the tether, our STM chip aboard the ROV can easily send and receive TTL serial to and from the modules that carry the data through the tether.
A Nucleo-L432KC board on the communication buoy communicates SPI to the nRFs and TTL to the RS-422 modules, essentially acting as a translator. Using an entire Nucleo board to translate TTL serial to SPI may be considered overkill, but it made setting up the system very easy, because in just a few lines of code we could go from “SPI_Receive(data);” to “UART_Transmit(data);” and vice versa.
Since we have mentioned “sensor data” quite a few times by now, you may be wondering what exactly it is that we are sensing. We have two sensors on board the ROV though they both detect a few different things.
Since the ROV is an underwater vehicle, we figured it would be useful to know its depth, so we attached a “Bar30” combined pressure/temperature sensor (Blue Robotics) to the ROV. This digital sensor communicates using I2C serial, which means it can easily talk to our STM32 chip. We retrieve data from the sensor by sending I2C queries to different register addresses on board the sensor, and the sensor responds by sending the contents of the register back to us. Pressure data is in the form of millibars (mbr), which is easy to convert to depth with an increase of about 1,000mbr per meter of water. Temperature from the sensor is in degrees Celsius. The sensor head rests in the water, fastened to the ROV’s face plate via a threaded “neck” that slides through a hole in the plate, with a nut and O-ring on the inside that tighten to the plate and create a secure, water-tight seal.
The other sensor we utilize is a 9-axis inertial measurement unit (IMU). This device, a Bosch BNO055 9-DOF orientation sensor chip, assembled on a breakout board by Adafruit, is equipped with an electronic accelerometer, gyroscope, and magnetometer. These devices allow the chip to calculate Euler angles, which denote X, Y, and Z axis rotation of the sensor relative to Earth. We thought this sensor would be useful to inform the user of the ROV’s bearing in the often dark and disorienting underwater environment. Similarly to our pressure/temperature sensor, the IMU communicates via I2C, with data being stored in the registers of the device.
On the other end of our wireless connection—our control station—we have another nRF connected via SPI directly to another STM32407ZGT6 chip aboard a custom PCB. This chip reads control data from our Arduino UNO and USB host shield mentioned earlier. After reading in the control data, the STM chip sends the data to the nRF for transmission to the communication buoy, while simultaneously reading in sensor data from the nRF that was sent by the buoy.
Sensor data from the ROV is displayed on a ULCD-70DT display (4D Systems). We chose this screen because we already had it lying around, but it made the setup quite simple, since 4D Systems has proprietary software for quickly downloading widgets to the screen’s SD card. From here, we can send I2C commands to the display to update the widgets with live sensor data, which is once again handled by our STM32 chip.
Physically, our control station consists of a Nanuk 940 waterproof case (Figure 6). An 18” Vizio TV is mounted in the lid of the case for viewing video data from the ROV. All our controlling electronics are stored in the main compartment of the case, beneath a removable aluminum plate to protect and obscure the electronics. The aluminum plate also has a hole for our LCD to rest on and connect to the STM chip on the other side and receive sensor data over I2C.
In the spirit of simplicity and replaceability, we power the entire control station from an 18V Milwaukee tool battery (like the ones you plug into a drill), along with a few switching voltage regulators to power the different devices in the box.
There are a few other loose ends worth mentioning that tie this project together. For example, you may be wondering how the ROV and communication buoy are powered. We use a 266W-h 14.8V Li-Po battery (Blue Robotics) to power both systems. This large battery is sufficient to power the ROV for at least 1 hour under normal operating conditions, with “normal operating conditions” meaning steady movement followed by stationary observation. Technically, our six, 390W motors could drain the battery in under 10 minutes at full throttle, but full throttle is very fast, and we aren’t trying to race this thing as much as we just want to look at fish. The battery also powers our communication buoy through the tether, in combination with some switching regulators. There is a small voltage drop over the 100’ tether of about 2V, but luckily, our regulators can handle a wide range of inputs.
It’s also worth mentioning our optical system. Our camera is a Race-Keeper 700TVL Bullet Camera. While the camera works well enough to operate the ROV, it isn’t great quality for capturing footage, and so we mount a GoPro to the outside of the ROV for capturing more cinematic shots. Because it gets dark down in the water, we also mounted a waterproof RGB diving light from NEEWER to help us see, and it has managed to illuminate the depths pretty well with several hours of battery life (rated to 40m of depth).
INTO THE DEPTHS
With all our systems in position and operational, it was time to fire up the ROV. Our first test was at a local lake off of a dock. This test was when we learned that the propellers on some of our thrusters were on backward! The ROV was pretty hard to control, though we still managed to drive it around in the water a bit and verify that it held up okay.
We did our second test in a medium-sized backyard pool. With the propellers now on the right way, the ROV controlled much better. We were able to turn, go up, down, forward, and even backward. It was November, and there was about 1cm of ice on top of the water (Figure 7), and the ROV was able to charge upwards and break through it, which we thought was cool. We still wanted to improve the controls just a little bit as it was hard to finely control the ROV. After the test, we implemented a moving average filter to our duty cycle values, meaning that instead of feeding the ESCs a PWM exactly matching the current controller value, we constantly read in multiple control values to an array, average them, and feed the ESC a PWM correlating to this averaged value. Each time a new value is read into the array, all the values already in the array are moved over one position until they are eventually kicked out. The size of the array can be adjusted to change the potency of the filter.
We did our third and most recent test in the ocean at an inlet with a dock. The moving average filter worked well for improving the control of the ROV. We were able to move around the dock, and observed some jellyfish hanging out in the water (Figure 8). This area had about 10’ of depth, and the ROV had no problem going to the bottom, though we are confident it could go down much deeper than this, and we intend on diving deeper in the future.
We set out to observe the mysterious waters of Vancouver Island, and we are very satisfied to have achieved this goal and to have a cool piece of equipment to show for it. Working on the ROV also got us thinking of some additions for the future, such as some solar panels on the communication buoy so that the ROV could stay in the water in perpetuity.
We hope that our journey has sparked your interest in marine electronics. Next time you’re swimming in a lake or driving along the seashore, take the time to marvel at what may lie below the surface.
 Blue Robotics Website: https://bluerobotics.com/
 Kristian Lauszus, USB Host Shield Library: https://github.com/felis/USB_Host_Shield_2.0
 AKK Technology Wireless Video Transmitter and Receiver: https://www.akktek.com/products/vtx/akk-ts832-rc832.html
 nRF24 Series from Nordic Semiconductors: https://www.nordicsemi.com/Products/nRF24-series
 Nordic Semiconductors nRF chips: https://www.nordicsemi.com/products/nrf24-series
 Owen Edwards, nRF24l01+ library for MBed: https://os.mbed.com/users/Owen/code/nRF24L01P/forks
 Texas Instruments, MC3486 Quadruple Differential Line Receiver With 3-State Outputs, SLLS097C, Texas Instruments, June 1980 (REV February 2002). https://www.ti.com/product/MC3486
 Texas Instruments, MC3487 Quadruple Differential Line Driver, SLLS098C, Texas Instruments, May 1980 (REV February 2004). https://ti.com/lit/ds/symlink/MC3487.pdf
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • JULY 2023 #396 – Get a PDF of the issueSponsor this Article
Clinton Dundas, Alexander Ottosson, and Tony Biccum knew that they would do a capstone project together since their third semester in the Camosun College Electronics Engineering Technology program. Their choice of an ROV project was inspired by their combined interest in robotics and local marine ecosystems. After Camosun College, they all intend to pursue careers in electronics, with Clinton and Alexander planning on attending the University of Victoria (British Columbia) to earn degrees in electronics/computer engineering.