Jump to content
The simFlight Network Forums

Problem with Lua Script Monitoring Com Port


Recommended Posts

I am attempting to come up with a lua script that will monitor a com port and based on received strings trigger some LVars to control the Avionics stack in my Add On aircraft.

 

This is my first attempt at doing anything with the com library and I'm at a bit of a loss for why what I have isn't working.

 

My sim pit has an Ardiono based avionics stack and it works well with several of my add on aircraft via a program called LinktoFS Multi.  However, my newest Add On, an A2A 172 has some advanced features that require LVars.  Several months ago I came across another pit builder who was working on a similar project and had already come up with a script.  Unfortunately I can't find his name or a link to the source in my notes so I can neither give that person credit or ask them questions.

To try and test this I setup a temporary Ardiono sending two test strings.  It sends "A45" and "A46" alternately every two seconds.  Those are the existing strings I use to switch Comm Audio 1 and 2 via the other program so I want to keep them for consistency.

 

Here's the lua script:

speed = 9600
handshake = 0
ArdComPrt = com.open("COM8", Speed, handshake)

if ArdComPrt == 0 then
    ipc.display("Could not open ARDUINO Com Port")
	ipc.sleep(2500)
    ipc.exit()
end

while ArdComPrt > 0 do
    Frm_Arduino = ""
    char = ""
    if (com.test(ArdComPrt)>0) then
        while com.test(ArdComPrt) > 0 do
            char = com.read(ArdComPrt,1)
            Frm_Arduino =  Frm_Arduino..char
        end
    end

    if Frm_Arduino == "A45" then
        ipc.writeLvar("L:kma26SelectorKnob_pos",1)
    elseif Frm_Arduino == "A46" then
        ipc.writeLvar("L:kma26SelectorKnob_pos",2)
    end
    ipc.sleep(50)
end 

and here's what I have the Arduino on com 8 doing as a test source:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("A45");
  delay(2000);
  Serial.println("A46");
  delay(2000);
} 

Via the Arduino IDE's serial monitor I can see the "A45 and "A46" going out every two seconds.  I can also see the Tx LED on the Arduino flashing every two second.

 

I placed some ipc.display commands in my lua script and I can see that ArdComPrt handle returns a value of 904947972 repeatedly and following it each time com.test(ArdComPrt) returns a 0.  So it appears that the Lua script is not seeing the strings my Ardiono is sending.

 

Any thoughts or ideas on what I'm doing wrong would be greatly appreciated.  As I said above, being new to the com library I'm at a bit of a loss for why what I have isn't working.

 

Thanks!
Tom G.

Link to comment
Share on other sites

To try and test this I setup a temporary Ardiono sending two test strings.  It sends "A45" and "A46" alternately every two seconds.  Those are the existing strings I use to switch Comm Audio 1 and 2 via the other program so I want to keep them for consistency.

 

Here's the lua script:

...

 

Via the Arduino IDE's serial monitor I can see the "A45 and "A46" going out every two seconds.  I can also see the Tx LED on the Arduino flashing every two second.

 

I placed some ipc.display commands in my lua script and I can see that ArdComPrt handle returns a value of 904947972 repeatedly and following it each time com.test(ArdComPrt) returns a 0.  So it appears that the Lua script is not seeing the strings my Ardiono is sending.

 

A question first. Why read once character at a time and accumulate them? Why not just read what's there, or at least the 3 characters, all at once (assuming you were receiving anything, that is)?

 

Additionally, i'm not sure whether Arduino terminates strings with a zero as in C. I know it uses a sort of C, but if it does, that zero would be part of the return. I don't think Lua uses zero terminators. And does "println" actually add a new line or line feed code too? That might mess up comparisons for equal strings.

 

However, the answer to the question "why is nothing being received?" can only be that the port is incorrect. The fact that it opened without error doesn't mean it's the correct port. Also COM ports, unlike USB ones, can only be used by one program at a time. You aren't running the Arduino PC programming program at the same time are you?

 

The handle is actually a 32 bit address. You should really only check it it is zero or non-zero, not greater or less than zero.

 

And do consider using event.com to trigger entry to a processing function, rather than a loop with a sleep.

 

Pete

Link to comment
Share on other sites

A question first. Why read once character at a time and accumulate them? Why not just read what's there, or at least the 3 characters, all at once (assuming you were receiving anything, that is)?

 

 

A good question and my honest answer is lack of experience.  The received strings will have a minimum of 3 characters similar to the test string "A45" which will active Comm 1 xmit.  However, some of the codes will be followed by 1 to 5 digits to do things like set a radio frequency or select a DME, etc.  So I I could receive the first three characters all at one time consistently and listen for additional depending on the code string sent.

 

