Howto:Use Arduino with FlightGear: Difference between revisions

Finish cleanup
(More cleanup)
(Finish cleanup)
Line 139: Line 139:
You have to do this every time after you use the Arduino IDE.}}
You have to do this every time after you use the Arduino IDE.}}


==== Start FlightGear ====
==== Starting FlightGear ====
 
===== Method 1: Command line =====
===== Method 1: Command line =====
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:
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:
<syntaxhighlight>
<syntaxhighlight>
--generic=serial,in,30,/dev/ttyACM0,controltest
--generic=serial,in,30,/dev/ttyACM0,controltest
</syntaxhighlight>
</syntaxhighlight>


===== Method 2: FGRun =====
===== Method 2: FGRun =====
Alternatively, you can use FlightGear's graphical user interface (FGRun) to launch Flightgear. Select the correct settings from Advanced Option tab. [[File:Starting Flightgear with input options enabled.jpg|thumb|none|Starting Flightgear with FGRun, selecting input/output options]]
Alternatively, you can use FlightGear's graphical user interface (FGRun) to launch FlightGear. See the image below for the correct settings.
[[File:Starting Flightgear with input options enabled.jpg|thumb|none|Starting Flightgear with FGRun, selecting input/output options]]


If you don't know 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 a more detailed guide, see [https://sites.google.com/site/flightgeararduinoandlinux/home Flightgear, Arduino and Linux]
If you don't know your correct port is , you can check it with a following command in terminal:
<syntaxhighlight>
dmesg | tail
</syntaxhighlight>
It should give you a message something like <code>ttyACM0: USB ACM device</code> or <code>ttyACM1: USB ACM device</code>. That is your port. Finally, save setting by clicking "OK" and click "Run" to start FlightGear. For a more detailed guide, see [https://sites.google.com/site/flightgeararduinoandlinux/home Flightgear, Arduino and Linux]


== Example 2: Outputting properties ==
<big>By {{usr|Rubdos}}</big>
[[File:Arduinofgfs.jpg|thumb|270px|Arduino LCD panel displaying speed, heading and altitude.]]
[[File:Arduinofgfs.jpg|thumb|270px|Arduino LCD panel displaying speed, heading and altitude.]]
== Example ==
This example uses the example using the [[Generic protocol]] and an [http://arduino.cc/en/Main/arduinoBoardMega2560 Arduino Mega 2560].
{{usr|Rubdos}} (Ruben De Smet) has built an example using the [[generic protocol]] and an Arduino Mega 2560.
Below is the protocol XML file used to control the Arduino.
The code used to control the Arduino with generic protocol was:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<?xml version="1.0"?>
<?xml version="1.0"?>
Line 195: Line 202:
</PropertyList>
</PropertyList>
</syntaxhighlight>
</syntaxhighlight>
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: [https://gist.github.com/rubdos/5422870]


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.
Below is the C code used for the example, taken from https://gist.github.com/rubdos/5422870.
A demo is uploaded to youtube, with voiceover in which the display shows the RPM of the first engine of (the single engine) [[DR400]]: [https://www.youtube.com/watch?v=lVtV9-CgqBo]
<syntaxhighlight lang="c">
//PIN 0 -> 7 has positive segment part
 
// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);   
  pinMode(5, OUTPUT);   
  pinMode(6, OUTPUT);   
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);     
  pinMode(9, OUTPUT);   
 
  pinMode(49, OUTPUT); 
  pinMode(50, OUTPUT);
  pinMode(51, OUTPUT);
  pinMode(52, OUTPUT);
  pinMode(53, OUTPUT);
 
  Serial.begin(9600);
}
 
void writeNumber(int nr)
{
  if(nr == 0)
  {
    digitalWrite(2, LOW); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, HIGH); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 1)
  {
    digitalWrite(2, LOW); // midden
    digitalWrite(3, LOW); // lt
    digitalWrite(4, LOW); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, LOW); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 2)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, LOW); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, HIGH); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, LOW); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 3)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, LOW); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 4)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, LOW); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, LOW); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 5)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, LOW); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 6)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, LOW); // rt
    digitalWrite(6, HIGH); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 7)
  {
    digitalWrite(2, LOW); // midden
    digitalWrite(3, LOW); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, LOW); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 8)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, HIGH); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else if(nr == 9)
  {
    digitalWrite(2, HIGH); // midden
    digitalWrite(3, HIGH); // lt
    digitalWrite(4, HIGH); // t
    digitalWrite(5, HIGH); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, HIGH); // b
    digitalWrite(8, HIGH); // rb
    digitalWrite(9, LOW); // dot
  }
  else
  {
    digitalWrite(2, LOW); // midden
    digitalWrite(3, LOW); // lt
    digitalWrite(4, LOW); // t
    digitalWrite(5, LOW); // rt
    digitalWrite(6, LOW); // lb
    digitalWrite(7, LOW); // b
    digitalWrite(8, LOW); // rb
    digitalWrite(9, LOW); // dot
  }
}
 
