Saturday, August 2, 2014

Fly By Wire

So far the Arduino posts have been pretty useless. Nothing really about airplanes or anything useful. This post is going to have some meat. It will include input and output. This will be something that could be used as a fly by wire system, but shouldn't be used for anything critical since it has no redundancy.



The real world is mostly analog. Sometimes it would be easier if it was binary (on/off) but mostly it is not quite on, or not quite off. It may seem like a big leap to go from blinking lights to reading analog inputs, but that is the great thing about Arduino. It is very easy to read analog devices.

Radio Shack sells potentiometers that will work as an analog input. There are other sources, Radio Shack is sometimes more handy. The potentiometer is really a variable resistor. A good choice is the 10K potentiometer, linear taper. Linear taper means when the wiper is moved the value will change a linear amount. For this application almost any scavenged potentiometer would work.

If one side of the resistor is connected to +5V, then the wiper can be connected to one of the analog inputs of the board. The standard Arduino library has a function:

   analogRead()

that will read the analog input and convert that to a value between 0 and 1023.

A simple test will turn on the light when the potentiometer is turned past half way. Any value could be used depending on application. The setup() function will be identical to the blink sketch, since it will use the LED light as the blink sketch did. There is a new variable "pot" shortened potentiometer, set to 3, meaning analog pin 3.


/*
 Analog Demo
 
 Turn on the LED when a potentiometer is turned past 
 half way, and turn it off when turned the other way 
 past half way
 
 This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// Analog pin 3 will be connected to potentiometer
// its name is shortened
int pot = 3; 

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  int val;
  
  val = analogRead(pot);
  
  if (val > 511) {
    digitalWrite(led, HIGH); 
  } else {
    digitalWrite(led, LOW);
  }
 
} 


The loop() function has many new concepts from the Blink sketch. There is a function variable "val" used to hold the analog value read. This function variable exists only in the loop() function, it cannot be read or set in the setup() function. It is perfect for this application, since the loop() function is the only place that will care what the last value read was, and it may change between reads. The value is read immediately in the loop() function the library function analogRead(pot). The "pot" contains the value 3, indicating analog pin 3 is to be read. The value read is compared to 511 (about half of 1023 the max value of analogRead). If the value read is greater than 511 the LED pin is set to HIGH or else the LED pin is set to LOW like in the Blink sketch.

The if() comparison allows comparing many things. The comparison operators on the Arduino library page outlines the comparisons that can be made. The most problematic one will be '=='. The single '=' means set the value, where '==' asks the question, are these the same value? We will get into more comparisons in another post. In this case the comparison checks the value read to see if it is greater than 511. If the value is less than or equal to 511, then the "else" portion of the comparison will happen.


Wiring the potentiometer to the Arduino board will require 3 wires and 3 pins. Some kits will include the potentiometer pre-wired. It is easy to solder 3 wires to the potentiometer. Using something smaller than 20 gauge wire, is preferred, but not required. The 0.1 header snap strips can be bought at most electronic supply sources, surplus stores or Radio Shack. The pins can be "snapped" off individually or in groups. The pins are inserted into the board, in the specified pins.

Logical diagram of a potentiometer
The potentiometer has 3 connections. The two outside connections are either end of the resistor, and the middle is the wiper of the resistor.  If the middle (wiper) connection is plugged into analog pin 3 of the Arduino board, and one side connected to +5V and the other to one of the GND (ground pin) the above sketch should work!.


The Rest of The Story

That isn't flying anything by wire. What the above work did was create a way to put control inputs into a computer. The computer can convert those inputs to other outputs. The if/else statement could have been more complex, and allowed controlling multiple LED lights if there were more LEDs available.

One library that is available for the Arduino is the servo library. The servo library is used to control model type airplane servos. The model airplane servos are controlled by setting a value or angle, and the arm of the servo will move to that location, and hold.  The normal servos are limited to either 90 or 180 degrees of rotation.

The model airplane servos have 3 wires coming out of them. There is a power wire (usually red), a ground wire (brown or black) and a control signal. Most servos have a standard connection order, with power in the middle and ground opposite the control wire. The connectors usually are sockets like the sockets on the Arduino board, so using the wires in the kit with pins on both ends, or soldering pins on both ends of a wire will allow connecting the servo to the Arduino.


Connecting the ground wire to a GND pin on the Arduino, and the power to the +5V will give the server power it needs to turn. Connecting the signal wire to pin 10 will match the sketch.

/*

FlyByWire

 Convert potentiometer position to servo position

 This example code is in the public domain.
*/

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 


// Pin 10 has a servo connected.
// give it a name:
int servo = 10;

// Analog pin 3 will be connected to potentiometer
// its name is shortened
int pot = 3; 
 
void setup() 
{ 
  myservo.attach(servo);  // attaches the servo on pin 10 to the servo object 
} 
 
 
void loop() 
{ 
  int val;
  
  val = analogRead(pot);          // Read the potentiometer position 
  
  pos = map(val, 0, 1023, 0, 180); // change potentionmeter range to servo range
 
  myservo.write(pos);             // tell servo to go to position in variable 'pos' 
    
} 


This sketch shows something new at the top. The

  #include <Servo.h>

Tells the sketch compiler to go find the servo library, and build that code into the results sent to the Arduino board. The standard Arduino library is included automatically. The Servo code may not be needed for all applications, so it is included only in the applications that need servo code to save space. the Sketch menu in the sketch editor has an "import library" selection allowing adding various libraries to an application. Including unnecessary libraries will slow loading sketches to the Arduino at a minimum, and may prevent the sketch from fitting in the memory of the Arduino.

The servo library tries to be "Object Oriented". Object oriented is a programing concept where an object knows how to operate itself. The setup() function creates the myServo object, and attaches the servo to it. For this sketch, the servo is connected to pin 10.

The loop() function reads the potentiometer as above. One new function introduced here is:

   map(val, inMin, inMax, outMin, outMax)

Map is used to map one range to another range. The servo range, is from 0 degrees to 180, and that is the output position. The potentiometer range is 0 to 1023. The value input is converted from the input range, and converted to the output range. As an example, if the potentiometer is set to the mid range (about 511), the map will convert to the middle of the servo range, half way between 0 and 180 (about 90).



Wiring the servo and the potentiometer can be done. The potentiometer can be connected to the +3, and the servo must be connected to the +5V pins. Unfortunately some servos use more power than can be delivered on the USB port, so the board must be powered by a wall ward, or other external power supply to make this sketch run smoothly. Any adapter that has 12V out on the center contact, and delivers more than 1000ma (or 1A) will work great.

When this is run, the potentiometer could be hooked to a throttle knob, and the servo could be hooked to the throttle setting on a carburetor to act as a remote control for the throttle. Using something like this can eliminate complex mechanical linkages. Changing the map values could allow less movement in the throttle being translated into more movement of the servo. 

This post is probably not totally clear, but as we go, I will explain more about how all this works, and ways to connect more inputs and outputs to your Arduino. I will explain more about the various voltages, and how the electricity flows through things.

If something isn't clear, please let me know.






No comments:

Post a Comment