PDA

View Full Version : Detecting Link2_FS is connected.



John UK
02-27-2014, 12:24 PM
Hi.

Is there a way to use code on an Arduino to detect that Link2_FS is connected to it?

I have a board that has several switches and LEDs on it, one of which I want to use to indicate that Link2_FS is connected to it such that when I connect Link2_fs to the com port for the board the LED comes on and when I disconnect it, the LED goes out.

I have had some luck with using;

if(serial) ..... but this causes the LED to flash, presumably in time with the refresh time.

I don't even know if I am looking at this in the right way if the truth be told.

Any help would be great!

J.

BuzziBi
02-27-2014, 04:11 PM
For Link2fs to begin communicating with the simulator (through Arduino), you need the code to send or return something.
If the code does not ask for information or send any, you do not get any information.
But I guess this is the purpose with you using Link2fs, to send and receive information to / from the simulator (through Arduino).
And when you start the simulator, you can simply ask for ie. compass heading.
When (if) the compass heading is returned to Link2fs, you can command a led to light up.
If there is no communication, the led will not light up.

John UK
02-28-2014, 04:36 AM
... you can simply ask for ie. compass heading.
...

Thanks, that sounds like it would do what I want. However I cant see how to do it!

BuzziBi
02-28-2014, 09:28 AM
[QUOTEHowever I cant see how to do it![/QUOTE]
I tested this, and it seams to work.
The Led lights up when the connection is established

int CodeIn;// used on all serial reads

String Heading;
int Headingi;
int connection = 13; // The led to check connection.
void setup()
{
pinMode(connection, OUTPUT);

Serial.begin(115200);
}


void loop() {
if (Serial.available()) {
CodeIn = getChar();
if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
}
}


char getChar()// Get a character from the serial buffer
{
while(Serial.available() == 0);// wait for data
return((char)Serial.read());// Thanks Doug
}


void LESSTHAN(){ // The first identifier was "<"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'J'://Found the second identifier "Heading"
Heading = "";
Heading += getChar();
Heading += getChar();
Heading += getChar();
Headingi = Heading.toInt(); // convert it to an integer (Thanks Phill)*/
if (Headingi > 000 ){digitalWrite(13, HIGH);}else{digitalWrite(13, LOW);}
break;
}
}

John UK
02-28-2014, 11:17 AM
[QUOTEHowever I cant see how to do it!
I tested this, and it seams to work.
The Led lights up when the connection is established
[/QUOTE]

Thanks this works just fine for switching on the light. However it stays on when Link2_FS is disconnected.

I guess the way to do this would be to understand the wait time for the data refresh and to put the light out if no data is received in time.

I have the the refresh time set to 5 seconds so I guess I would have to wait 6 seconds before switching off the light. Any ideas? ;)

SteveL
02-28-2014, 05:31 PM
How about extracting "Local FSX time" periodically and comparing the time with the last extraction. If it doesn't update, you are not connected.

BuzziBi
02-28-2014, 06:36 PM
I was thinking of a way to flush the Serial (RX) after "digitalWrite(13, HIGH)"
But have not found the solution yet!

John UK
02-28-2014, 07:20 PM
How about extracting "Local FSX time" periodically and comparing the time with the last extraction. If it doesn't update, you are not connected.

I tried Var1 = millis() and then in the code buzzibee posted for using the lessthan J a second Variable Var2=millis().<j for="" the="" switching="" on="" of="" led="" var2="millis().<j" input="">
I then compared:- if (Var1 > Var2){switch off led} thinking that Var1 would always be less than var2 as it was assigned first in the loop until there was no response from the lessthen J. <j timing...<j="" when="" it="" would="" be="" produced="" later="" than="" the="" last="" instance="" of="" <j's="" timing.
<j.

I couldn't get it to work but then I am new to this.</j.
</j></j>

