Controlling Oars For An RC Model Galley

Now that my kids are older I have the time to return to model ships. I did a static model but now I am thinking of making a Roman galley for radio control. To avoid problems with synchronizing the oars on two sides when driven by separate electric motors I thought maybe servo drive would be a good solution.

I made a test jig representing the oars on a bireme galley, and used an Uno along with a prototyping shield to interface the Uno to the RC receiver and four servos on the test jig. Each side has a "sweep" servo to move the oars back and forth and a "lift" servo to raise and lower them. The Uno receives "throttle" and "rudder" inputs from the RC Rcvr and derives signals to control the four servos. This is my first arduino project ever, and there were a few coding hiccups along the way, but I got more used to coding as I went.

I tried to use the servo library but I had problems because the Uno uses its clock to derive 20msec intervals for PWM to the servos, but the incoming pulses from the RC Rcvr are "20msec" according to its own crystal clock. The asynchronous internl interrupts used in the Uno to drive the PWM were causing me problems.

Ultimately I did not use the servo library at all. Instead I connected the Rcvr outputs to the Uno's two external interrupt pins and used edge detection and the internal microsecond counter to measure their widths. Once the program has measured the latest pulses, it goes ahead and calculates next values for the servos, given the preceding values and the incoming settings. The resulting pulses are sent to the servos one at a time, as "write high, wait an interval, write low". Nice and simple.

I have a log for all this on Model Ship World; for any who are interested here are links to some videos I posted. The first shows how the oars on the inside of a turn stop or even backstroke. The second shows my first attempt at incorporating a short pause at the end of the power stroke. The third incorporates some suggestions from a fellow who commented on MSW on how to increase realism for the stroke.


Interesting motions created. Do you have anywhere that describes the mechanical setup and the software you wrote?

Not sure what you mean by mechanical setup. If you mean the rowing jig, no I have no drawings I just made it up as I went, other than making the waterline beam about 7 inches which would be a Roman quadrireme at 1/32 scale (according to Michael Pitassi in "Roman Warships").

Here a couple of closer photos of the jig. I didn't bother with oar blades. Mini drawer slides are used to allow the sweep motion. The large wood blocks with the grooved ends allow the lift movement; in an actual model I would instead use SS shafts and linear bearings from ServoCity. I'm not sure how I would attach the oar looms in an actual model; the joint strength would need to be improved somehow, maybe by just having a brass tube reinforcement on the oar to prevent the end from splitting?? Maybe??

I designed the proto shield to interface the Uno to the servos and the Rcvr. Here are pictures of it from top and bottom.

The four 3-pin connectors for the servos are near the bottom. Each has a dedicated fuse to protect it. Each fuse can be bypassed via a 2-pin jumper, which are present for testing just the jig. The DIP switches are for contingencies and as seen in the videos I used to enable certain features. Final use for the switches is TBD. There are three 3-pin connectors near the top left for servo connections from the RC Rcvr, Presently only two are used (throttle & rudder); the third is for future contingencies. The large header at the left is for servo power supply, +6V/GND, which has many pins because it could be several amps in a ship model. GND is common with arduino GND but +6V powers the servos only. The arduino in the videos gets +5V from a USB connection and this +5V is passed upstream to the RC Rcvr via its servo connections to the arduino. In a model ship I would supply the arduino and hence the Rcvr from a 9V battery and the arduino's on-board regulator.

The software?

Briefly, there are two ISR's which are called when an edge occurs at either the throttle or the rudder input. The ISR reads the DC level; if high then the pulse just started and the start time microsecond counter reading is stored; if low then the pulse just ended and the end time counter reading is stored and a flag is set. End of ISR.

The main loop hangs around in an empty WHILE loop waiting for a flag. When a flag occurs the pulse width is calculated by subtracting the start time from the end time. A running average of five entries is maintained. Once both pulses have been measured (they are received every 20 msec) the main loop continues (the flags are also cleared).

It first uses the throttle reading to figure out how fast the sweep servos should be moving. Once this is known, a value is calculated for the delta between consecutive positions which of course are 20 msec apart. The next sweep value is calculated by either adding the delta value to the previous sweep value or subtracting it, depending on whether we are in the power portion of the stroke or the return portion. Thus every 20 msec we have a new setting to send to the sweep servos.

As I mentioned in the video, for the lower half of throttle settings the strike rate (strokes per minute) is constant and the sweep length increases. In the upper half of the range, the sweep is full always, and the strike rate increases. The above sweep calculator takes all this into account.

Next, a new "lift" value is calculated. This just depend on the sweep value, and whether we are in the power or return portion of the stroke.

Next, the rudder value is used to determine what the ship is trying to do. For low rudder deflections the oars just row straight ahead (or back) to allow slight course corrections by rudder alone. For higher deflections the oars on the inside of the turn are stopped. For very high deflections they are reversed. In all, the compass is divided into 10 possible ship motions, for example "going ahead with moderate right turn", or "in reverse with hard left turn", etc etc. A variable called "shipsMotion" is set to zero through nine depending on the rudder value.

If the throttle value is very low the ship is "stopped" which is shipsMotion=0.

Next there is a large SWITCH statement with shipsMotion used as the variable.
For each of the 10 cases values are assigned for the sweep and lift on each side. For example, if we are going straight ahead then both sweep values are simply the value calculated above. If turning hard right, then the starboard sweep value is the negative of the calculated value while the port sweep remains equal to calculated sweep. The software just assigns sweep or negative sweep, or a fixed value if oars are stopped, as appropriate for each case.

The port and starboard lifts are always the same, since the sides always row in sync, unless one side is stopped in which case that lift becomes a fixed value. In the test I stopped the oars in the water; in an actual model it may be best to stop them out of the water as was done in the trireme Olympias's sea trails in the 90's. (If you google "trireme Olympias" you can find videos of 170 volunteers rowing her near Greece).

Next, the final sweep and lift values are sent to the servos, one after the other. That's the end of the main loop; it now goes back to the WHILE loop and awaits the next flags.

That's it in a nutshell. It was fun doing this, but to make any more determinations on stroke shape and such, I will need to make a model for "sea trials".

Thanks for your interest.

Great explanation, thanks.