// the loop routine runs over and over again forever
long number = 0;
int decimals[5] = {0, 0, 0, 0, 0};
 
void loop() {
  for(int i = 49; i < 54; i++)
  {
    // Disable the incorrect segment displays
    if(i == 49)
    {
      digitalWrite(53, HIGH);
    }
    else
    {
      digitalWrite(i - 1, HIGH);
    }
    digitalWrite(i, LOW);
   
    // Enable the segments
    writeNumber(decimals[4 - (i - 49)]);
    delay(1);
  }
  if(Serial.available() > 14) // Wait until there are two bytes available. Then read them out.
  {
    String command;
    String var;
    char lastchar;
 
    while(lastchar != '=')
    {
      lastchar = Serial.read();
      if(lastchar != '=')
      {
        command += lastchar;
      }
    }
    while(lastchar != '\n')
    {
      lastchar = Serial.read();
      if(lastchar != '\n')
      {
        var += lastchar;
      }
    }
   
    if(command == "altitude" )
    {
      char buf[50];
      var.toCharArray(buf, 50);
      number = atol(buf);
    }
   
    /*if(number == 10000)
    {
      number = 0;
    }*/
   
    long currentnumber = number;
   
    int remainder = currentnumber % 10;
    currentnumber =  (currentnumber - remainder) / 10;
    decimals[4] = remainder;
   
    remainder = currentnumber % 10;
    currentnumber =  (currentnumber - remainder) / 10;
    decimals[3] = remainder;
       
    remainder = currentnumber % 10;
    currentnumber =  (currentnumber - remainder) / 10;
    decimals[2] = remainder;
           
    remainder = currentnumber % 10;
    currentnumber =  (currentnumber - remainder) / 10;
    decimals[1] = remainder;
           
    remainder = currentnumber % 10;
    currentnumber =  (currentnumber - remainder) / 10;
    decimals[0] = remainder;
  }
}
</syntaxhighlight>
 
The hardware used was five seven-segment displays, multiplexed straight on the Arduino device. Ideally, you'd rather use some 74HC595 or other shift register chips to drive them, to unload the Arduino and have more current.
 
Below is a demo uploaded to YouTube, with voiceover in which the display shows the RPM of [[Robin DR400]]'s single engine.
{{#ev:youtube|lVtV9-CgqBo}}


== Related content ==
== Related content ==
Line 204: Line 444:


== External links ==
== External links ==
* [http://arduino.cc/ Official website]
* [http://arduino.cc/ Official Arduino website]
* [http://playground.arduino.cc/Main/FlightGear FlightGear Serial Communications with Arduino] (tutorial)
* [http://playground.arduino.cc/Main/FlightGear FlightGear Serial Communications with Arduino] (tutorial)
* [http://forum.flightgear.org/viewtopic.php?f=18&t=11126 Arduino LCD and FlightGear] (FlightGear forum)
* [http://forum.flightgear.org/viewtopic.php?f=18&t=11126 Arduino LCD and FlightGear] (FlightGear forum)