BuzziBi
03-01-2014, 06:48 PM
Having spent all day trying to find out about this :p (one have to be a bit insane!)
Even posted a question at the Arduino Forum: Can we get a led to light by serial communication? The answer(so far): You can not! due da...da....da... :D
Or it will light up, but will not go off bacause the lack of connection, causes the arduino to just wait for next serial event. And as serial flush only flush the TX buffer, the RX that turned the LED on, still is in the buffer. (As I understand it!)
I finally figured a way to at least register serial communication.
You can flash led each time the Link2fs update.
In the test I use 5 sec refresh time on the Link2fs and make the led light up for half a sec.
(The delay(500).
This works. The led goes on when receiving the Heading, stays on for half a sec and goes off, and repeats for as long as you are connecte to Link2fs.
If you disconnect the Link2fs, the Heading will not be received and the light will stay off.

SteveL (http://www.mycockpit.org/forums/member.php?u=22551)s suggestion to use the "Local FSX time" , did not work for me bacause the Link2fs does not receive this if FSX is paused, and this made it cind of hard to find a way to create a code.


int CodeIn;// used on all serial reads

String Heading;
int Headingi;
int connection = 13; // The led to check connection.

void setup()
{
pinMode(connection, OUTPUT);

Serial.begin(115200);
}

void loop() {
if (Serial.available()) {
CodeIn = getChar();
if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
}
}

char getChar()// Get a character from the serial buffer
{
while(Serial.available() == 0);// wait for data
return((char)Serial.read());// Thanks Doug
}

void LESSTHAN(){ // The first identifier was "<"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'J'://Found the second identifier "Heading"
Heading = "";
Heading += getChar();
Heading += getChar();
Heading += getChar();
Headingi = Heading.toInt(); // convert it to an integer (Thanks Phill)*/

if (Headingi > 000 )digitalWrite(connection, HIGH);
delay(500);
digitalWrite(connection, LOW);
break;
}
}
If anyone finds another solution to this problem, I will be really disappointed in myself :roll:

SteveL
03-01-2014, 07:23 PM
Hi BuzziBi. Here's the way I think it would work:
1. Save the last Local FSX time in the Arduino as "OLD TIME"
2. When you read the next data request, if Link2fs is connected it will return a new time which is greater than the old time. record this as "NEW TIME"
3. If no data is retrieved (Link2fs not connected), the time will not update. NEW TIME will not change.
4. Test:
if NEW TIME = OLD TIME, there is no connection. Turn lamp off.
if NEW TIME > OLD TIME, there is a connection. Turn lamp on.
5. Copy NEW TIME to OLD TIME
6. Repeat.
Steve

BuzziBi
03-02-2014, 04:53 AM
SteveL (http://www.mycockpit.org/forums/member.php?u=22551) thats the same thing I was trying, BUT! There's always a but :D
This methode will halt on the same reason that you can't use a diode to confirme the serial connection.
When you store a time as New Time, this will be the "Old Time" "IF" you get a new one. But if the Link2fs can't send you a New time, the old time will still be the New time for as long as you hawe power on the arduino. Soooooo...... I cant see how to make it work with the time doda
Maby someone who realy can code, can make a timeout sketch on the Old Time/New Time.
Only way I can see it is if you can store the Old Time and make a timeout on that. Lets say if the Time stored not have been updated in eg. 5 sec. the diode will light up. Maby a way to go, but my knowledge of coding are not sufficient to make this happen! Sorry :D
:D

JMeller
03-03-2014, 12:59 AM
Buzz,
Your a forum friend so I hate to go against you, but Steve has a brilliant solution. L2FS sends data when it has changed; therefore, the time stamp will be sent every second. It can be done. Don't make me stop building my bot! ;)

-James

EDIT:
Hint -
Since there will be not be a serial read to jump to a method, you'll need to calculate the main loop revolutions per second; after a calculated second-and-a-half, if OLD TIME = NEW TIME then the connection has been disconnected.

BuzziBi
03-03-2014, 04:16 AM
To MyCockpit Forum Owners: We realy, realy, realy, nead a smily who is tearing his hair off!

To JMeller (http://www.mycockpit.org/forums/member.php?u=13381)
You're absolutely right, SteveL (http://www.mycockpit.org/forums/member.php?u=22551) s suggestion is good! To clarify a few things:


Have I misunderstood that Link2fs sends data according to the update frequency you select in "Communication Settings"?

If you choose 10 seconds in "Refresh time (Sec)", then Link2fs sends data every ten'th second?

What you wrote about the OLD TIME = NEW TIME then the connection has been disconnected.
Is not that the same as I wrote about the timeout sketch on the Old Time/New Time? (or am I mixing things)

This was not really not my problem. I just threw me in the thread, because (silly me) I'm always curious if there are solutions to things :D

The thread starter should do some work here. But now that you've thrown glove, I have to take this as a challenge. (This is where the hair tearing smily would come in handy) :D
I'll see if I'm smart enough to find a solution. I'm a little busy building an Asus eee motherboard into a 27 "Acer monitor. (My fiance wants an entertainment PC in the gym) and I (quote) "just threw me in the thread, because (silly me) I'm always curious if there are solutions to things :D" (New heartearing smily)

JMeller
03-04-2014, 12:38 AM
To clarify a few things:


Have I misunderstood that Link2fs sends data according to the update frequency you select in "Communication Settings"?



L2FS sends selected data to the arduino any time the selected data changes. The 'refresh cycle' sends ALL selected data to the arduino- regardless whether the data has changed. Using the time stamp, the time will change every second; thereby, forcing L2FS to send the time data since it has changed - 'refresh cycle' rendered irrelevant.

As for your sketch, it would work great at start-up (assuming your aircraft is not parked facing 0 degrees and you never fly 0 degrees). ;)
And, as John had stated, it will not indicate a true connection loss.

Here's your second jab. =D

SteveL
03-04-2014, 02:19 AM
Hi guys, If I could code proficiently I would have given you a sketch. Ive been writing plc programs for 40 years or so but I'm kinda new to Arduinos so my coding is slow and error prone. Buzz, it would be great if you could show me how this logic is properly coded.

BuzziBi
03-04-2014, 09:47 AM
The glove picked up, and this was the result! (And SteveL, I'm not sure if this is logicaly and properly coded) :D
LED (pin 13), will now light up if FSX is paused or if you disconnect Link2fs.
I have not tested the code with other functions other the the LED ON/OFF function, but it seams to work.
There is a bug that I can't find what causes:
The LED will blink every time the countloop restarts (every 10'th sec).
One could say that this was intendet, but... I must admit, it was not :D And I cant find out how to avoid it.
OR...Now that this problem has occupied my time and my head faaaar too long, I could not care less!
Basically it was someone else who wanted this Sketc,
And if I know JMeller right........ He will not agree that this is the way to do it, and probably come up with a childlike simple solution to the whole thing :D (No hard feelings James, I admire your knowledge) :D

int CodeIn;// The normal declearations go hereunsigned long timer;
int CentSec=0;
int LED = 13;
String FSXTime;
void setup(){
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
Serial.begin(115200);
}
void loop() {
{OTHER();}// Check for "Other" things to do. (Non extraction stuff)
if (Serial.available()) { //Check if anything there
CodeIn = getChar(); //Get a serial read if there is.


if (CodeIn == '?') {QUESTION();}// The first identifier is "?" ,, goto void QUESTION
}
}
char getChar()// Get a character from the serial buffer(Dont touch)
{while(Serial.available() == 0);// wait for data (Dont touch)
return((char)Serial.read());// (Dont touch) Thanks Doug
}
void OTHER(){
unsigned long mils=millis();
if (mils-timer>=100) {
timer=mils;
CentSec++;
if (CentSec==100) { // Reset to 0 after counting for 10 seconds.
CentSec=0;
digitalWrite (LED, HIGH);}
}
}
void QUESTION(){ // The first identifier was "?"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'd'://Found the second identifier "FSX Time"
FSXTime += getChar();
CentSec==100;
if (FSXTime == FSXTime) {digitalWrite(LED, LOW);}
break;
}
}

JMeller
03-04-2014, 07:25 PM
Very nice, Roy! I knew you would pick up the gloves. :)

Although it wouldn't matter (nor is necessary) in your quick sketch illustrating the connected/disconnected status, the case 'd' was only reading the first character; in a working sketch, this would cause a slight delay until the remaining characters were read.

I realize you wanted the heartbeat of the led every 10th second ;). However, in case a person doesn't, that has been modified.
Changes highlight:


include LiquidCrystal.h // incorrect syntax for webpage display
int DWrite = 31;


int CodeIn;
int CentSec=0;
int LED = 13;
long timer;
String FSXTime;
LiquidCrystal lcd(33, 35, 25, 41, 23, 43);


void setup(){
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
Serial.begin(115200);

pinMode(DWrite, OUTPUT);
digitalWrite(DWrite, LOW);
lcd.begin(40, 2);

}


void loop() {
{OTHER();}// Check for "Other" things to do. (Non extraction stuff)

if (Serial.available()) { //Check if anything there
CodeIn = getChar(); //Get a serial read if there is.
if (CodeIn == '?') {QUESTION();}
}
}


char getChar()// Get a character from the serial buffer(Dont touch)
{while(Serial.available() == 0);// wait for data (Dont touch)
return((char)Serial.read());// (Dont touch) Thanks Doug
}

void OTHER(){
lcd.setCursor(0,1);
lcd.print(FSXTime);
unsigned long mils=millis();
if (mils-timer >= 2000UL) {
// (The "UL" after the number is a syntax detail that is important
// when dealing with large numbers in millis and micros.)
timer=mils;
CentSec++;
if (CentSec == 2000) {
CentSec=0; digitalWrite (LED, HIGH);
}
}
}




void QUESTION(){ // The first identifier was "?"
CodeIn = getChar(); // Get another character
switch(CodeIn) {// Now lets find what to do with it
case 'd'://Found the second identifier "FSX Time"
FSXTime = "";
for(int i =0; i<6; i++){FSXTime += getChar();}
digitalWrite(LED, LOW);
break;
}
}


Again, thanks for picking up the gloves; I enjoy the sparring since I always learn something.

Oh, and Steve, thanks for the suggestion.

SteveL
03-05-2014, 01:13 AM
James, You are very welcome.
Buzz, James, Everybody - Thank you all. I'm still digesting this code, a tremendous learning experience.
Steve

BuzziBi
03-05-2014, 06:25 AM
Hi James!
I guess the only only one learning anything from this experience is me (and other who cares to study the code).
Suffering from a memory, that seems like made ​​of Teflon, I'm afraid the experience vanishes all too quickly :o
One fine thing doe, this forum is a good encyclopedia!
About the serial.read: As the code only was meant to switch the LED on/off, I didn't care to serial.read all the 6 figures from the FSX local time. I should have pointed this out doe!
I did not realize that this would cause a delay in the sketch. Sorry! :)

