Project tutorial
Servo Control Panel

Servo Control Panel © GPL3+

A panel to control the pitch of a wing (or aircraft or control surface deflection) in a small wind tunnel.

  • 1,753 views
  • 2 comments
  • 7 respects

Components and supplies

Apps and online services

About this project

Demo.

About this project

The idea is to realize an instrument panel to control a servo and display the angle and sweep mode on a LCD screen. Although compact and cheap boards dedicated to servo testing do exist, I wanted to realize a device to control and display the flap deflection of a wing model in a little, didactic wind tunnel and I wanted to do it, as far as possible, with the items provided with the Arduino Starter Kit.

How it works

Usually, servo testers give the possibility to control the servo angle by rotating a knob, put the servo in the neutral position, and sweep automatically between the minimum and maximum angle positions. Since my objective is to provide a user interface for wing angle of attack variation or control surface deflection, I do not need to put the servo in the neutral position (i.e. 90° if the servo rotates between 0° and 180°), but I need a switch to set a reference zero angle. In fact, the servo may be at any position while the wing (or control surface) angle relative to the wind is null. Also, I am interested to measure the deflection of the control surface relative to the reference zero. Finally, I want the servo to automatically sweep between two given angles around the reference zero at a certain angular velocity, which I want to control, although I am not interested in measuring it (I just want it to rotate faster or slower).

