matemika
Published © GPL3+

Simple UHF Antenna Rotator

The video shows the process of building an antenna rotor for a lightweight VHF / UHF antenna.

IntermediateProtip6,448
Simple UHF Antenna Rotator

Things used in this project

Story

Read more

Custom parts and enclosures

Motor DC holder

Small bearing holder

Clutch, first element

LPDA Antenna holder

Small gear wheel

20x20 profile cover

Clutch, second element

Big gear wheel

Height lock, first element

Height lock, second element

Bearing bracket

Small bearing holder, second element

Schematics

Example electrical connection in Fritzing

Code

rotor.ino

C/C++
Arduino NANO V3
const int iAzStepperRev = 200;
String sMotorSpeed = "";
int motorSpeed = 0;
int stepCount = 0;  
float fAzStepperPos = 0;
int iAzStepperTemp = 0;
float fAzStepperTemp = 0;
float fMotorSpeed = 0;
int iMotorSpeed = 0;
unsigned long previousTimeStepper = millis();
unsigned long previousTimeSend = millis();
long timeIntervalStepper = 8;
long timeIntervalSend = 100;

void AZ_StepperRelase()
{
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
}

void setup() {
  Serial.begin(4800);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void PrintValues(float &fAzTemp, float &fMotorSpeed, float &fAzPos)
{
  Serial.print(iMotorSpeed, 1);
  Serial.write('\t');
  Serial.print(fMotorSpeed, 1);
  Serial.write('\t');
  Serial.println(fAzPos, 1);
}


void MoveStepper()
{
  int iAzStepperPos = analogRead(A7);
  fAzStepperPos = map(iAzStepperPos, 0 , 1023, 0, 8790);
  fAzStepperPos = fAzStepperPos / 10.0;
  fAzStepperPos = fAzStepperPos - 236.5;
  fMotorSpeed = motorSpeed;
  if (fMotorSpeed < 0)
    iMotorSpeed = map(-fMotorSpeed, 0, 100, 100, 255);
  else
    iMotorSpeed = map(fMotorSpeed, 0, 100, 100, 255);

  if (Serial.available() > 0)
    sMotorSpeed = Serial.readString();
  motorSpeed = sMotorSpeed.toInt();

  if (motorSpeed > 0) {
    analogWrite(11, iMotorSpeed);
    analogWrite(10, iMotorSpeed);
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(5, HIGH);
  }
  else   if (motorSpeed < 0) {
    analogWrite(11, iMotorSpeed);
    analogWrite(10, iMotorSpeed);
    digitalWrite(2, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(5, LOW);
  }
  else if (motorSpeed == 0)
    AZ_StepperRelase();
}

void Safety()
{
  if ((fAzStepperPos < -60.0 && motorSpeed > 0) || (fAzStepperPos > 270.0 && motorSpeed < 0))
    sMotorSpeed = "0";
}

void loop()
{
  unsigned long currentTime = millis();

  //master loop
  Safety();
  MoveStepper();

  //task 1 - send frame
  if (currentTime - previousTimeSend > timeIntervalSend)
  {
    previousTimeSend = currentTime;
    fAzStepperTemp = map(analogRead(A6), 0, 1023, -55, 155);
    PrintValues(fAzStepperTemp, fMotorSpeed, fAzStepperPos);
      }
}

ROTOR_DC.pde

Java
Processing Code
import processing.serial.*;
import controlP5.*;

Serial magistrala;
ControlP5 cp5;
PFont font;

PImage background;
PImage dial;
float heading;
float headrad;
float strefaMartwa = 285.0;
float fAzTemp = 0.0;
float fAzPos = 0.0;
String sAzPos = "";
float fAzSpeed = 0.0;
float[] fDataUART= {};
float fSetAzSpeed = 0.0;
int iSetAzSpeed = 0;
String sSetAzSpeed = "0";
int iBorderX, iBorderY, iBorderW, iBorderH, iGateMaps;

void setup() 
{
  magistrala = new Serial(this, "/dev/UKF_ROTATOR", 4800);
  magistrala.bufferUntil('\n');
  font = loadFont("DejaVuSans-20.vlw");  
  background(0);
  dial = loadImage("dial.png");

  cp5 = new ControlP5(this);

  size(1100, 600);  

  cp5.addButton("LEFT")                        
    .setPosition(20, 345)                         
    .setSize(175, 60)                            
    .setFont(font)
    .setColorBackground(color(255, 0, 0)); 

  cp5.addButton("STOP")                        
    .setPosition(20, 255)                         
    .setSize(360, 80)                            
    .setFont(font)
    .setColorBackground(color(255, 0, 0)); 

  cp5.addSlider("AzSpeed")
    .setRange(1, 100)
    .setFont(font)
    .setHandleSize(20)
    .setCaptionLabel("")
    .setSize(220, 30)
    .setPosition(160, 200);

  cp5.addButton("RIGHT")                        
    .setPosition(205, 345)                        
    .setSize(175, 60)                            
    .setFont(font)
    .setColorBackground(color(255, 0, 0));

  cp5.addButton("MAPA")                        
    .setPosition(20, 500)                         
    .setSize(175, 60)                            
    .setFont(font)
    .setColorBackground(color(255, 0, 0)); 

  frameRate(100);
  magistrala.bufferUntil ( '\n' );

  STOP();
}

void draw() {
  background(0);
  image(dial, 525, 25, 550, 550);

  //ramka statusu
  fill(0, 80, 220);
  rect(10, 110, 380, 75, 7);
  textFont(font, 24);

  //ramka prdkoci
  fill(240, 240, 0);
  rect(10, 195, 380, 40, 7);
  textFont(font, 24);

  //ramka prdkoci
  fill(240, 240, 0);
  rect(10, 245, 380, 170, 7);
  textFont(font, 24);

  //ruchoma ramka
  fill(0, 0, 255);
  rect(iBorderX, iBorderY, iBorderW, iBorderH, 0);

  //tekst
  fill(255, 255, 255);
  textFont(font, 32);
  text("RADIO ROTOR CONTROLER", 10, 30); 
  textFont(font, 24);
  text("CALLSIGN: SP9MX", 10, 65); 
  textFont(font, 24);
  text("OPERATOR: MATEUSZ", 10, 95);
  textFont(font, 24);
  text("ACT AZIMUTH:", 15, 140);
  sAzPos = nf(fAzPos, 0, 1);
  text(sAzPos, 305, 140);  
  text("ACT ROT SPEED:", 15, 170);
  if (fAzSpeed < 0)
    sAzPos = nf(-fAzSpeed, 0, 0);
  else sAzPos = nf(fAzSpeed, 0, 0);
  text(sAzPos, 305, 170);
  fill(0, 0, 0);
  textFont(font, 24);
  text("SET SPEED:", 15, 225);

  //promie wodzcy
  stroke(255, 0, 0);
  strokeWeight(4);
  float pi =3.1415;
  float radian = - pi*(fAzPos/180);
  float x = 800-275*sin(radian);
  float y = 300-275*cos(radian);
  line(800, 300, x, y);

  //strefa martwa rotora
  //pocztek
  stroke(0, 0, 255);
  strokeWeight(1);
  float radian2 = - pi*((strefaMartwa-15)/180);
  float x2 = 800-275*sin(radian2);
  float y2 = 300-275*cos(radian2);
  line(800, 300, x2, y2);
  float radian3 = - pi*((strefaMartwa+15)/180);
  float x3 = 800-275*sin(radian3);
  float y3 = 300-275*cos(radian3);
  line(800, 300, x3, y3);

  fSetAzSpeed=cp5.getController("AzSpeed").getValue();
  iSetAzSpeed = (int)fSetAzSpeed;
  println(fDataUART);
}

void LEFT() 
{
  magistrala.write(str(iSetAzSpeed));
  iBorderX = 15;
  iBorderY = 340;
  iBorderW = 185;
  iBorderH = 70;
}

void STOP() 
{
  magistrala.write("0");
  iBorderX = 15;
  iBorderY = 250;
  iBorderW = 370;
  iBorderH = 90;
}

void RIGHT() 
{
  magistrala.write(str(-iSetAzSpeed));
  iBorderX = 200;
  iBorderY = 340;
  iBorderW = 185;
  iBorderH = 70;
}

void importDataUART()
{
  fAzTemp = fDataUART[0];
  fAzSpeed = fDataUART[1];
  fAzPos = fDataUART[2];
}

void MAPA()
{
  if (iGateMaps == 0)
  {
    iGateMaps=1;
    dial = loadImage("dx.png");
  } 
  else if (iGateMaps == 1)
  {
    iGateMaps=0;
    dial = loadImage("dial.png");
  }
}

void serialEvent(final Serial s) 
{
  fDataUART = float(splitTokens(s.readString()));
  redraw = true;
  importDataUART();
}

Credits

matemika

matemika

0 projects • 2 followers

Comments