Sometimes spare parts are hard to find. So was the control clock for a Yaesu G2700 rotator at ON6NL ‘s place. The decision to make one was made easy. There is a potmeter in the rotor, normally 500 Ohms. The rotor has 450 degrees turning angle allowing overlap on either side. of 45 degrees.. So starting northwest the rotor can rotate through north, east, south, west, north and northeast.
The rotor driver consisted of a Chinese module PWM control and direction control found at Aliexpress for around €10-15 and a transformer, diodes and electrolytic capacitors from the junkbox. This is only for DC motors!
The readout was kept as simple as possible. A 2x16LCD an arduino nano and the software.
The display showing a 15 degrees overlap.
Over the pot-meter output a capacitor of 470nF was placed to ground. This made the readout more stable.
// Antenna direction display for rotors with potmeter
// By PA3CSG and ON6NL - April 2024
//
// Reads pot.meter and displays compass direction, degrees
// and warnings for overlap and nearing end stops
//
// Hardware: LCD i2c display 16 positions, 2 lines, Arbduino Nano and potmeter in rotor
//
// First fill in
// the maximum position you allow the rotor to turn to the left = CCW as DegMinus
// with degrees left of North as minus ( 45 degrees CCW (NW) overlap is -45)
// the maximum position you allow the rotor to turn to the right = CW as DegMax
// with degrees right of North added to 360 ( 45 degrees CW (NE) overlap is 405)
//
// To calibrate ; Turn rotor fully Counter Clock Wise position
// Note the number in the lower right corner of the display.
// This number must be entered as the valueCCW
// Turn rotor fully Clock Wise position
// Note the number in the lower right corner of the display.
// This number must be entered as the valueCW
// Compile and upload the sketch
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
//+++++++++++++ Calibration settings +++++++++++++++++++++++++++++
int valueCCW = 2; // Digital value of the pot meter at full CCW
int valueCW = 915; // Digital value of the pot meter at full CW
int DegMinus = -45; // DEGREES of the maximum position the rotor turns CCW
int DegMax = 405; // DEGREES of the maximum position the rotor turns CW
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int analogInputPin = 0; // analog input on Pin 0 of Arduino
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address of the Display, 16 chars, 2 lines
byte N[8] = {
B00100,
B01110,
B10101,
B00100,
B00100,
B00100,
B00100,
B00100,
};
byte EW[8] = {
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
};
byte S[8] = {
B00100,
B00100,
B00100,
B00100,
B00100,
B10101,
B01110,
B00100,
};
byte BS[8] = {
B00000,
B10000,
B01000,
B00100,
B00010,
B00001,
B00000,
B00000,
};
void setup() {
//initialize lcd screen
lcd.init();
// turn on the backlight
lcd.backlight();
// Welcome screen
lcd.setCursor ( 0 , 0);
lcd.print(F("Antenna readout"));
lcd.setCursor ( 0 , 1);
lcd.print(valueCCW);
lcd.print(F("="));
lcd.print(DegMinus);lcd.print((char)223); //Degrees symbol
lcd.print(F(" "));
lcd.print(valueCW);
lcd.print(F("="));
lcd.print(DegMax);lcd.print((char)223); //Degrees symbol
lcd.createChar(0, N);
lcd.createChar(1, EW);
lcd.createChar(2, BS);
lcd.createChar(3, S);
delay (2000);
lcd.clear ();
//Serial print set up
Serial.begin(115200);
}
void loop() {
// Convert pot. meter value to digital value
int Dvalue = analogRead(analogInputPin); // Read pot. meter value
Serial.print(F(" Dvalue ")); // Debug in Serial Monitor
Serial.println(Dvalue);
// Digital readout Value on display
lcd.setCursor(12,1); //col 12 line 2
// Fill with space to align
if (Dvalue < 1000) { lcd.print(F(" ")); } // Below 1000 one fill space
if (Dvalue < 100) { lcd.print(F(" ")); } // Below 100 one more fill space
if (Dvalue < 10) { lcd.print(F(" ")); } // Below 10 one more fill space
lcd.print(Dvalue);
// Map digital value to degrees between full CCW and full CW
int Degrees = map(Dvalue , valueCCW , valueCW , DegMinus , DegMax );
// Direction in degrees on display with degrees symbol
lcd.setCursor(6,0);
// Fill with space to align
if ((Degrees > -10) && (Degrees < 0)) { lcd.print(F(" ")); } // -9 to -1
if ((Degrees > -1) && (Degrees < 10)) { lcd.print(F(" ")); } // 0 to 9
if ((Degrees > 9) && (Degrees < 100)) { lcd.print(F(" ")); } // 10 to 99
lcd.print(Degrees);
lcd.print((char)223); //Degrees symbol
// Compass Direction on display
lcd.setCursor(11,0);
if (Degrees < -23 ) { lcd.print(F("NW")); }
if ((Degrees > -22) && (Degrees < 23 )) { lcd.print(F(" N")); }
if ((Degrees > 22) && (Degrees < 68)) { lcd.print(F("NE")); }
if ((Degrees > 67) && (Degrees < 113)) { lcd.print(F(" E")); }
if ((Degrees > 112) && (Degrees < 158)) { lcd.print(F("SE")); }
if ((Degrees > 157) && (Degrees < 203)) { lcd.print(F(" S")); }
if ((Degrees > 202) && (Degrees < 248)) { lcd.print(F("SW")); }
if ((Degrees > 247) && (Degrees < 293)) { lcd.print(F(" W")); }
if ((Degrees > 292) && (Degrees < 338)) { lcd.print(F("NW")); }
if ((Degrees > 337) && (Degrees < 381)) { lcd.print(F(" N")); }
if (Degrees > 382) {lcd.print(F("NE")); }
// Compass rose on display
if (Degrees < -23 ) { lcd.setCursor(0,0); lcd.write(byte(2)); lcd.print(F(" ")); } // NW "\"
if ((Degrees > -22) && (Degrees < 23 )) { lcd.setCursor(0,0); lcd.print(F(" ")); lcd.write(byte(0)); lcd.print(F(" ")); } //N
if ((Degrees > 22) && (Degrees < 68)) { lcd.setCursor(0,0); lcd.print(F(" /")); } // NE
if ((Degrees > 67) && (Degrees < 113)) { lcd.setCursor(0,0); lcd.print(F(" ")); lcd.write(byte(1)); } // E
if ((Degrees > 112) && (Degrees < 158)) { lcd.setCursor(0,1); lcd.print(F(" ")); lcd.write(byte(2)); } // SE
if ((Degrees > 157) && (Degrees < 203)) { lcd.setCursor(0,1); lcd.print(F(" ")); lcd.write(byte(3)); lcd.print(F(" ")); } //S
if ((Degrees > 202) && (Degrees < 248)) { lcd.setCursor(0,1); lcd.print(F("/ ")); } //SW
if ((Degrees > 247) && (Degrees < 293)) { lcd.setCursor(0,0); lcd.write(byte(1)); lcd.print(F(" ")); } //W
if ((Degrees > 292) && (Degrees < 338)) { lcd.setCursor(0,0); lcd.write(byte(2)); lcd.print(F(" ")); } // NW "\"
if ((Degrees > 337) && (Degrees < 381)) { lcd.setCursor(0,0); lcd.print(F(" ")); lcd.write(byte(0)); lcd.print(F(" ")); } //N
if (Degrees > 382) { lcd.setCursor(0,0); lcd.print(F(" /")); } // NE
if ((Degrees > 112) && (Degrees < 248)) {lcd.setCursor(0,0); lcd.print(F(" ")); } // Clear unused top positions
else {lcd.setCursor(0,1); lcd.print(F(" ")); } // Clear unused bottom positions
// Special positions
lcd.setCursor(0,1);
if ((Degrees < 0 ) || (Degrees > 360 ))
{
lcd.print(F("overlap ")); // Overlap areas
if (Dvalue <= (valueCCW + 5) ) { // Rotor close to end stop CCW
lcd.setCursor(0,1); lcd.print(F(" ROTATE CW ")); //col 1, line 2
}
if (Dvalue >= (valueCW - 5) ) { // Rotor close to end stop CW
lcd.setCursor(0,1); lcd.print(F(" ROTATE CCW ")); //col 1, line 2
}
}
else {
lcd.setCursor(3,1); lcd.print(F(" ")); // No special position
}
delay (200); // wait between readings
}