In my case, I used a little servo with JR connector, I assumed that the flap angle is equal to the servo angle (this is a rough estimate), and the auto-sweep function has been set between -30° and +60° (positive values, means increase in lift force: flap rotates down, the aerodynamic force increases upwards.

The panel operates in two modes: manual control and auto sweep. The user interface provides three buttons, a knob, and a LCD screen. The display shows the servo angle in manual control mode and the limit angles (set in the Arduino code and not editable from the panel) in auto-sweep mode. The switch buttons serve as zeroing the reference angle, commuting between the manual control and auto-sweep mode, and changing the sign of the angle reported on the LCD display. In fact, since the servo rotation may be opposite to the desired convention, the last switch button gives the possibility to change the sign on the screen, but does not invert the rotation of the servo, which is linked to the rotation of the knob. In manual control mode, the servo knob controls the servo angle, which is shown on the LCD screen. Initially, the display shows the servo absolute angle, after the zeroing it shows the servo angle relative to that zero. In the auto-sweep mode, the servo knob controls the rotation rate by adjusting the delay between consecutive rotations (between 15 and 100 ms).

Final note

I have managed to use items from the Arduino Starter Kit, except for the bigger breadboard. The panel shown in the final picture has a slightly different arrangement from the breadboard scheme for assembly reasons. Consider that you may need an external power source to control the servo, according to the voltage and power consumption of your device. If the servo vibrates, check your connections, then try to add an external power source. You may need to rearrange some of the items on your breadboard.

Although incorrect, I have kept the original names for the code filename, variables, and display statements. Angle of attack, alpha, AOA are synonymous, defined as the angle between a reference line and the wind direction in the longitudinal plane. In my application, I have changed the deflection angle of a control surface, which also changes the angle of attack, by altering the local wind direction due to the pressure difference between the upper and lower wing surfaces. By AOA on the display I mean servo angular position, which is related to the control surface deflection by the linkage system. The variation of angle of attack and lift force due the control surface deflection is related to the control surface effectiveness.

Code

angleAttackControlPanel.inoArduino
// Panel to control a servo rotation and read angle on a LCD display,
// with the possibility to set a reference angle and read values
// from that reference. Useful to get the deflection angle of a 
// control surface from a datum. Once set a reference angle, to get
// again the absolute position of the servo, just reset the Arduino.
// There is also the possibility to perform an automatic sweep
// between two given angles, from a given reference, and to change
// the rotational speed of the servo, by adjusting the delay between
// successive angles.
//
// Made by Danilo Ciliberti on 9th December 2017

#include <LiquidCrystal.h>
#include <Servo.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Servo myServo;

int const signPin = 6;  // button to switch sign of the angle
int const sweepPin = 7; // button to turn auto angle sweep on/off
int const zeroPin = 8;  // button to set reference
int const pot = A0;     // potentiometer that controls angle/rate
int potVal;             // value of the angle/rate
int angle;              // angle of the servo
int rotDelay;           // speed of the servo (delay between angles)
int zero = 0;           // reference angle of attack
int signSwitch = 1;     // sign of the angle (positive or negative)
int alpha;              // angle of attack
int sweepState = 0;     // auto sweep state (on/off)
int lowLimit = -30;     // low angle limit for auto sweep
int highLimit = 60;     // high angle limit for auto sweep
int newLowLimit;        // low limit angle from the zero
int newHighLimit;       // high limit angle from the zero

void setup() {
  pinMode(zeroPin, INPUT);
  pinMode(signPin, INPUT);

  lcd.begin(16, 2);
  lcd.print("Angle of attack");
  lcd.setCursor(0, 1);
  lcd.print("control panel");
  delay(3000);
  lcd.clear();

  myServo.attach(9);  // servo is attached to pin 9
  Serial.begin(9600);
}

void loop() {

  // if the zero button is pressed the angle of attack is set to 0
  if (digitalRead(zeroPin) == HIGH) {
    zero = angle;
    // centers the auto sweep limits around the new zero
    newLowLimit = lowLimit + zero;
    newHighLimit = highLimit + zero;
    Serial.print("Setting low angle limit: ");
    Serial.println(newLowLimit);
    Serial.print("Setting high angle limit: ");
    Serial.println(newHighLimit);
    delay(100);
  }

  // if the sign button is pressed changes the sign of the angle
  if (digitalRead(signPin) == HIGH) {
    signSwitch = -1 * signSwitch;
    delay(100);
  }

  alpha = signSwitch * (angle - zero);   // angle of attack respect to reference

  // check if auto sweep button has been pressed
  if (digitalRead(sweepPin) == HIGH) {
    sweepState = 1;
    Serial.print("Auto sweep state = ");
    Serial.println(sweepState);
    lcd.clear();
    delay(100);
  }

  // turn on auto sweep if auto sweep button has been pressed
  if (sweepState == 1) {

    // check if alpha range is out of servo range
    if (newLowLimit < 0 || newLowLimit > 179) {
      newLowLimit = 0;
      Serial.print("Actual low angle limit: ");
      Serial.println(newLowLimit);
    }
    if (newHighLimit > 179 || newHighLimit < 0) {
      newHighLimit = 179;
      Serial.print("Actual high angle limit: ");
      Serial.println(newHighLimit);
    }
    
    // if auto sweep button has been released
    if (digitalRead(sweepPin) == LOW) {
      
      lcd.home();
      lcd.print(lowLimit);
      lcd.print(" < AOA < ");
      lcd.print(highLimit);
      lcd.setCursor(0, 1);
      lcd.print("Auto sweep ON");

      // check the angle sign to assign correct sweep angles sequence
      if (signSwitch == 1) {
        angle = zero + alpha;
      }
      else {
        angle = zero - alpha;
        newHighLimit = -lowLimit + zero;
        newLowLimit = -highLimit + zero;
      }

      while (angle < newHighLimit) {
        // assign delay between angles, varying servo rotational speed
        potVal = analogRead(pot);
        Serial.print("potVal: ");
        Serial.print(potVal);
        rotDelay = map(potVal, 0, 1023, 15, 100);
        Serial.print(", rotDelay: ");
        Serial.print(rotDelay);
        Serial.println(" ms");
        myServo.write(angle);
        delay(rotDelay);
        
        // if during loop auto sweep button is pressed exit the loop
        if (digitalRead(sweepPin) == HIGH) {
          sweepState = 0;
          Serial.print("Auto sweep state = ");
          Serial.println(sweepState);
          lcd.clear();
          delay(100);
          goto manual;
        }
        angle++;
      }
      
      while (angle > newLowLimit) {
        // assign delay between angles, varying servo rotational speed
        potVal = analogRead(pot);
        Serial.print("potVal: ");
        Serial.print(potVal);
        rotDelay = map(potVal, 0, 1023, 15, 100);
        Serial.print(", rotDelay: ");
        Serial.print(rotDelay);
        Serial.println(" ms");
        myServo.write(angle);
        delay(rotDelay);
        
        // if during loop auto sweep button is pressed exit the loop
        if (digitalRead(sweepPin) == HIGH) {
          sweepState = 0;
          Serial.print("Auto sweep state = ");
          Serial.println(sweepState);
          lcd.clear();
          delay(100);
          goto manual;
        }
        angle--;
      }
      
    }
  }
  else {  // if auto sweep is turned off
    manual:   // label destination of interrupted loop
    lcd.setCursor(0, 1);
    lcd.print("Manual control");
    
    potVal = analogRead(pot);
    Serial.print("potVal: ");
    Serial.print(potVal);
    angle = map(potVal, 0, 1023, 0, 179);
    Serial.print(", angle: ");
    Serial.print(angle);
    myServo.write(angle);
    delay(15);
    Serial.print(", zero: ");
    Serial.print(zero);
    Serial.print(", AOA: ");
    Serial.println(alpha);
    
    lcd.home();
    lcd.print("AOA = ");
    // To avoid overlapping text among readings I must use blank 
    // characters (space) when needed over the four predicted positions.
    
    // between -179 and -100 four digits are assigned
    if (alpha >= -179 && alpha <= -100) {
      lcd.print(alpha);
      lcd.print(" deg");  // no space after
    }
    // between -99 and -10 three digits are assigned
    else if (alpha >= -99 && alpha <= -10) {
      lcd.print(alpha);
      lcd.print(" deg ");  // one space after
    }
    // between -9 and -1 two digits are assigned
    else if (alpha >= -9 && alpha <= -1) {
      lcd.print(alpha);
      lcd.print(" deg  ");  // two spaces after
    }
    // between 0 and 9 only one digit is assigned
    else if (alpha >= 0 && alpha <= 9) {
      lcd.print(alpha);
      lcd.print(" deg   ");  // three spaces after
    }
    // between 10 and 99 two digits are assigned
    else if (alpha >= 10 && alpha <= 99) {
      lcd.print(alpha);
      lcd.print(" deg  ");  // two spaces after
    }
    // between 100 and 179 three digits are assigned
    else if (alpha >= 100 && alpha <= 179) {
      lcd.print(alpha);
      lcd.print(" deg ");  // one spaces after
    }
    // out of -179,+179 the servo cannot rotate
    else {
      lcd.home();
      lcd.print("Error: signal");
      lcd.setCursor(0,1);
      lcd.print("out of range.");
      delay(1000);
      lcd.clear();
    }
  }
}

Schematics

Breadboard view
Breadboard connections for the Servo Control Panel. The S button serves to change the sign of the angle shown on the LCD screen. The A button commutes between manual control and auto-sweep. The Z button set the actual servo angle as zero. The servo knob controls the servo angle in manual mode and rotation rate in auto-sweep mode.
Angleattackcontrolpanel bb ydjhwkp6pt

Comments

Similar projects you might like

Servo Control with TV Remote Control

Project showcase by eldo85

  • 5,591 views
  • 5 comments
  • 17 respects

MKR1000 Servo Control Panel

Project tutorial by Scott Beasley

  • 3,927 views
  • 3 comments
  • 18 respects

Servo-Controlled, Light-Tracking Solar Panel Platform

Project tutorial by scott mangiacotti

  • 12,449 views
  • 10 comments
  • 41 respects

Dual Axis Solar Tracker Panel with Auto and Manual Mode

Project tutorial by Giannis Arvanitakis

  • 7,154 views
  • 6 comments
  • 35 respects
Add projectSign up / Login