Additionally, i'm not sure whether Arduino terminates strings with a zero as in C. I know it uses a sort of C, but if it does, that zero would be part of the return. I don't think Lua uses zero terminators. And does "println" actually add a new line or line feed code too? That might mess up comparisons for equal strings.

 

 

 

I will need to do some reading and research on the terminator to figure that out.  The serial.println is supposed to send a line feed.  If that might be messing it up I'll try a regular serial.print for sending the strings.

 

However, the answer to the question "why is nothing being received?" can only be that the port is incorrect. The fact that it opened without error doesn't mean it's the correct port. Also COM ports, unlike USB ones, can only be used by one program at a time. You aren't running the Arduino PC programming program at the same time are you?

 

 

 

I did a couple basic test to confirm the Com port and it does appear to be correct, Com 8.  For example knowing that it can only be used by one program at a time I turned on the Arduino IDE serial monitor and could see the test strings being sent.  With it on the lua script could not open the com port.  I did the reverse and opened com port 8 with the lua script and the IDE could no longer access Com 8.  So, I think that shows I've got the correct Com Port, yes?  I also downloaded a program to monitor USB serial ports and when I set it to watch Com 8 I see the test strings as traffic on the port.

 

Assuming the Com Port is correct and the data can be seen on the port by the monitor, any further thoughts on trouble shooting steps that I can take?

 

The handle is actually a 32 bit address. You should really only check it it is zero or non-zero, not greater or less than zero.

 

 

Thanks, I'll modify the script accordingly.

 

And do consider using event.com to trigger entry to a processing function, rather than a loop with a sleep.

 

 

I'll read up on the use of event.com and modify my code.

 

Thanks for the reply!  I'll do some more work on this and come back with any further questions.

Link to comment
Share on other sites

A good question and my honest answer is lack of experience.  The received strings will have a minimum of 3 characters similar to the test string "A45" which will active Comm 1 xmit.  However, some of the codes will be followed by 1 to 5 digits to do things like set a radio frequency or select a DME, etc.  So I I could receive the first three characters all at one time consistently and listen for additional depending on the code string sent.

 

Or, better, add a terminating character if youcan, like for instance ASCII 0 or maybe a control like NL or CR (10 or 13, decimal). Then just specify the maximum length and the termination used.

 

Assuming the Com Port is correct and the data can be seen on the port by the monitor, any further thoughts on trouble shooting steps that I can take?

 

First, try without the com.test part. It isn't needed as com.read will return the number of bytes read in any case. If that works then maybe I have a problem in com.test, so let me know please. (I do have an Arduino, but at present it's only being used to control indicators, so outputs from the PC only, no inputs. All my input devices are HID, so using the HID functions.)

 

Lastly, you could try using com.readlast -- just as a test. It assumes fixed length blocks though. If you get data with that but not with com.read let me know directly because something is wrong with my code if so.

 

Pete

Link to comment
Share on other sites

Pete, Thanks!

I like the idea of using a terminating character.  I'll be sure to try that. With the variable length of the strings it sounds like that would be the cleanest way to deal with it.

I'll get back to you with my findings on com.test, read, and readlast.  Work is getting a bit crazy though, I just got pulled into a multi day fire dril, so it may be a few days, but, I'll be sure to post my progress as soon as possible.

Link to comment
Share on other sites

Pete,

 

I removed com.test as suggested and it didn't make a difference.  I've also changed the Lua script to use event.com.  Another user sent me a code example from there setup that is working for them and it also used event.com

 

Here's what I'm doing to test this now.

 

Ardiono test code same as before:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("A45");
  delay(2000);
  Serial.println("A46");
 delay(2000);
}

Lua Script:

speed = 9600
handshake = 0
ArdComPrt = com.open("COM8", Speed, handshake)

if ArdComPrt == 0 then
    ipc.display("Could not open ARDUINO Com Port")
    ipc.sleep(1000)
    ipc.exit()
elseif ArdComPrt ~= 0 then
    ipc.display("ARDUINO Com Port OPEN")
    ipc.sleep(1000)
    ipc.display("")
end

function ArdData(ArdComPrt, datastring, length)
    if datastring == "A45" then
        ipc.writeLvar("L:kma26SelectorKnob_pos",1)
    elseif datastring == "A46" then
        ipc.writeLvar("L:kma26SelectorKnob_pos",2)
    end
end

event.com(ArdComPrt, 10, 1, 10, "ArdData")

Using a serial monitor program to watch the port I see the following repeating in Hex

41 34 35 0d 0a 41 34 36 0d 0a

So, the A45 and A46 are each being sent with a Line break and Carriage Return. But still no joy.  The Com Port indicates open but the script doesn't appear to be detecting the serial traffic.

 

I've also switched out Arduino cards and serial ports.

 

Any further thoughts?

Link to comment
Share on other sites

41 34 35 0d 0a 41 34 36 0d 0a

