NoseyNick VA3NNW's Arduino Rotor Controller "Rotorduino"

One day in late 2015, just as winter set in, I found to my dismay that my CDE / Hy-gain HAM-IV Rotor would turn left (CCW) but not right (CW). I didn't know if it was a fault in the rotor, at the top of the tower, the cable down the tower, the control box in the shack, or any of the connectors. I decided I had EITHER a fault in my right-hand end-stop switch (normally closed, opens when you hit the right-hand end, stops you turning any further right to avoid over-shoot damage) or one of the cables / connector pins associated with it. It was certainly acting like I was against the right-hand end (when I wasn't) and thus wasn't letting me turn any further.

I REALLY didn't want to climb the tower until the spring time, but after a bit of diagnosis, a lot of web searching, and a bit of a process of elimination, I decided that yes, that end-stop switch, or some cable/connector associated with it (terminal 5 in the diagram below), was open when it should be closed. I also realised that as a very temporary and very dangerous workaround, I could short terminal 5 to terminal 8, in the control-box on the ground. I could turn right again. I do run the risk of ex$pen$ive permanent damage if I ever run off the right-hand end, but in the meantime I can rotate left and right, and I don't need to climb the tower to fix the rotor / switch / cable / etc.

I put together the diagram below, based mostly on the HAM-IV.pdf manual available from Hy-gain themselves, a CDE HAM-M manual from bunkerofdoom, and the diagram at the bottom of W4ZT's rotor delay page. I wanted/needed something neater than either of those. You are welcome to re-use my version for whatever purpose you wish, with credit / link back to here.

Hy-Gain Ham-XX / TailTwister / CDE / MFJ / many other compatible rotors

Hy-gain HAM-IV rotor circuit

I have marked the fault that exists on mine, and my dangerous, temporary workaround. I have not included wire colour info, as I have found at least 3 different colour schemes on the internet and mine seems to be a 4th!

Note: Just to avoid confusion (?), the layout of the terminals on the terminal block (top right) are not the same as the layout in the plug/socket (bottom left). The pins "up the tower" correspond to:

  1. COMMON/GND, including compass pot wiper reading
  2. brake lifter POWER (2.4ohm to 1)
  3. compass pot +ve (520ohm to 7)
  4. left limit / motor winding (~5ohm to 1)
  5. right limit sw (NormClosed to 8)
  6. left limit sw (NormClosed to 4)
  7. compass pot -ve
  8. right limit / motor winding (~5ohm to 1)

The controller switches...

Brake delay, computer control, etc

Whilst I had the controller box open, I was reminded that I have been meaning to automate it a bit better, add a brake delay, etc. There seem to be several options if you wish to buy a ready-made solution (in no particular order):

CDE/Hy-gain HAM-IV Power supply

My CDE control box has a 13V DC power supply built in. I was hoping I could connect an Arduino directly to this, but it turns out this (very simple) PSU provides about 37-45mA (or less), adequate for its own ≈27mA pot/voltmeter circuit, but leaving only about 10mA, not enough for an Arduino, never mind Arduino plus LEDs plus relays.

Hy-gain HAM-IV Meter PSU circuit

7812 simplified TO-220 However, the crude resistor+zenner voltage regulator (the R1 390ohm resistor into VR1 Zenner) is easily replaced by something like a cheap 7812 voltage regulator (datasheet). It has essentially the same circuit to control the voltage, PLUS a bypass transistor to provide far more current (see right). Some other specs…

"Floating ground" issue and new Azi pot electronics

There's also a "floating ground" issue. Look at terminal 1 in the above circuit. The zenner ensures the PSU rails remain a nice constant 13V apart, but the whole PSU is being pulled up and down (relative to ground) depending on the position of the 500Ω azimuth pot on the right. If the pot is fully right (closest to Terminal 7) the PSU rails (Terminals 7 and 3) are 0V..13V, but if the pot is fully left (closest to Terminal 3) the PSU rails are technically -13V..0V. This has never been a problem for CDE's self-contained azimuth voltmeter circuit, but if we want an Arduino to interface with the outside world via USB, we don't really want that whole USB port being pulled above+below ground. If there's any OTHER path to ground (EG through your PC/laptop) we will be dumping current into places it doesn't belong, not to mention ruining any assumptions about that 500Ω pot being 500Ω!

We don't want to re-wire the rotor itself (at the top of the tower), this might not be physically practical and in any case we don't have any spare wires in the cable/connectors, so we need to take this old pot circuit…

Old pot circuit

… and replace it with a new circuit where we instead pull both ends of the pot high (typically 5V for an Arduino) through some other resistance (to control current / avoid a short when the wiper is fully-left or fully-right) with the pot wiper still being pulled to GND (0V), like this:

New pot circuit

The old circuit is a simple voltage-divider. The new circuit is equivalent to TWO voltage dividers where we are changing the bottom half of the dividers like this (examples for fully left, 50%, and fully right):

Equivalent pot circuit

Ignore solutions where A=0 (superconducting/shorted pull-up resistors) or B=0 (shorted rotor pot). There are others where X=0 when Y=0 - also fairly obvious. By far the most useful solution is:

Nice! Note A and B have dropped out of the equation too! This means that we don't need to care too much what the values of A and C are (our pullup resistors) are as long as they are the same, and limit current enough to avoid shorts. Nor do we need to care too much what the resistance B is (azimuth pot at the top of the tower) - I was assuming a 500Ω but would work equally well if someone has a rotor with a 1k pot or whatever.

If we DO care, we can also calculate the value of B (rotor pot) given known A=C (pull-up resistors in the control box), and WolframAlpha has given us that equation too:

It also tells us the algebra breaks if 2YZ = Y+Z. This is a fairly obvious "divide by zero", however if we think about the possible values of Y and Z, this condition can only ever actually happen in real life if…

It makes perfect sense that we can't calculate the azimuth (X) in either of these conditions, and also makes sense to test for both of these conditions in the Arduino code and alarm / signal if we see them.

New pot circuit

If we are interfacing with "the real world", in fact electronics that are going to be in the near-field of a transmitting antenna, up a 15m tower, in Canadian weather, we should also add some protection circuitry. We will add bleed diodes to protect against over-voltage (> 5V) and under-voltage (< 0V), and extra resistors between the terminals and the Arduino for extra isolation.

Azi Pot Induction / Shared Ground Issue

old protection circuitry

The azi pot circuit above works fine when testing with any sensible pot on the bench, but neglects one important issue. The points marked 3 "Y", 7 "Z", and even 1 GND above are not single points, they are long wires out of the control box, across to, and up the tower, the entire length of which are right next to the high-power AC drive circuitry on the other wires (2, 4, 5, 6, 8), carrying enough power to lift the brake, and for the main motor windings to drag around a military-grade TA-53M antenna (or whetever you have on your tower). Some combination of the shared ground, and induction from these 30VAC RMS (≈85V pk-pk) high-current wires, superimposes a significant AC component on top of your little 0-3VDC sensor voltage, any time the brake is lifted and worse when the motor is rotating.

