Hi fellow wiki editors!

To help newly registered users get more familiar with the wiki (and maybe older users too) there is now a {{Welcome to the wiki}} template. Have a look at it and feel free to add it to new users discussion pages (and perhaps your own).

I have tried to keep the template short, but meaningful. /Johan G

Difference between revisions of "Howto:Use Arduino with FlightGear"

From FlightGear wiki
Jump to: navigation, search
m (External links)
Line 1: Line 1:
[[File:Arduinofgfs.jpg|thumb|270px|Arduino LCD panel displaying speed, heading and altitude.]]
 
'''Arduino''' is an open-source electronics prototyping platform based on flexible, easy-to-use [[:Category:Hardware|hardware]] (consisting of a board designed around an 8-bit or a 32-bit microcontroller) and software (based on an integrated development environment (IDE)).
 
[[FlightGear]]'s IO interface allows easy development of hardware that can improve the immersion and realism of the simulation. The output [[Generic protocol|protocols]] allow hardware to response to simulation data (like shown in the image on the right), while the input protocol allows FlightGear to reply to hardware events (eg. on the press of a button).
 
  
 +
'''[http://www.arduino.cc/ Arduino]''' is an open-source electronics prototyping platform based on flexible, easy-to-use [[:Category:Hardware|hardware]] (consisting of a board designed around an 8-bit or a 32-bit microcontroller) and software [http://arduino.cc/en/main/software Arduino IDE]).
 +
[[FlightGear]]'s IO interface allows easy development of hardware that can improve the immersion and realism of the simulation. The output [[Generic protocol|protocols]] allow hardware to response to simulation data, while the input protocol allows FlightGear to reply to hardware events (eg. on the press of a button).
 +
 +
==How to: Control Flightgear with Arduino==
 +
 +
With this "how to", you are able to do a switch and a potentiometer interface to control Flightgears properties such as aileron, elevator, gears, lights, fuel valve, etc.
 +
 +
===Equipment and software===
 +
 +
This example uses following components and software:
 +
*FlightGear 3.2
 +
*[[FlightGear_Launch_Control|Flightgear Launch Control]] (program to make FlightGear start without terminal command and options)
 +
*Arduino UNO
 +
*Linux (Ubuntu 14.04)
 +
*on/off switch
 +
*potentiometer
 +
*Flightgears Cessna 172P Skyhawk
 +
 +
===Input protocol file===
 +
 +
Input protocol file is used to specify how serial information is read by Flightgear. In Ubuntu protocol files are found in:
 +
"/usr/share/games/flightgear/protocol" directory.
 +
 +
====Protocol file structure====
 +
 +
Create controltest.xml file to your protocol folder and paste code from below to it.
 +
 +
<?xml version="1.0"?>
 +
<PropertyList>
 +
<generic>
 +
  <input>
 +
 
 +
  <line_separator>\n</line_separator>
 +
  <var_separator>,</var_separator>
 +
 
 +
  <chunk>
 +
    <name>Strobe</name>
 +
    <node>/controls/lighting/strobe</node>
 +
    <type>bool</type>
 +
  </chunk>
 +
 
 +
  <chunk>
 +
    <name>Throttle</name>
 +
    <node>/controls/engines/engine/throttle</node>
 +
    <type>float</type>
 +
  </chunk>
 +
 +
  </input>
 +
  </generic>
 +
</PropertyList>
 +
</code>
 +
 +
Explanation of lines:
 +
 +
*Line separator: "line_separator" is used to tell Flightgear that a line of commands is at end and new one is starting. In this example file its "/n" and it means new line.
 +
*Variable separator: "variable_separator" is used to tell Flightgear that another variable is after this mark. In this protocol file it's ",".
 +
*Chunk: "chunk" is to specify area for one variable and it's information.
 +
*Name: "name" is used only for identifying variable so it can be anything.
 +
*Node: "node" is an address to tell what property in Flightgear is changed. In this example it is "/controls/lighting/strobe" and "controls/engines/engine/throttle".
 +
*Type: "type" line tells what kind of command is send. In this example it is a "bool" and that means a boolean type of property of a "float" for float.
 +
 +
For a better explanation of configuration file, read [[Generic_protocol|Generic Protocol]] wiki page. You can find a list of properties that can be controlled from a Flightgears docs-folder a file called "README.properties". Or you can use [[Property_browser|Flightgears Property Browser]] from main menu: Debug > Browse Internal Properties. Properties in protocol file needs to be in same order as they are send from Arduino.
 +
 +
===Wiring and coding Arduino===
 +
 +
====Wiring====
 +
Potentiometer is connected to Arduinos ground and +5 volts. Potentiometers middle connector is connected to A0 analoq input. Switch is connected to ground with 10 kOhms pull-down resistor and +5 and digital pin 7.
 +
[[File:Arduino switch and potentiometer wiring.png|frame|none|Wiring schematic for connecting potentiometer and switch to Arduino]]
 +
 +
====Code====
 +
Copy this code to Arduino IDE and send it to Arduino Uno:
 +
 +
    /*
 +
      FGFS Input Test
 +
      Reads a digital input on pin 7, prints the result to the serial port.
 +
      Reads a potentiometer input on A0 and print result to serial port.
 +
      This example code is in the public domain.
 +
    */
 +
 +
    int potPin = 0;      // potentiometer on A0
 +
    int switchPin = 7;    // switch on pin 7
 +
    float potValue = 0;  // float variable to store potentiometer value
 +
 +
    void setup() {
 +
    Serial.begin(9600);          // open serial connection
 +
    pinMode(switchPin, INPUT);  // pin 7 declared as input
 +
    }
 +
       
 +
       
 +
    void loop() {
 +
 +
    Serial.print(digitalRead(switchPin));  // read and print switch state
 +
    Serial.print(",");                      // print ,
 +
    potValue = analogRead(potPin);          // read potentiometer and store it to potValue
 +
    potValue = potValue / 1024;            // divide potValue with 1024 to make it between 0 and 1
 +
    PrintDouble(potValue, 2);              // pass potValue to PrintDouble-function, read from below what magic happens
 +
    Serial.print("\n");                    // print new line
 +
    delay(500);                            // delay only for making this guide easier to follow on serial monitor
 +
 +
    }
 +
 +
 +
    void PrintDouble(double val, byte precision){
 +
      // prints val with number of decimal places determine by precision
 +
      // precision is a number from 0 to 6 indicating the desired decimial places
 +
      // example: lcdPrintDouble( 3.1415, 2); // prints 3.14 (two decimal places)
 +
      // From http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548
 +
   
 +
      if(val < 0.0){
 +
        Serial.print('-');
 +
        val = -val;
 +
      }
 +
 +
      Serial.print (int(val));  //prints the int part
 +
      if( precision > 0) {
 +
        Serial.print("."); // print the decimal point
 +
        unsigned long frac;
 +
        unsigned long mult = 1;
 +
        byte padding = precision -1;
 +
        while(precision--)
 +
      mult *=10;
 +
 +
        if(val >= 0)
 +
    frac = (val - int(val)) * mult;
 +
        else
 +
    frac = (int(val)- val ) * mult;
 +
        unsigned long frac1 = frac;
 +
        while( frac1 /= 10 )
 +
    padding--;
 +
        while(  padding--)
 +
    Serial.print("0");
 +
        Serial.print(frac,DEC) ;
 +
      }
 +
    }
 +
 +
====Test serial output====
 +
 +
Use Arduino IDEs serial monitor and you should see something like this:
 +
[[File:Flightgear arduino serial monitor.png|frame|none|Arduino IDEs serial monitor output]]
 +
 +
First number is switch data, so it's either 0 (switch off) or 1 (switch on). After "," mark is our throttle data. First it's 0.00 meaning idle throttle and then potentiometer is gradually turned until it reaches 0.99.
 +
 +
'''NOTE!''' Remember to '''unplug Arduino's USB cable and plug it back''' in because Flightgear won't be able to read serial without doing this! You have to do this every time after you use Arduino IDE.
 +
 +
====Start Flightgear====
 +
 +
Flightgear needs to be started with a correct command line option for it to be able to read serial connection. This example uses following option:
 +
--generic=serial,in,30,/dev/ttyACM0,controltest
 +
 +
If you like, you can use graphical user interface, Flightgear Launch Control (aka FGRun), to launch Flightgear. Select correct settings from Advanced Option tab. [[File:Starting Flightgear with input options enabled.jpg|thumb|none|Starting Flightgear with FGLaunch Control, selecting input/output options]]
 +
 +
If you don't now your correct port, you can check it with a following command in terminal: dmesg | tail. It should give you a message something like: "ttyACM0: USB ACM device" or "ttyACM1: USB ACM device". That's your port. Finally save setting by clicking 'OK' and click 'Run' to start flightgear. For more detailed guide, see [https://sites.google.com/site/flightgeararduinoandlinux/home Flightgear, Arduino and Linux]
 +
 +
 +
[[File:Arduinofgfs.jpg|thumb|270px|Arduino LCD panel displaying speed, heading and altitude.]]
 
== Display/Generic protocol Example by rubdos ==
 
== Display/Generic protocol Example by rubdos ==
  

Revision as of 09:54, 9 February 2015

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware (consisting of a board designed around an 8-bit or a 32-bit microcontroller) and software Arduino IDE). FlightGear's IO interface allows easy development of hardware that can improve the immersion and realism of the simulation. The output protocols allow hardware to response to simulation data, while the input protocol allows FlightGear to reply to hardware events (eg. on the press of a button).

How to: Control Flightgear with Arduino

With this "how to", you are able to do a switch and a potentiometer interface to control Flightgears properties such as aileron, elevator, gears, lights, fuel valve, etc.

Equipment and software

This example uses following components and software:

  • FlightGear 3.2
  • Flightgear Launch Control (program to make FlightGear start without terminal command and options)
  • Arduino UNO
  • Linux (Ubuntu 14.04)
  • on/off switch
  • potentiometer
  • Flightgears Cessna 172P Skyhawk

Input protocol file

Input protocol file is used to specify how serial information is read by Flightgear. In Ubuntu protocol files are found in: "/usr/share/games/flightgear/protocol" directory.

Protocol file structure

Create controltest.xml file to your protocol folder and paste code from below to it.

<?xml version="1.0"?>
<PropertyList>
<generic>
 <input>
  
  <line_separator>\n</line_separator>
  <var_separator>,</var_separator>
  
  <chunk>
   <name>Strobe</name>
   <node>/controls/lighting/strobe</node>
   <type>bool</type>
  </chunk>
  
  <chunk>
   <name>Throttle</name>
   <node>/controls/engines/engine/throttle</node>
   <type>float</type>
  </chunk>

 </input>
 </generic>
</PropertyList>

Explanation of lines:

  • Line separator: "line_separator" is used to tell Flightgear that a line of commands is at end and new one is starting. In this example file its "/n" and it means new line.
  • Variable separator: "variable_separator" is used to tell Flightgear that another variable is after this mark. In this protocol file it's ",".
  • Chunk: "chunk" is to specify area for one variable and it's information.
  • Name: "name" is used only for identifying variable so it can be anything.
  • Node: "node" is an address to tell what property in Flightgear is changed. In this example it is "/controls/lighting/strobe" and "controls/engines/engine/throttle".
  • Type: "type" line tells what kind of command is send. In this example it is a "bool" and that means a boolean type of property of a "float" for float.

For a better explanation of configuration file, read Generic Protocol wiki page. You can find a list of properties that can be controlled from a Flightgears docs-folder a file called "README.properties". Or you can use Flightgears Property Browser from main menu: Debug > Browse Internal Properties. Properties in protocol file needs to be in same order as they are send from Arduino.

Wiring and coding Arduino

Wiring

Potentiometer is connected to Arduinos ground and +5 volts. Potentiometers middle connector is connected to A0 analoq input. Switch is connected to ground with 10 kOhms pull-down resistor and +5 and digital pin 7.

Wiring schematic for connecting potentiometer and switch to Arduino

Code

Copy this code to Arduino IDE and send it to Arduino Uno:

   /*
     FGFS Input Test
     Reads a digital input on pin 7, prints the result to the serial port.
     Reads a potentiometer input on A0 and print result to serial port.
     This example code is in the public domain.
   */

   int potPin = 0;       // potentiometer on A0
   int switchPin = 7;    // switch on pin 7
   float potValue = 0;   // float variable to store potentiometer value

   void setup() {
   Serial.begin(9600);          // open serial connection
   pinMode(switchPin, INPUT);   // pin 7 declared as input
   }
       
        
   void loop() {

   Serial.print(digitalRead(switchPin));   // read and print switch state
   Serial.print(",");                      // print ,
   potValue = analogRead(potPin);          // read potentiometer and store it to potValue
   potValue = potValue / 1024;             // divide potValue with 1024 to make it between 0 and 1
   PrintDouble(potValue, 2);               // pass potValue to PrintDouble-function, read from below what magic happens
   Serial.print("\n");                     // print new line
   delay(500);                             // delay only for making this guide easier to follow on serial monitor

   }


   void PrintDouble(double val, byte precision){
     // prints val with number of decimal places determine by precision
     // precision is a number from 0 to 6 indicating the desired decimial places
     // example: lcdPrintDouble( 3.1415, 2); // prints 3.14 (two decimal places)
     // From http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548
    
     if(val < 0.0){
       Serial.print('-');
       val = -val;
     }

     Serial.print (int(val));  //prints the int part
     if( precision > 0) {
       Serial.print("."); // print the decimal point
       unsigned long frac;
       unsigned long mult = 1;
       byte padding = precision -1;
       while(precision--)
     mult *=10;

       if(val >= 0)
    frac = (val - int(val)) * mult;
       else
    frac = (int(val)- val ) * mult;
       unsigned long frac1 = frac;
       while( frac1 /= 10 )
    padding--;
       while(  padding--)
    Serial.print("0");
       Serial.print(frac,DEC) ;
     }
   }

Test serial output

Use Arduino IDEs serial monitor and you should see something like this:

Arduino IDEs serial monitor output

First number is switch data, so it's either 0 (switch off) or 1 (switch on). After "," mark is our throttle data. First it's 0.00 meaning idle throttle and then potentiometer is gradually turned until it reaches 0.99.

NOTE! Remember to unplug Arduino's USB cable and plug it back in because Flightgear won't be able to read serial without doing this! You have to do this every time after you use Arduino IDE.

Start Flightgear

Flightgear needs to be started with a correct command line option for it to be able to read serial connection. This example uses following option:

--generic=serial,in,30,/dev/ttyACM0,controltest
If you like, you can use graphical user interface, Flightgear Launch Control (aka FGRun), to launch Flightgear. Select correct settings from Advanced Option tab.
Starting Flightgear with FGLaunch Control, selecting input/output options

If you don't now your correct port, you can check it with a following command in terminal: dmesg | tail. It should give you a message something like: "ttyACM0: USB ACM device" or "ttyACM1: USB ACM device". That's your port. Finally save setting by clicking 'OK' and click 'Run' to start flightgear. For more detailed guide, see Flightgear, Arduino and Linux


Arduino LCD panel displaying speed, heading and altitude.

Display/Generic protocol Example by rubdos

Rubdos (Ruben De Smet) has built an example using the Generic Protocol and an Arduino Mega 2560. The code used to control the Arduino with generic protocol was:

<?xml version="1.0"?>
<PropertyList>
   <generic>
       <output>
           <binary_mode>false</binary_mode>
           <line_separator>newline</line_separator>
           <var_separator>newline</var_separator>
           <preamble></preamble>
           <postamble></postamble>
           <chunk>
               <name>Altitude</name>
               <node>/position/altitude-ft</node>
               <type>integer</type>
               <format>altitude=%i</format>
           </chunk>
           <chunk>
               <name>RPM</name>
               <node>/engines/engine/rpm</node>
               <type>integer</type>
               <format>rpm=%i</format>
           </chunk>
       </output>
   </generic>
</PropertyList>

It is a simple plaintext protocol, which can easily be parsed by an Arduino. The code used on the Arduino is available on github as a gist: [1]

As hardware, five seven segment displays were used, multiplexed straight on the Arduino device. In production, you'd rather use some 74HC595 or other shift register chips to drive them, to unload the Arduino and have more current. A demo is uploaded to youtube, with voiceover in which the display shows the RPM of the first engine of (the single engine) DR400: [2]

Related content

External links