Devices & Components
Arduino Uno Rev3
Resistor 221 ohm
Rotary potentiometer (generic)
Pushbutton switch 12mm
Breadboard (generic)
Capacitor 100 µF
Servos (Tower Pro MG996R)
Resistor 10k ohm
Standard LCD - 16x2 White on Blue
Software & Tools
Arduino IDE
Project description
Code
angleAttackControlPanel.ino
arduino
1// Panel to control a servo rotation and read angle on a LCD display, 2// with the possibility to set a reference angle and read values 3// from that reference. Useful to get the deflection angle of a 4// control surface from a datum. Once set a reference angle, to get 5// again the absolute position of the servo, just reset the Arduino. 6// There is also the possibility to perform an automatic sweep 7// between two given angles, from a given reference, and to change 8// the rotational speed of the servo, by adjusting the delay between 9// successive angles. 10// 11// Made by Danilo Ciliberti on 9th December 2017 12 13#include <LiquidCrystal.h> 14#include <Servo.h> 15LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 16Servo myServo; 17 18int const signPin = 6; // button to switch sign of the angle 19int const sweepPin = 7; // button to turn auto angle sweep on/off 20int const zeroPin = 8; // button to set reference 21int const pot = A0; // potentiometer that controls angle/rate 22int potVal; // value of the angle/rate 23int angle; // angle of the servo 24int rotDelay; // speed of the servo (delay between angles) 25int zero = 0; // reference angle of attack 26int signSwitch = 1; // sign of the angle (positive or negative) 27int alpha; // angle of attack 28int sweepState = 0; // auto sweep state (on/off) 29int lowLimit = -30; // low angle limit for auto sweep 30int highLimit = 60; // high angle limit for auto sweep 31int newLowLimit; // low limit angle from the zero 32int newHighLimit; // high limit angle from the zero 33 34void setup() { 35 pinMode(zeroPin, INPUT); 36 pinMode(signPin, INPUT); 37 38 lcd.begin(16, 2); 39 lcd.print("Angle of attack"); 40 lcd.setCursor(0, 1); 41 lcd.print("control panel"); 42 delay(3000); 43 lcd.clear(); 44 45 myServo.attach(9); // servo is attached to pin 9 46 Serial.begin(9600); 47} 48 49void loop() { 50 51 // if the zero button is pressed the angle of attack is set to 0 52 if (digitalRead(zeroPin) == HIGH) { 53 zero = angle; 54 // centers the auto sweep limits around the new zero 55 newLowLimit = lowLimit + zero; 56 newHighLimit = highLimit + zero; 57 Serial.print("Setting low angle limit: "); 58 Serial.println(newLowLimit); 59 Serial.print("Setting high angle limit: "); 60 Serial.println(newHighLimit); 61 delay(100); 62 } 63 64 // if the sign button is pressed changes the sign of the angle 65 if (digitalRead(signPin) == HIGH) { 66 signSwitch = -1 * signSwitch; 67 delay(100); 68 } 69 70 alpha = signSwitch * (angle - zero); // angle of attack respect to reference 71 72 // check if auto sweep button has been pressed 73 if (digitalRead(sweepPin) == HIGH) { 74 sweepState = 1; 75 Serial.print("Auto sweep state = "); 76 Serial.println(sweepState); 77 lcd.clear(); 78 delay(100); 79 } 80 81 // turn on auto sweep if auto sweep button has been pressed 82 if (sweepState == 1) { 83 84 // check if alpha range is out of servo range 85 if (newLowLimit < 0 || newLowLimit > 179) { 86 newLowLimit = 0; 87 Serial.print("Actual low angle limit: "); 88 Serial.println(newLowLimit); 89 } 90 if (newHighLimit > 179 || newHighLimit < 0) { 91 newHighLimit = 179; 92 Serial.print("Actual high angle limit: "); 93 Serial.println(newHighLimit); 94 } 95 96 // if auto sweep button has been released 97 if (digitalRead(sweepPin) == LOW) { 98 99 lcd.home(); 100 lcd.print(lowLimit); 101 lcd.print(" < AOA < "); 102 lcd.print(highLimit); 103 lcd.setCursor(0, 1); 104 lcd.print("Auto sweep ON"); 105 106 // check the angle sign to assign correct sweep angles sequence 107 if (signSwitch == 1) { 108 angle = zero + alpha; 109 } 110 else { 111 angle = zero - alpha; 112 newHighLimit = -lowLimit + zero; 113 newLowLimit = -highLimit + zero; 114 } 115 116 while (angle < newHighLimit) { 117 // assign delay between angles, varying servo rotational speed 118 potVal = analogRead(pot); 119 Serial.print("potVal: "); 120 Serial.print(potVal); 121 rotDelay = map(potVal, 0, 1023, 15, 100); 122 Serial.print(", rotDelay: "); 123 Serial.print(rotDelay); 124 Serial.println(" ms"); 125 myServo.write(angle); 126 delay(rotDelay); 127 128 // if during loop auto sweep button is pressed exit the loop 129 if (digitalRead(sweepPin) == HIGH) { 130 sweepState = 0; 131 Serial.print("Auto sweep state = "); 132 Serial.println(sweepState); 133 lcd.clear(); 134 delay(100); 135 goto manual; 136 } 137 angle++; 138 } 139 140 while (angle > newLowLimit) { 141 // assign delay between angles, varying servo rotational speed 142 potVal = analogRead(pot); 143 Serial.print("potVal: "); 144 Serial.print(potVal); 145 rotDelay = map(potVal, 0, 1023, 15, 100); 146 Serial.print(", rotDelay: "); 147 Serial.print(rotDelay); 148 Serial.println(" ms"); 149 myServo.write(angle); 150 delay(rotDelay); 151 152 // if during loop auto sweep button is pressed exit the loop 153 if (digitalRead(sweepPin) == HIGH) { 154 sweepState = 0; 155 Serial.print("Auto sweep state = "); 156 Serial.println(sweepState); 157 lcd.clear(); 158 delay(100); 159 goto manual; 160 } 161 angle--; 162 } 163 164 } 165 } 166 else { // if auto sweep is turned off 167 manual: // label destination of interrupted loop 168 lcd.setCursor(0, 1); 169 lcd.print("Manual control"); 170 171 potVal = analogRead(pot); 172 Serial.print("potVal: "); 173 Serial.print(potVal); 174 angle = map(potVal, 0, 1023, 0, 179); 175 Serial.print(", angle: "); 176 Serial.print(angle); 177 myServo.write(angle); 178 delay(15); 179 Serial.print(", zero: "); 180 Serial.print(zero); 181 Serial.print(", AOA: "); 182 Serial.println(alpha); 183 184 lcd.home(); 185 lcd.print("AOA = "); 186 // To avoid overlapping text among readings I must use blank 187 // characters (space) when needed over the four predicted positions. 188 189 // between -179 and -100 four digits are assigned 190 if (alpha >= -179 && alpha <= -100) { 191 lcd.print(alpha); 192 lcd.print(" deg"); // no space after 193 } 194 // between -99 and -10 three digits are assigned 195 else if (alpha >= -99 && alpha <= -10) { 196 lcd.print(alpha); 197 lcd.print(" deg "); // one space after 198 } 199 // between -9 and -1 two digits are assigned 200 else if (alpha >= -9 && alpha <= -1) { 201 lcd.print(alpha); 202 lcd.print(" deg "); // two spaces after 203 } 204 // between 0 and 9 only one digit is assigned 205 else if (alpha >= 0 && alpha <= 9) { 206 lcd.print(alpha); 207 lcd.print(" deg "); // three spaces after 208 } 209 // between 10 and 99 two digits are assigned 210 else if (alpha >= 10 && alpha <= 99) { 211 lcd.print(alpha); 212 lcd.print(" deg "); // two spaces after 213 } 214 // between 100 and 179 three digits are assigned 215 else if (alpha >= 100 && alpha <= 179) { 216 lcd.print(alpha); 217 lcd.print(" deg "); // one spaces after 218 } 219 // out of -179,+179 the servo cannot rotate 220 else { 221 lcd.home(); 222 lcd.print("Error: signal"); 223 lcd.setCursor(0,1); 224 lcd.print("out of range."); 225 delay(1000); 226 lcd.clear(); 227 } 228 } 229} 230
Github
Online repository on Github
Github
Online repository on Github
Downloadable files
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.
Breadboard view

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.
Breadboard view

Comments
Only logged in users can leave comments