The diagram on the right shows the first version of my AziPot input protection circuitry. I used 500-ohm resistors for the pull-ups (A and C). Diodes clamped the voltage between 0-5V to protect the Arduino, with some more resistors (also 500-ohm, but unlabelled in the diagram) for a bit of current-limiting.

We are trying to measure a DC voltage between 0-5V, or in practice more like 0-2.5V (see the 1st oscilloscope below). With a large AC component superimposed on top, the analog input makes a fairly poor random-number generator, depending on exactly when I sample it (see the 2nd oscilloscope below). I could average a series of readings, or I could add some capacitance into the circuit on the "inside" of the protection circuitry (2nd version of the Azipot circuitry), however my voltage-clamping works against me here - the 3rd oscilloscope shows an example where the AC signal is being clamped at 0V, leading to an artificially high average (or capacitor-smoothed value). In practice this gives erroneously "central" values near the ends of the Azimuth scale (which return to a "correct" reading when the brake/motor are no longer energised.

osc 1 osc 2 osc 3
new protection circuitry
... so the 3rd revision of my Azipot circuitry (left) puts the Azi-pot pull-up and current-limiting on the outside, with the voltage-clamping and smoothing capacitor (100µF or so) on the inside. The DC+AC "outside" voltage is smoothed through the RC low-pass filter before voltage-clamping. The arduino does still see a bit of "noise" when the brake/motor are activated, but the readings are a whole lot more useful than the previous circuit versions.

Arduino control of the meter

The meter (I) in the original CDE circuit is a 1mA ammeter, acting as a voltmeter. It sees 0V / 0mA when the rotor is fully left, 13V / ≈1mA when the rotor is fully right, via a 10k resistor and part of a 5k calibration pot (13V through ≈13kΩ, see?).

We will want the Arduino to control it, partly 'cos it's neat to be able to do things like displaying target bearings and stuff, but mostly because we now need to do the above complicated algebra before we know what to display on the meter. An Arduino PWM port can do "analogWrite(0..255)" which isn't strictly analog, but as far as a slow mechanical meter is concerned, will be a value between 0 and 5V. We will thus need to re-wire the meter from an Arduino PWM pin, via about 5kΩ (preferably adjustable for calibration) to ground. Another option might be a fixed resistor slightly less than 5k (say, 4k7) and deliberately don't analogWrite(255) (5V) but limit to analogWrite(240) (4.7V) or whatever now gives a full-scale deflection

Arduino shield

We are replacing the CDE "R1 390Ω resistor into 13V Zenner" with a 7812 voltage regulator. The F1 fuse, assuming it was just protecting the meter, is now a bit more optional (We still have F2, and all the Arduino's protective circuitry). We are removing the R2 10k to replace with some other 5k pot.

All in all, we are replacing most of the CDE PCB, in fact if we can add replacements for the CR1 rectifier diode and C1 capacitor (470µFD or greater - newer Hy-gain rotors seem to use 1000µFD, and I seem to have 1000µFD 63V in my junk-box), we have replaced the whole CDE/Hy-gain PCB. We need 2 pull-up resistors for our new Azi pot circuit (should compare nicely with the 500 ohm azi-pot - I used 510 ohm), and 2 more isolation resistors (almost any value, i used 510 ohm again) and the over/under-voltage protection diodes (total 4). All this deserves a new PCB, and when Arduinos are involved, it's traditional to build these PCBs in the form of a "Shield" card that sits on top of the Arduino.

shield

Veroboard design

I quite like Veroboard / stripboard. Rather than making your own PCBs with all those messy etching chemicals (or indeed sending off for someone else to do the same), you buy stripboard which is a generic PCB with a grid of 2.5mm holes joined with horizontal copper tracks. You drill tracks when you need to split horizontal tracks into two or more, add jumper wires as vertical tracks, and mount through-hole components vertically between tracks or horizontally between 2 parts of a drilled track.

To be clear, the copper tracks are on the bottom of the board, all components and wires are on the top of the board. The exceptions (in this case) are the long pins going down to the arduino below, and a cunning upside-down socket for my choice of relay module.

Due to an Arduino CAD error, pins 8-13, GND, and AREF don't quite fit the 2.5mm grid, but the pins down to the Arduino are long enough that they can be fairly easily pre-bent, with pliers, to fit (see detail below, right).

I designed the Arduino code to work with almost any pinout, but deliberately used the same pins as the RB-Dfr-170 / dfr0144 relay shields - 2, 7, 8, and 10 (you could stack the Arduino, relay shield, and Rotorduino shield, but may struggle to find space for all 3 in the Rotor box!). The relay board I ordered was not a shield, but had VCC,RLY1..RLY4,GND pins on a row of 2.5mm pins. I found I could position it quite neatly hanging off the bottom-right, diagonally adjacent to my Arduino, but it took a bit of up-across-down fiddling to get a female connector BELOW the board on the "wrong" side of the stripboard (see detail bottom right). If you use a shield with a different pinout (EG RB-See-452) you may need to move some other pins round - this is easy in my software, but would require re-work of the vero shield. Another option would be a ribbon-cable to a nearby relay module (or "un-stacked" shield). My relay module wanted 12V power to (but 5V signals). If you have a 9V module, you could use a 7809 instead of a 7812 voltage regulator, and make no other modifications ot the circuit. If you have a 5V-powered module you can remove the right-most vertical wire from "RLY VCC 12V" down to "12V" and replace with the dotted wire marked further left from "RLY VCC" up to the right of the "5" terminal (which provides 5V from the Arduino).

Most of the space is taken up with a row of grey+blue 5mm-spaced terminal blocks to make it easier to connect into the CDE controller box (I bought about 400 of these terminals for a few dollars years ago) and connectivity to them.

Click "Vero Areas" below for a key pointing out the different areas of the board, corresponding to the same areas in the "Circuit" diagram itself. Click "Vero Details" for a less cluttered view, also explaining some of the connector details. "Photo" is a photo of my constructed board.

The white holes are drilled tracks on the bottom of the board to split the track into 2 or 3 horizontal tracks. The pink holes show the locations of Arduino programming pins - I avoid to reduce risk of shorts.

Circuit |  Vero Areas |  Vero Details |  Photo

Veroboard shield

Rotorduino shield construction process

  1. Cut the veroboard to approx 39 tracks × 26 holes
  2. If your Arduino's reset button is next to the USB, you may wish to saw / dremmel a triangle off top right corner (as shown) for easier access. If your reset button is elsewhere, well, sorry, you may need to use the power switch instead
  3. MARK all the components, wires, connectors, and hole positions on the TOP (non-copper) side of the board. Use a few different colours of permaent marker
  4. Check, check, and check again.
  5. Drill the copper tracks (underneath) where marked
  6. Solder all the vertical wires (yellow in the above diagram)
  7. Note the 5V VCC modification if your relay module requires 5V. DISCONNECT the right-most wire from "RLY VCC 12V" to "12V". Connect the dotted wire from "RLY VCC" up to the "5" screw/spring terminal
  8. Bend the pins on one of the stackable headers, as shown, using pliers. There are 2 bends per pin, one right at the vero, one approx halfway down each pin. Test how they fit the Arduino, re-bend if appropriate
  9. Note that the Arduino Analog pin header has only 6 pins, not 8. If you bought a big collection of 8-pin headers you may need to trim one to size. Do this by removing and disposing of pin 7, cut through the connector there, and file any rough edges
  10. Solder all 4 arduino stackable headers
  11. Check the shield plugs neatly into the Arduino. Re-bend any pins if appropriate. Check clearances. Unplug from Arduino
  12. For the BOTTOM-mounted header for the relay module, I found I could solder UPWARD-facing pin headers, then push a stackable header (trimmed from 8 to 6 pins as above) adjacent to it, held in place with some of the plastic blocks from 6 more pin headers (pins removed), then jumper the 6 pin-headers to the inverted stackable header. See "Vero details", bottom-right
  13. Alternatively, you may prefer to use a single 6-pin header and connect to a nearby relay module with a 6-way ribbon cable.
  14. Solder all the screw / spring connectors
  15. Solder the trim-pot. There's space for almost any through-hole trimpot.
  16. Solder the rectifier diode on the bottom-left of the board
  17. Solder the large capacitor. Check orientation!
  18. Solder the 2 small ceramic disc capacitors next to it
  19. Solder the 7812 (or 7809 for 9V relay modules). It is a little vulnerable hanging off the edge, but should get good air circulation and have space for a heat sink - the 7812 can get hotter than you expect, as it is essentially acting as a resistor dropping your 30V to 12V, arguably wasting more power than the rest of the circuit added together :-/
  20. Check there's about 6k of resistance between Arduino pin 9 and the "M" spring/screw connector. Adjust the pot to suit
  21. Using a continuity meter, test the entire board for shorts, it is very easy to accidentally bridge adjacent tracks when soldering. Remember there are a few places where adjacent tracks are EXPECTED to be connected, EG A5 to terminal "C", 2 adjacent Arduino GNDs, 2 other GNDs in the bottom-right. Depending on your continuity-tester, the diodes and/or resistors in the top-left may produce false-positives too?
  22. WITHOUT connecting the Arduino or relay module, temporarily borrow 30V AC from the CDE/Hy-gain meter transformer (or pins 11 and 13 on the CDE/Hygain PCB). Connect them to screw/spring terminals "G" and "X" (for Xformer)
  23. Measure voltages from GND to "(12V) Vin". It should be 12V if you have a 7812, 9V is you have a 7809. Check "RLY VCC 12V" (except if you have made the 5V relay mod). Check there's NOT 12V anywhere unexpected
  24. Disconnect the mains.
  25. Solder the pull-up resistors (top right, on the Terminal 3/7 tracks). Mine were 510ohm, anything from about 500ohm to 1k should be fine as long as both are the same value. If you have a big collection of resistors, try to pick 2 as close in measured value as possible
  26. Solder the top-left corner of the board - the current-limiting resistors (again 500ohm to 1k) and rail-clamping diodes. Be very careful of the direction they are pointing - the idea is NOT to allow current to flow straight from 5V to GND, but the exact opposite - to allow any overvoltage to be dumped onto the 5V rail, or any -ve under-voltage to be dumped onto the GND rail.
  27. Check the positions of the 2 left-most vertical (yellow) wires. The (filtered) Terminal 7 comes down to Arduino A2, Terminal 3 to A3.
  28. Connect ONLY your Arduino to your computer's USB (NOT to the shield - leave that to one side for now). Use the free Arduino IDE software to load my software onto the Arduino. Check that the debugging LED on Arduino pin 13 blinks (you are in debug mode by default).
  29. Open the Serial monitor in the Arduino software (Tools, Serial Monitor, or the little magnifying glass near the top-right). Set it to Autoscroll, any line ending (NOT "no line ending"), 9600 baud (Or see SERIAL_BAUD near the top of my software if you wish to change this). Click in the long box at the top (to the left of "Send"). Hit return a few times. You should see the debugging menu. Type "1" [and return] for a nice Arduino pinout.
  30. Unplug the USB. Carefully connect the Arduino underneath the shield. Check for clearance, make sure nothing looks close enough to short.
  31. Reconnect the 30VAC. Check for 5V between any G / GND and the terminal marked "5". Remove power.
  32. Connect your relay module. Reconnect the 30VAC.
  33. Several relays should tick-tick-tick to indicate an error condition (Rotorduino has detected no Azi Pot). Disconnect power.
  34. Connect a spare potentiometer (any value 500ohm to about 2k) between Terminals 3 and 7, with the middle connection (wiper) to G (GND).
  35. Reconnect power. This time the relays should NOT tick-tick-tick - Rotorduino has detected your fake AziPot so thinks it has a real rotor connected.
  36. Connect a spare wire between terminal "L" (left) to any G (GND). You should hear your brake relay (1) click, very shortly followed by your left relay (2). When you remove the L-G connection, left relay (2) should immediately click back, followed by brake relay (1) about 3 seconds later.
  37. Connect the spare wire between terminal "R" (right) to any G (GND). You should hear your brake relay (1) click, very shortly followed by your right relay (3). When you remove the R-G connection, right relay (3) should immediately click back, followed by brake relay (1) about 3 seconds later.

Built

Rotorduino

Here it is, built. I removed some of the unused space space on the LHS because it fits neater under the azimuth meter. The 7812 voltage regulator hangs off the bottom left. It is a little vulnerable there but allows easy addition of a heat sink if required - the 7812 can get hotter than you expect, as it is essentially acting as a resistor dropping your 30V to 12V, arguably wasting more power than the rest of the circuit added together. I found a very small 10k meter calibration pot (set to approx midpoint for the required 5k for 1mA FSD), there is space for a larger pot (over the wire). The terminal connectors are labelled:

There are also 2.5mm pin/socket connectors for:

Physical installation

+++ TODO: physical placement, USB port
+++ TODO: OTHER connection details (relays etc)
+++ TODO: include CW / CCW / status LEDs
+++ TODO: include meter calibration

Here it is in place in the bottom of the CDE case, connected to the Arduino and my relay module (both below my vero shield). The front panel will be at the bottom of this picture, with the meter on the left, the switches on the right. A hole is cut for the USB port in the LHS of the case, and mounting holes are drilled for proper mounting bolts but the boards are held in place with cable-ties until I get a chance to obtain the appropriate hardware.

Rotorduino in place

CDE HAM-IV
Credit: rigpix

Parts list

PartNotesCost
CDE / Hy-gain / TailTwister / MFJ / other rotor Assuming you already have one if you are wanting ot automate it? $0 (assuming you have one)
Arduino / Genuino Uno, Diecimila, Duemilanove, Leonardo, or any clone Any Uno / clone should be fine, but if your arduino clone is one of those with extra servo connector pins, you may want to be careful to avoid shorts betweem those and the rotorduino shield. $27 $26 $22 $23 $24,
plenty of clones <$25, shop around.
4 Channel Relay module / shield 3 channels would probably be adequate if you find one cheaper. I used RB-Elf-156 (12V). RB-Ite-04 should work fine (with the 5V VCC mod). RB-Suf-05 may need some physical re-work to fit underneath, or a ribbon cable to connect it (and the 5V mod) My board uses Arduino pins 2, 7, 8, and 10 to be compatible with the RB-Dfr-170/144 shield, but I have not tested this, and the triple-decker stacking may limit your mounting options in the CDE/Hy-gain case. RB-See-452 Shield uses different pins. My software can be easily changed, but hardware would need work to swap with the L/brake/R switch input pins. RB-Lin-84 I'm not familiar with, looks like it might be configurable to use pins 2, 7, 8, 10, and ignore the xbee (or add your own xbee code?) RB-Elf-156 $9.41 (12V), RB-Ite-04 $7.90 (5V), RB-Suf-05 $11.63 (5V), RB-Dfr-170/144 $20.92 (9V, good pinout), RB-See-452 $27.40 (pins 4,5,6,7!) RB-Lin-84 $22.66 (9V, check pins!)
Veroboard / stripboard 2.5mm (0.1in) grid, 39 tracks × 26 holes, maybe slightly less? GBP1.50 for 39×62 - ≈$1.50 for 39×26?
7812 voltage regulator (12V) (or 7809 for 9V relay modules), or find any other way to work a 12V (or 9V) PSU into your controller case, and arrange for it to get to Vin on the Arduino / VCC on the relay module / shield L78S12CV GBP1, TS7812CZ GBP1.09, L7812CP GBP1.50, L78S05CV GBP1 (5V), TS78M05CZ GBP1.09 (5V) <$2.00
Diodes × 5 4 for over/under-voltage protection, 1 for PSU rectification 5 × 10c or less?
Resistors × 4 2 for the AziPot pull-up, 2 to isolate the Arduino from the rotor a bit. The pull-up ones in the top-left (5V to T3 and T7) should, ideally, be as similar to each other as possible to make the algebra accurate (measure them and find a nice matching pair?) I used 510Ω, anything from about 200Ω to 1k5 should work OK. The ones in the middle of the board (down to Arduino A2 and A3) can probably be even higher values, within reason (maybe 10k?). 4 × 10c or less?
Pot / trimpot set to approx 5k Start above 5k, bring down to achieve meter FSD. Alternatively, something like a 4k fixed resistor in series with a 2k pot, for greater precision. Another option might be a fixed resistor a bit lower than 5k (4k64, 4k7, 4k75, 4k81, 4k87), and calibrate in software to never analogWrite(255) but limit lower. 15c - 50c?
Capacitor, 470µF or greater, 40V or greater I had a 1000µF 63V in my junk-box 50c-75c?
0.33µF capacitor
0.1µF capacitor
ceramic disc caps on I/O of 7812. Junk-box / anywhere 2 × 15c or less?
Spring / Screw terminals, 5mm (0.2in) pitch × 12 If you prefer, you can re-work to use more pin-connectors or whatever. I bought about 350 of these spring connectors for less than $10 at a local hamfest a few years ago. pennies
Wire Suitable for all the vero vertical connections. Also hook-up wire suitable for all the connections to the meter, front panel pot, L/brake/R microswitches, transformer, rotor terminal block, etc. pennies
8-Pin Stackable Headers Long pins, to provice sockets on top of the shield and long pins to the arduino below the shield. Pins need to be long enough to clear the arduino components, and 8 of them need bending to accommodate the "wrong" spacing of the Arduino headers 10×8 @ $4.10, I used 5×8?
Pin headers I used a few of these for the "clever" up/across/down connector to the relay module 10×40 @ $2.47, I used 1×9?
Misc hardware? nuts, bolts, washers, stand-offs? Cable ties? pennies
Tools Soldering iron, solder, maybe desoldering tool for removing old CDE/Hy-gain PCB and re-wiring? Inter-continental ballistic missile*. Track-cutting tool (or very careful drilling). Hacksaw and/or Dremmel. A brain. Screwdrivers, pliers, wire cutters, etc. $0 (assuming you already have them)
6-core ribbon cable? ... unless you can connect your relay module directly to your Arduino, and still fit nicely in the Rotor box, like I could Assume $0
Total $35 - $40? +Time

(*optional)

Software

I wrote my own rotor control software (+++ WORK IN PROGRESS +++).

I initially wanted to be compatible with Rotor-EZ, just because that's what the "other guys at the club" use/like, but after a bit of research, realised there are a number of other rotor control protocols out there, and Rotor-EZ's is not exactly the cleanest, most "complete", or the easiest to implement. There's also no really good reason why I should feel any loyalty to Rotor-EZ's protocol in particular, as long as I can control it nicely from some software on my desktop/laptop (EG anything that uses hamlib, most dx-cluster software).

I'd love to implement many protocols, in some neat multi-protocol-compatible way, which may or may not be practical, but in the meantime, some combination of Yaesu / EasyComm looks easier and cleaner than Rotor-EZ's slightly awkward handling of "AP1xxx<CR>" vs "AP1xxx;".

Honourable mention / shout-out to K3NG / Radio Artisan, and the Arduino Rotator Computer Interface blog post). I DID stumble across this project early in my research, but for some reason dismissed it on the mistaken understanding that it wasn't compatible with Hy-Gain/CDE rotors, only Yaesu ones (yaesu-rotator-computer-serial-interface in the URL?) or home-built ones, and/or was going to need a digital display or something. It turns out it could control my relays, can do Azi without Elevation, it's probably capable of doing everything I needed except my X = (Y-YZ) ÷ (Y+Z-2YZ) algebra. It could do a sort of adequate job of just measuring the voltage on one side of the AziPot, or, to be honest, I could probably have added my algebra into the K3NG code, and submitted it back for others to appreciate too. If I had realised this earlier in my software development lifecycle, I would probably have just written a rotator_pins_va3nnw.h, rotator_features_va3nnw.h etc. The K3NG / Radio Artisan code was really useful as a protocol reference for Yaesu / EasyComm protocols though, and also adds some nice "backslash commands" which I may borrow.

Most of what I have learned about Rotor protocols, I have learned from:

Hamlib, (hamlib github), partially implements easycomm (see also easycomm.txt), rotorez, Yaesu gs232a, and probably a bunch of others, but typically not the entire command-set of any of them, just enough for the basic hamlib requirements.
k3ng_rotator_controller, k3ng_rotator_controller.ino in particular, and their wiki, also the radioartisan blog post, radioartisan yahoo group - as mentionned above, this implements Yaesu GS-232A, GS-232B, EasyComm, and a few extensions of its own, and has a great open source philosophy.
HamSupply Rotor EZ Protocol pdf ... which claims to be compatibile with "HyGain DCU-1 control", which I found at Hy-gain's DCU-1 support page. Commands are sometimes <CR>-terminated (\r), sometimes semicolon-terminated (;), sometimes the same command acts slightly differently depending on the ; vs <CR>.
A fair GS-232A/B reference is at gatorradio.org Yaesu GS-232B Manual pdf
Richard VE2DX proposes / discusses a DUAL Azimuth control protocol v2.0.0 pdf, extending GS-232B for "dual azi", calling it GS232B-AZ/AZ, but it is hard to tell if this has actually been implemented anywhere.
K4JRG's "Rotor Control DXA USB" is also based on a subset of GS-232 with a few extra commands of its own. It also uses 19200 8N1 by default.
Umesh K6VUG built an Antenna Positioning System with Arduino (pdf), which implements / discusses EasyComm II
Murray ZL1BPU (great guy, love his Digital Modes book!) seems to have created his own ZL1BPU Rotator Controller Comms Protocol, and implements one obvious "go to XXX" command from each of ORION, YAESU, SARTEK. Note that unlike most of the other protocols, no <CR><NL> sequence is needed for his "native" commands.
http://www.qsl.net/yo3dmu/index_Page346.htm lists a huge number of rotor protocols but doesn't itself give many real details.
SP3TYF built an arduino controller for a 24V HyGain AR-303, and was featured on hackaday, but I don't understand enough Polish to take advantage of any of his code :-D

Commands

[ Sortable - click column headers to sort by command / response / etc ]

Command Notes Response Protocol
API***; Sets the target bearing but does not execute DCU-1
AM 1; Starts Rotation to Target Bearing DCU-1
AP1xxx<CR> Sets the target bearing and executes Rotor-EZ
AP1xxx; Sets the target bearing but does not execute Rotor-EZ
AM1; executes rotation to the bearing set by the "AP1xxx;" command Rotor-EZ
AI1; or AI1<CR> inquires current bearing ";xxx" (xxx = 000..360) Rotor-EZ
; terminates rotation Rotor-EZ
E enable endpoint option Rotor-EZ
e disable endpoint option Rotor-EZ
O enable overshoot option Rotor-EZ
o disable overshoot option Rotor-EZ
S enable unstick option Rotor-EZ
s disable unstick option Rotor-EZ
V reports version number and copyright information "ROTORCARD © IDIOM PRESS" ? Rotor-EZ
J enable jam protection Rotor-EZ
j disable jam protection - NOT recommended Rotor-EZ
K enter RotorCard calibration mode (see manual) Rotor-EZ
k exit RotorCard calibration mode (see manual) Rotor-EZ
R<CR> Clockwise Rotation Yaesu GS-232A (H)
L<CR> Counter Clockwise Rotation Yaesu GS-232A (H)
A<CR> CW/CCW Rotation Stop Yaesu GS-232A (H)
C<CR> antenna direction value "+0aaa" now " AZ=aaa" Yaesu GS-232A (H)
M<CR> Antenna Direction Setting. MXXX (M000 .. M360 or M450) Yaesu GS-232A (H)
M<CR> Time Interval Direction Setting.
MTTT XXX XXX XXX ...
(TTT = Step value)
(XXX = Horizontal Angle)
Yaesu GS-232A (H)
T<CR> Start Command in the time interval direction setting mode. Yaesu GS-232A (H)
N<CR> Total number of setting angles in "M" mode and traced
number of all datas (setting angles)
"+nnnn+mmmm" now " AZ=nnn EL=mmm" Yaesu GS-232A (H)
S<CR> All Stop Yaesu GS-232A (H)
O<CR> Offset Calibration (for Azi) Yaesu GS-232A (H)
F<CR> Full Scale Calibration (for Azi) Yaesu GS-232A (H)
X1<CR> Rotation Speed 1 (Horizontal) Low Yaesu GS-232A (H)
X2<CR> Rotation Speed 2 (Horizontal) Middle 1 Yaesu GS-232A (H)
X3<CR> Rotation Speed 3 (Horizontal) Middle 2 Yaesu GS-232A (H)
X4<CR> Rotation Speed 4 (Horizontal) High Yaesu GS-232A (H)
U<CR> UP Direction Rotation (CW) Yaesu GS-232A (H2)
D<CR> DOWN Direction Rotation (CCW) Yaesu GS-232A (H2)
E<CR> UP/DOWN Direction Rotation Stop Yaesu GS-232A (H2)
C2<CR> Antenna Direction Value "+0aaa+0eee" now " AZ=nnn EL=nnn" Yaesu GS-232A (H2)
W<CR> Antenna Direction Setting.
WXXX YYY
Yaesu GS-232A (H2)
W<CR> Time Interval Direction Setting.
WTTT XXX YYY XXX YYY ...
(TTT = Step value)
(XXX = Horizontal Angle)
(YYY = Elevation Angle)
Yaesu GS-232A (H2)
T<CR> Start Command in the time interval direction setting mode. Yaesu GS-232A (H2)
N<CR> Total number of setting angle in "W" mode and traced number of all datas (setting angles) "+nnnn+mmmm" Yaesu GS-232A (H2)
S<CR> All Stop Yaesu GS-232A (H2)
O2<CR> Offset Calibration (for Ele) Yaesu GS-232A (H2)
F2<CR> Full Scale Calibration (for Ele) Yaesu GS-232A (H2)
B<CR> Elevation Antenna Direction Value "+0xxx" - now " EL=xxx" Yaesu GS-232A (H2)
P45<CR> Set_mode 450 Degree Yaesu GS-232B (H3)
P36<CR> Set_mode 360 Degree Yaesu GS-232B (H3)
Z<CR> Switch N Center/S Center Yaesu GS-232B (H3)
MBxxx<CR> Turn Azi2 to bearing xxx VE2DX
XB1<CR> Rotation Speed 1 (Vertical) Low VE2DX
XB2<CR> Rotation Speed 2 (Vertical) Middle 1 VE2DX
XB3<CR> Rotation Speed 3 (Vertical) Middle 2 VE2DX
XB4<CR> Rotation Speed 4 (Vertical) High VE2DX
O2B<CR> offset calibration VE2DX
FB<CR> full-scale calibration VE2DX
FB2<CR> full-scale calibration VE2DX
NB<CR> same as 'N' for rotor B VE2DX
TB<CR> same as 'T' for rotor B VE2DX
Y<CR> synchronize Azi1 and Zri2 rotors from now on VE2DX
Ynnn<CR> synchronize from now on except Azi2 has nnn-degree offset from Azi1 VE2DX
Y999<CR> break sync VE2DX
ZB<CR> toggle between ... "N Center" or "S Center" VE2DX
AZ[nnn.n]<CR|NL|SP?> Position azimuth rotator EasyComm II
EL[nn.n]<CR|NL|SP?> Position elevation rotator EasyComm II
SA<CR|NL|SP?> Stop azimuth rotator EasyComm II
SE<CR|NL|SP?> Stop elevation rotator EasyComm II
VE<CR|NL|SP?> Show version EasyComm II
HELP<CR|NL|SP?> show help page EasyComm/K6VUG
SV<CR|NL|SP?> show current values EasyComm/K6VUG
SV AZPW|ELPW[nnnnnnn]<CR|NL|SP?> min/max pulse widths EasyComm/K6VUG
SV SPEED [nn]<CR|NL|SP?> 1 to50 rpm EasyComm/K6VUG
SV TIMEOUT [nn]<CR|NL|SP?> seconds EasyComm/K6VUG
SV DEFAULTS<CR|NL|SP?> reset defaults EasyComm/K6VUG
A<CR> Stop K3NG yaesu
C<CR> Report Azimuth in Degrees: "AZ=000" on GS_232B, else "+0360" K3NG yaesu
C<CR> WITH FEATURE_ELEVATION_CONTROL: "AZ=nnnEL=nnn" else "+0360+0090" K3NG yaesu
F<CR> Full Scale Calibration - see GS232A.pdf K3NG yaesu
L<CR> Rotate Azimuth Counter Clockwise K3NG yaesu
M###<CR> Rotate to ### degrees K3NG yaesu
MTTT XXX XXX XXX ...<CR> Timed Interval Direction Setting (TTT = Step value in seconds, XXX = Azimuth in degrees) K3NG yaesu
N<CR> Report Total Number of M Timed Interval Azimuths K3NG yaesu
O<CR> Offset Calibration - see GS232A.pdf K3NG yaesu
R<CR> Rotate Azimuth Clockwise K3NG yaesu
S<CR> Stop K3NG yaesu
T<CR> Start Timed Interval Tracking K3NG yaesu
X1<CR> Horizontal Rotation Low Speed K3NG yaesu
X2<CR> ... K3NG yaesu
X3<CR> ... K3NG yaesu
X4<CR> Horizontal Rotation High Speed K3NG yaesu
H<CR> print help - "depricated" but [+++ long help spew +++] K3NG yaesu
P36<CR> for 360-degree rotation (no overlap mode) "Mode 360 degree" K3NG yaesu GS_232B
P45<CR> for 450-degree rotation (overlap mode) "Mode 450 degree" K3NG yaesu GS_232B
Z<CR> to toggle N Center / S Center? K3NG yaesu GS_232B
ZN<CR> azimuth_starting_point = 0 "N Center" VA3NNW GS-232B++
ZS<CR> azimuth_starting_point = 180 "S Center" VA3NNW GS-232B++
ZE<CR> ? VA3NNW GS-232B++
ZR<CR> ? VA3NNW GS-232B++
Zxxx<CR> ? Centre bearing VA3NNW GS-232B++
AZ[x][x]x.x<CR|NL|SP> go to azimuth K3NG easycom
AZ<CR|NL|SP> Az query "AZxxx.x" [space?] K3NG easycom
EL[y][y]y.y<CR|NL|SP> go to elevation K3NG easycom
EL<CR|NL|SP> El query "ELyyy.y" [space?] K3NG easycom
ML<CR|NL|SP> Move Left K3NG easycom
MR<CR|NL|SP> Move Right K3NG easycom
MU<CR|NL|SP> Move Up K3NG easycom
MD<CR|NL|SP> Move Down K3NG easycom
SA<CR|NL|SP> Stop azimuth moving K3NG easycom
SE<CR|NL|SP> Stop elevation moving K3NG easycom
VE<CR|NL|SP> Request Version "VE002" K3NG easycom
ARxx<CR> analog pin read "ARxx0000" to "ARxx1023" K3NG slave
AWxxyyy<CR> analog pin write "OK\n" K3NG slave
AZ<CR> read azimuth "AZxxx.xxxxxx" K3NG slave
CL<CR> return clock string "CLYYYY-MM-DD hh:mm:ssZ" K3NG slave
DOxx<CR> digital pin initialize as output "OK\n" K3NG slave
DIxx<CR> digital pin initialize as input "OK\n" K3NG slave
DPxx<CR> digital pin initialize as input with pullup "OK\n" K3NG slave
DRxx<CR> digital pin read "DRxx0" or "DRxx1" K3NG slave
DLxx<CR> digital pin write low "OK\n" K3NG slave
DHxx<CR> digital pin write high "OK\n" K3NG slave
DTxxyyyy<CR> digital pin tone output "OK\n" K3NG slave
EL<CR> read elevation "ELxxx.xxxxxx" K3NG slave
GS<CR> query GPS status "GS0" (no sync) or "GS1" (sync) K3NG slave
NTxx<CR> no tone "OK" K3NG slave
PG<CR> ping "PG" K3NG slave
RB<CR> reboot "" (no response) K3NG slave
RC<CR> read coordinates "RC+xx.xxxx -yyy.yyyy" K3NG slave
SAx<CR> activate serial read event; x = port # "OK" K3NG slave
... and unsolicited (after SAx) "EVSxy" - Serial port read event; x=port, y=byte NOT IMPLEMENTED K3NG slave
SDx<CR> deactivate serial read event; x = port # "OK" K3NG slave
SSxyyyyyy...<CR> serial write string; x = port #, yyyy = string to send "" (no response?) K3NG slave
SWxy<CR> serial write byte "" (no response returned?) K3NG slave
on error - Serial port buffer timeout "ER01" K3NG slave
on error - command too short or syntax error "ER02" K3NG slave
on error - Command syntax error? sometimes? huh? "ER0289" K3NG slave
... and unsolicited "CS2.0.2015122901" - report a cold start (remote to host only) K3NG slave
\Ax[x][x][.][xxxx]<CR|NL> manually calibrate azimuth "Azimuth set to N" K3NG slash
\Bx[x][x][.][xxxx]<CR|NL> manually calibrate elevation K3NG slash
\C<CR|NL> return clock_string "YYYY-MM-DD hh:mm:ssZ" K3NG slash
\D<CR|NL> toggle debug mode, no return K3NG slash
\E<CR|NL> "Initialized eeprom, resetting unit in 5 seconds..." K3NG slash
\Fxx<CR|NL> turn pin off; xx = pin number 00..99 or A0..A9 "OK" K3NG slash
\G<CR|NL> some sun/moon grid square stuff \GFN20EV to set lat+lon? K3NG slash
\L<CR|NL> rotate to long path (AZI +/- 180), nmo return K3NG slash
\M0<CR|NL> "Moon tracking deactivated." K3NG slash
\M1<CR|NL> "Moon tracking activated." K3NG slash
\Nxx<CR|NL> turn pin on; xx = pin number 00..99 or A0..A9 "OK" K3NG slash
\Oyyyymmddhhmm<CR|NL> set clock (seconds 00) "Clock set to YYYY-MM-DD hh:mm:ssZ" K3NG slash
\P<CR|NL> Park "Parking..." ... "Parked\n" K3NG slash
\r<CR|NL> "Remote port rx sniff on" [or off] K3NG slash
\Sxxxx...<CR|NL> send xxxx to slave (with \r) K3NG slash
\SWxy<CR|NL> serial write byte; x = serial port # (0, 1, 2, 3), y = byte to write NOT IMPLEMENTED K3NG slash
\SDx<CR|NL> deactivate serial read event; x = port # NOT IMPLEMENTED K3NG slash
\SSxyyyyyy...<CR|NL> serial write string; x = port #, yyyy = string to send NOT IMPLEMENTED K3NG slash
\T0<CR|NL> "Remote port tx sniff off" K3NG slash
\T1<CR|NL> "Remote port tx sniff on" K3NG slash
\U0<CR|NL> "Sun tracking deactivated." K3NG slash
\U1<CR|NL> "Sun tracking activated." K3NG slash
\Wxxyyy<CR|NL> turn on pin PWM; xx = pin number, yyy = PWM value (0-255) "OK" K3NG slash
\XS<CR|NL> Use sun as 0,0 "Heading calibrated. Az: xxx.x El: yyy.y" K3NG slash
\XM<CR|NL> Use moon as 0,0 "Heading calibrated. Az: xxx.x El: yyy.y" K3NG slash
\X0<CR|NL> Use 0,0 as 0,0 "Heading calibrated. Az: xxx.x El: yyy.y" K3NG slash
\Z0<CR|NL> "Suspend auto remote commands off" K3NG slash
\Z1<CR|NL> "Suspend auto remote commands on" K3NG slash
\?ARxx<CR|NL> analog pin read; xx = pin 00..99 A0..A9 "\\!OKARxxyyyy" yyyy=0000..1023 K3NG slash
\?AWxxyyy<CR|NL> analog pin write; xx = pin #, yyy = value 000..255 "\\!OKAW" K3NG slash
\?AS<CR|NL> AZ status "\\!OKAS<az_state>" 0=idle 1=slowR 2=slowL 3=R 4=L .. 16=various K3NG slash
\?AZ<CR|NL> query AZ "\\!OKAZ000.00" K3NG slash
\?CL<CR|NL> read the clock "\\!OKCLYYYY-MM-DD hh:mm:ssZ" or "\\!??CL" K3NG slash
\?DIxx<CR|NL> digital pin initialize as input; xx = pin # 00.99 or A0..A9 "\\!OKDO" K3NG slash
\?DPxx<CR|NL> digital pin initialize as input with pullup "\\!OKDP" K3NG slash
\?DRxx<CR|NL> digital pin read; xx = pin # "\\!OKDRxx0" or "\\!OKDRxx1" K3NG slash
\?DOxx<CR|NL> digital pin initialize as output; xx = pin 00.99 or A0..A9 "\\!OKDO" K3NG slash
\?DLxx<CR|NL> digital pin write low; xx = pin # "\\!OKDL" K3NG slash
\?DHxx<CR|NL> digital pin write high; xx = pin # "\\!OKDH" K3NG slash
\?DTxxyyyy<CR|NL> digital pin tone output yyyy = frequency "\\!OKDT" K3NG slash
\?EL<CR|NL> query EL "\\!OKEL000.00" or "\\!??EL" if no ELEVATION_CONTROL K3NG slash
\?ES<CR|NL> EL Status "\\!OKES<el_status>" or "\\!??ES" K3NG slash
\?FS<CR|NL> Full Status "\\!OKFSaaa,+eee,<az_state>,<el_state>,+lat,+lon,<GPS_SYNC>,YYYY-MM-DD hh:mm:ssZ;"
aaa=AZI 000-360 +eee=+ele or -ele az_state=0..16 el_state=0..16
K3NG slash
\?GAxxx.x<CR|NL> go to AZ xxx.x "\\!OKGA" or "\\!??GA" K3NG slash
\?GExxx.x<CR|NL> go to EL "\\!OKGE" or \\!??GE" K3NG slash
\?GS<CR|NL> query GPS sync "\\!OKGS0" or "\\!OKGS1" for GPS sync K3NG slash
\?NTxx<CR|NL> noTone; xx = pin # "\\!OKNT" K3NG slash
\?PG<CR|NL> Ping "\\!OKPG" K3NG slash
\?RB<CR|NL> reboot (immediately with no response) K3NG slash
\?RL<CR|NL> rotate left "\\!OKRL" K3NG slash
\?RR<CR|NL> rotate right "\\!OKRR" K3NG slash
\?RU<CR|NL> elevate up "\\!OKRU" K3NG slash
\?RD<CR|NL> elevate down "\\!OKRD" K3NG slash
\?RC<CR|NL> Read coordinates "\\!OKRC+lat +lon // if GPS installed K3NG slash
\?SA<CR|NL> stop azimuth rotation "\\!OKSA" K3NG slash
\?SE<CR|NL> stop elevation rotation "\\!OKSE" K3NG slash
\?SS<CR|NL> stop all rotation "\\!OKSS" K3NG slash
\?[*]<CR|NL> [unrecognized backslash command] "\\!??" K3NG slash
on error / unrecognized input "Error." K3NG slash
AZaaa.a ELeee.e UPuuuuuuuuu UUU DNddddddddd DDD<NL> UP.* DN.* ignorable (frequencies in Hertz), UUU/DDD are modes like SSB, AM or FM Hamlib EasyComm I
AZ0.0 EL0.0 UP000 XXX DN000 XXX<NL> example Hamlib EasyComm I
AO<CR|NL|SP> AOS? WTF? Hamlib EasyComm II
ANx<CR|NL|SP> Read analog input n. "AN\n;" - FFS?!? "ANx,yyy" Hamlib EasyComm II
AZ[x][x]x.x<CR|NL|SP> go to azimuth Hamlib EasyComm II
AZ<CR|NL|SP> query Azimuth "AZ[x][x]x.x" Hamlib EasyComm II
DMxx...<CR|NL|SP> Downlink Mode (FM, SSB, etc) Hamlib EasyComm II
DN000<CR|NL|SP> ignore??? Downlink freq in Hz? Hamlib EasyComm II
DRn<CR|NL|SP> Downlink Radio number (ignore) Hamlib EasyComm II
EL[y][y]y.y<CR|NL|SP> go to elevation Hamlib EasyComm II
EL<CR|NL|SP> query elevation "EL[y][y]y.y" Hamlib EasyComm II
IP<CR|NL|SP> Read input "IPn". "IP\n;" - FFS! +++???+++ Hamlib EasyComm II
LO<CR|NL|SP> LOS? WTF? Hamlib EasyComm II
ML<CR|NL|SP> Move Left Hamlib EasyComm II
MR<CR|NL|SP> Move Right Hamlib EasyComm II
MU<CR|NL|SP> Move Up Hamlib EasyComm II
MD<CR|NL|SP> Move Down Hamlib EasyComm II
OPn<CR|NL|SP> Set output number (WTF?) Hamlib EasyComm II
SA<CR|NL|SP> Stop azimuth moving Hamlib EasyComm II
SE<CR|NL|SP> Stop elevation moving Hamlib EasyComm II
STyy:mm:dd:hh:mm:ss<CR|NL|SP> Set time Hamlib EasyComm II
ST<CR|NL|SP> query time? I'm guessing "STyy:mm:dd:hh:mm:ss"? Hamlib EasyComm II
UMxx...<CR|NL|SP> Uplink Mode (FM, SSB, etc) Hamlib EasyComm II
UP000<CR|NL|SP> ignore??? Uplink freq in Hz? Hamlib EasyComm II
URn<CR|NL|SP> Uplink radio number (ignore) Hamlib EasyComm II
VE<CR|NL|SP> Get version. "VE\n;" - FFS! "VE002"? Hamlib EasyComm II
... and unsolicited "ALxxxx" for an alarm described by xxxx Hamlib EasyComm II
CRx<CR|NL|SP> Read config register 0-f? "CRX,y"? Hamlib EasyComm III
CR[space!]c<NL> Read config register 0-f. "CR %c\n;" - FFS! Hamlib EasyComm III
CWxxxx<CR|NL|SP> Write config register 0-f?
reg 0=MaxSpeed(number) a=overshoot(0|1) b=jamming(0|1) c=endpoints(0+1) d=unstick(0|1)
Hamlib EasyComm III
GE<CR|NL|SP|;> Get error register. "GE\n;" - FFS! "GEnn" 1=sensor|2=jam|4=homing errors Hamlib EasyComm III
GS<CR|NL|SP|;> Get status register. "GS\n;" - FFS! "GSnn" 1=idle|2=moving|4=pointing|8=error Hamlib EasyComm III
VL0000 .. VL9999<CR|NL|SP> Velocity Left (mdeg/s) Hamlib EasyComm III
VR0000 .. VR9999<CR|NL|SP> Velocity Right (mdeg/s) Hamlib EasyComm III
VU0000 .. VU9999<CR|NL|SP> Velocity Up (mdeg/s) Hamlib EasyComm III
VD0000 .. VD9999<CR|NL|SP> Velocity Dn (mdeg/s) Hamlib EasyComm III
VE<CR|NL|SP|;> Get version "VE003"??? Hamlib EasyComm III
RESET<CR|NL|SP> Reboot? Hamlib EasyComm III
PARK<CR|NL|SP> Park Hamlib EasyComm III
AP1xxx; sets the target bearing but does not execute. Hamlib rotorez
AM1; executes rotation to the bearing set by the "AP1xxx;" command Hamlib rotorez
AS1; stops rotation on DCU-1 Hamlib rotorez
AI1; inquires current bearing. ";000" .. ";359" degrees Hamlib rotorez
; terminates rotation "C2000 IDIOM V1.4S "? Hamlib rotorez
E enable endpoint option - effective immediately Hamlib rotorez
e disable endpoint option - effective immediately Hamlib rotorez
O enable overshoot option - effective immediately Hamlib rotorez
o disable overshoot option - effective immediately Hamlib rotorez
S enable unstick option - effective immediately Hamlib rotorez
s disable unstick option - effective immediately Hamlib rotorez
V reports version number "C2000 IDIOM V1.4S "? Hamlib rotorez
J enable jam protection - effective immediately Hamlib rotorez
j disable jam protection - effective immediately - NOT recommended! Hamlib rotorez
Wxxx yyy<CR> go to Az xxx El yyy Hamlib gs232a
C2<CR> query position "+0aaa+0eee" Hamlib gs232a
S<CR> stop rotation Hamlib gs232a
X1\r .. X4<CR> to set speed? Hamlib gs232a
U<CR> move up? Hamlib gs232a
D<CR> move down Hamlib gs232a
L<CR> move left Hamlib gs232a
R<CR> move right Hamlib gs232a
on error "?" Hamlib gs232a
Gxx xx is bearing in hex in 2-degree incr 00 to B4 "G nn\r\n"
"< nn" 2/sec when moving CCW(L)
"> nn" 2/sec when moving CW(R)
"= nn" when heading reached.
ZL1BPU
R report: "R hh dd" where hh is current hex/2 heading dd is dest ZL1BPU
S Stop. "S\r\n" ZL1BPU
V Version "V xy\r\n" for version x.y ZL1BPU
A<CR>xxx<CR> go to heading 000..359 "" (no response) ZL1BPU "orion format"
Mxxx<CR> go to 000..359 "" (no response) ZL1BPU "yaesu format"
Py<CR> go to y (char 0x00 to 0xff - but 180-deg off?) "" (no response) ZL1BPU "sartek format"
... and unsolicited "$ nn\r\n" 3 times every 2sec when first powered up ZL1BPU
on error - pot error (2/sec) "!P nn" ZL1BPU
on error - rotor error (2/sec) "!R nn" ZL1BPU
B96<CR> to set 9600 baud K4JRG GS-232++
B19<CR> to set 19200 baud K4JRG GS-232++
UI<CR> for menu: 1. Set N,S,E or W rotor heading (S)
2, Set LEFT (ccw) stop (10)
3. Set RIGHT (cw) tstop (857)
4. Set rotor MAX speed (4)
5. Start Delay (1)
6. Move rotor to XYZ degrees (302)
7. Flash Microcontroller      [send a .hex file?]
9. Save and exit
Please select:
K4JRG GS-232++