So, the A45 and A46 are each being sent with a Line break and Carriage Return. But still no joy. 

 

You have

 

if datastring == "A45"

 

but the string you are receiving is never == A45!!  In the event.com you set the terminator to 10 (=0a). That is included in the returned data, and of course so is the preceding 13 (0d).

 

Try this:

 

if datastring == "A45\r\n"

 

Similarly for the other. (\r = return, or 0d == 13. \n = newline, or 0a == 10. Alternatively you can use \013 and \010).

 

If the A45 message and A46 message are arriving with no gap, as you seem to imply, then you may need to keep reading in the function too -- I'm not sure whether the the event would trigger again until more (separate) data is received. Try first, but if necessary, rather than process the datastring/length supplied, loop doing the

 

com.read(ArdComPrt, 10, 1, 10)

 

call whilst it still returns data.

 

Pete

Link to comment
Share on other sites

Pete,

 

To clarify what the serial monitor is showing their is a 2 second pause between  41 34 35 0d 0a  and  41 34 36 0d 0a that I failed to note in my reply above., 
 

I started to edit my lua script per your suggestions and before I got too far I discovered something.  Prior to this I had been running the serial monitor program (Device Monitor Studio) only briefly just to confirm the strings being sent by the Arduino.  For this round of testing I left it running and observed it as I ran the lua script.  For testing I have the lua script assigned to two buttons.  One to launch it and the second to kill it.

 

I was watching the serial monitor during this round of testing and noticed that the data stream coming form Com 8 (the Arduino) stops any time I launch the lua script.

 

Having discovered this I did it a few more times just to confirm I could replicate  it and I can.  When it occurs I can jump start the serial port again by killing the lua script and turning the Auduino IDE's serial monitor on and then back off.  As soon as I do that the Device Monitor Studio shows the data flowing again.  But, if I launch the lua script the data stops.

 

Any thoughts on what would cause that?

 

 

Link to comment
Share on other sites

As an additional test I removed event.com line from the script so that the only thing affecting the com port was com open and the data still stops flowing so it appears to be the com.open that is stalling the port.

 

It seems the Arduino device is set to see certain conditions true on the connection -- the simulated (because it is USB?) DSR/DTR, and CTS/RTS lines. Or maybe it needs something like Xon/Xoff, some sort of throttle control?

 

Does your serial monitor show you any difference in the initialisation between what the Arduino control program does and the Lua com.open is doing?

 

You could try changing the handshake parameter in the com.open. Or else sending an XON byte.

 

Might be useful to check the Arduino documentation as well.

 

Pete

Link to comment
Share on other sites

Pete,

 

I'm doing some reading on a couple Arduino sites trying to figure out what the Arduino is expecting. I haven't found much yet.  On the official Arduino sites reference page I don't see any mention of flow control and the only serial parameters I seem to have control of are data bits, parity and stop bits.  By default it's set to 8N1.  I can configure the data bits from 5 to 8, parity None, Odd, or Even and, stop bits 1 or 2.

 

I haven't found anything on flow control yet but I've tried all four options from com.open in my lua script and none resolve the issue.  I've also posted out on one of the Arduino forums to see if anyone there might have some additional information.

 

Tom G.

Link to comment
Share on other sites

A user on an Arduino forum pointed out that the Arduino is designed to do a reset any time that a connection is open via the USB port.  I guess they did this to make uploading code to the board easier for users.  However, I'm told this may be what is stalling my serial port.

 

I am reading up on some ways to disable that reset.  But I am also curious why the Arduino IDEs serial monitor doesn't cause the same problem.  If I connect it and the port resets why then does the serial data resume.  I'm asking out on the Arduino forum to see if there's some sort of string I can return to the Arduino from the lua script to wake it up.

Link to comment
Share on other sites

Pete,

SERIAL DATA FLOW PROBLEM SOLVED!!!
 
My original com open statement in the Lua script looked like this:
 
speed = 9600
handshake = 0
ArdComPrt = com.open("COM8", Speed, handshake)
 
Just now to strip it all the way down and eliminate any other problem sources I took out the variable declarations and ran it as follows:
 
ArdComPrt = com.open("COM8", 9600, 0)
 
That works!  The Com Port opens and the data keeps flowing.
 
Should that have made a difference?  Should the 9600 or 0 been in quotes when I declared them?
 
 
I am running into some other problems with my LVars but I'll start a separate post about that If I am unable to solve those issues on my own. 
 
Link to comment
Share on other sites

Arrggghhhh!!!!!

 

I just noticed why and feel really embarrassed for all this activity over what may only be a case sensitive issue.

 

I declared speed=9600 but my com.open was looking for Speed 

 

Aaaarrrggghhh indeed! I should have spotted that for sure! But us programmers, we always assume it's something complicated, never so simple!

 

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.