SteveL
03-10-2014, 07:40 PM
Buzzi, great code, you simplified it much further than I could have accomplished. I followed everything except for one statement. In voidQuestion() you have a line which contains: if (FSXTime == FSXTime) ... I don't understand how this works, it seems to me that this statement would always be TRUE. Could you give me an explanation of how this works? Thanks, Steve

BuzziBi
03-11-2014, 01:31 PM
SteveL (http://www.mycockpit.org/forums/member.php?u=22551)
I'm not sure that I can explain this :p
I tink you must think that the "CentSec" (the count) will force the led HIGH, but the FSXTime that comes from the getChar(); and stored in the "String FSXTime;" will force the led LOW, if present.
If I'm way out there with this explanation, I hope James can bear to correct me.

SteveL
03-11-2014, 03:40 PM
Hey Buzzi, I'm embarrassed. I was looking at a printout of the original code you wrote and one of James' modified code and I somehow mixed the two up when I posted that question. I see that specific line of code has been revised. Thanks again for the assistance. I've completed the mechanical build-out of my cockpit and am now starting to fabricate the radio stack.

SteveL
03-11-2014, 03:45 PM
Hey Buzzi, I'm embarrassed. I was looking at a printout of the original code you wrote and one of James' modified code and I somehow mixed the two up when I posted that question. I see that specific line of code has been revised. Thanks again for the assistance. I've completed the mechanical build-out of my cockpit and am now starting to fabricate the radio stack.

JMeller
03-12-2014, 12:53 AM
Buzzi, you're on it - no correction (from this novice) needed. I would like to add, for clarification purposes only and intended for future readers of this post, that case 'd' (if L2FS time is present) is what holds the led low; reading the remainder of the time string is irrelevant and only serves the purpose of reading the buffer to prevent errors/lags down the line when attempting to read the serial data.

Therefore, if case 'd' is not met (L2FS not sending time update), Centsec will quickly be = 2000 and hold the led high. Since L2FS is disconnected and never reads 'd' from the serial, the led will remain high until connected and case 'd' is true and told to go low.

Therein lies a technical error in my modified code: Centsec should also be reset to 0 when case 'd' is met.


I also agree with Steve - your code is much better than what I had envisioned. Personally, I like this addition since I am always hastily testing new code; two bright red leds in the peripherals serve as a grim reminder that I forgot a simple step. :oops:

Looking forward to new pics/vids of your project,
-James