Serial Output from Flightgear to Arduino

I am trying to make a basic program to get a handle on serial communication with the arduino and Flightgear. I have a Duemilanove and I am trying to read the value for the throttle (for example: a number from 0 to 1). I followed the tutorial for the pushbutton input from Arduino playground Arduino Playground - FlightGearInputPushbutton to figure out the steps for input to flightgear. But now I'm trying to read output from Flightgear to the Arduino and display a number onto a 7-segment digital LED display.

OS: Win7 x64
the command line to start into Flightgear:

T:\FlightGear\bin\Win64\fgfs --fg-root=T:\FlightGear\data --aircraft=c172r --generic=serial,out,30,\\.\COM3,9600,arduino_coms_out --httpd=5400

my protocol is simply:

<?xml version="1.0"?>
<PropertyList>
<generic>
 
   <output>
	<binary_mode>false</binary_mode>
	<line_separator>newline</line_separator>
	<var_separator>,</var_separator>
	<preamble>\n\n</preamble>
   
   <chunk>
    <name>Throttle</name>
    <node>/controls/engines/engine/throttle</node>
    <format>%d</format>
   </chunk>

 </output>
</generic>
</PropertyList>

I am unsure what I would need to read the throttle value. I believe Flightgear sends the value as a string, if so could anyone find sample code to handle the output? I'm guessing throttle = Serial.read(); wouldn't work.
This is what I have so far for arduino code:

/*
  FGFS Slide Potentiometer Input
  Reads the serial port and displays the value to the 7-segment LED display
  
  Displaying throttle on a 7-Segment Red LED (common cathode) numerical display
  RadioShack 276-075 / Wiring 

  arduino pin -> 7-segment LED pin -> anode
   10 -> 14 -> A      --A--  
   11 -> 13 -> B     |     |
  n/a ->  9 -> RHDP  F     B
   12 ->  8 -> C     |     |
    6 ->  7 -> D      --G--
    7 ->  6 -> E     |     |
    8 ->  2 -> G     E     C
    9 ->  1 -> F     |     |
                      --D-- O 
    GND -> 4 (or 12) -> common cathode      
    
-------------------------*/

//        arduino pin:   0 0 0 0 1 1 1    (1
//                       6,7,8,9,0,1,2     1) = 11
//                       D,E,G,F,A,B,C
byte segDigits[10][7] ={{1,1,0,1,1,1,1}, // = 0
                        {0,0,0,0,0,1,1}, // = 1
                        {1,1,1,0,1,1,0}, // = 2
                        {1,0,1,0,1,1,1}, // = 3
                        {0,0,1,1,0,1,1}, // = 4
                        {1,0,1,1,1,0,1}, // = 5
                        {1,1,1,1,1,0,1}, // = 6
                        {0,0,0,0,1,1,1}, // = 7
                        {1,1,1,1,1,1,1}, // = 8
                        {0,0,1,1,1,1,1}, // = 9
                        };
float fg_throttle = 0;

#define A 10
#define B 11
#define C 12
#define D 6
#define E 7
#define F 9
#define G 8

void setup() {
  Serial.begin(9600);
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(F, OUTPUT);
  pinMode(G, OUTPUT);
}

void loop() {

  fg_throttle = Serial.read();         // this doesn't seem to read the value correctly

  // the throttle value ranges from 0 to 1,
  // the 10*fg_throttle makes it a value from 0 to 10 for the 7-seg digital display
  sevenSegWrite((int) 10*fg_throttle);
}

// Function that displays the value obtained from the throttle to the 7-seg LED display
void sevenSegWrite(int digit){
  byte pin = 6;
  for (byte segCount = 0; segCount < 13; ++segCount){
    digitalWrite(pin, segDigits[digit][segCount]);
    ++pin;
  }
}
  fg_throttle = Serial.read();         // this doesn't seem to read the value correctly

The Serial.read() function reads one character/byte from the serial monitor. If you are sending a value between 0 and 1, that code is going to read either a '0' or a '1", which you will see are NOT the same as 0 or 1.

When you multiply '0' (48) or '1' (49) by 10, you get 480 or 490, not a value between 0 and 10. Somehow, I doubt that you can display 480 or 490 on your single digit display.

Oh ok. That makes alot of sense. So ill have to make a function that reads the serial until it reached the comma (,) and return that value.

So ill have to make a function that reads the serial until it reached the comma (,), NULL terminate the array of characters received, convert the string received to an int, and return that value.

Yes.

The scenario is like that:

  • FGFS sends bytes over the serial link, one after another according to your custom protocol definition;
  • Arduino receives them one after another, it doesn't know if they represent floats, strings or whatever, they're plain bytes.

Arduino has to parse the incoming bytes, grouping together the ones that arrive between each variable/line separator and using those variable values according to what you intended Arduino to do with them.

It doesn't matter if FGFS sends the throttle value as a float/string or whatever; over the serial line (as it arrives to Arduino) it's just a plain sequence of bytes.
You have to code Arduino so that it reassembles the bytes together according to what it's expecting on the line (if I remember well, the variables are sent as Little Endian so pay attention to how you reassemble them together).


As a side note to that, I have a request for the more experienced Serial Programmers out there. I am starting coding a testbed on Windows, it's going to talk to Flightgear over a serial line. I'm going to use Code::Blocks/GCC.

Which Serial library would you suggest?

I'm not going to write my own! And I don't seem to find a standard (in the sense of widely accepted and used) Serial C++ Class on Windows. I'd prefer to use GNU/GPL stuff.

.

The examples in serial input basics show a variety of simple reliable ways to receive serial data. There is also a parse example.

...R