Jump to content
The simFlight Network Forums
Sign in to follow this  
cheeseburger

FSUIPC and Arduino

Recommended Posts

Hi folks, I work on MCP based on Arduino. I read/write offsets through FSUIPC by LUA script. Unfortunately I have one problem. I tried to explain it with parking brake. I have on push button. The code in arduino:

 

...
void pushButton(){
  button = digitalRead(prkgbrake);
   if (button == HIGH && exbutton == LOW && millis() - last > ddelay){
      Serial.write("brake:1\n")
      while( digitalRead(prkgbrake) == HIGH){
    }
  }
}
...




and this is LUA script
 

....
x = com.open("COM3", 115200, 0)

function offset(handle, str)
  ipc.log(str)
end

event.com(dev, 20, 1, 0, "readSerial")    



The problem is that if I push several times push button I get at first correct messages

brake:1
brake:1
brake:1
brake:1



but then I get something like that
 

brake:1
br
ake:1
brake:1brake:1
brak
e:1




Could someone help me where is the problem, and how to solve it? Thank you in advance icon_smile.gif
 

Edited by cheeseburger

Share this post


Link to post
Share on other sites
3 hours ago, cheeseburger said:


Could someone help me where is the problem, and how to solve it? Thank you in advance icon_smile.gif
 

Sorry, why are you worried about how the log looks? The fact that the function is called every time is surely proof that it works. 

Logging is asynchronous, and in a different thread, to your Lua plug-in. it is quite easy to get the logging from a Lua plug-in jumbled up. 

Why not actually program what you need to program in your "offset" function? Just logging something doesn't sem to actually do anything for you!

Pete

 

Share this post


Link to post
Share on other sites

Sorry for my late reply. Of course it does not matter how the log looks. This part of code which I posted here, should be push button for parking brake. Unfortunately, when I get by serial link to FSUIPC something like this "br" or "ake:1"  LUA script does not know, what is it and what to do. Thank you in advance :) 

Share this post


Link to post
Share on other sites
4 hours ago, cheeseburger said:

Unfortunately, when I get by serial link to FSUIPC something like this "br" or "ake:1"  LUA script does not know, what is it and what to do. Thank you in advance :) 

Of course - you're reading from a stream of data, so when you do the read you may not get a complete message. It's up to you to define what a "message end" delimiter is, and buffer until you receive it.

Cheers!

Luke

Share this post


Link to post
Share on other sites

As well as what Luke suggests you could detect a long enough time gap since the last reception and decide that what you received so far must be a complete command. If the commands are generated by you pressing bttons then that should be okay with a small number of milliseocnds (experiment), but if generated by program there may not be sufficient gap.

Generally, for Arduino, if just use something obvious as a message terminator, like the "resturn" code, decimal 13.

Pete

 

Share this post


Link to post
Share on other sites

Thank you for you replies. :)  I tried to connect rotary encoder, and I have a same problem, so it will be problem somwhere in serial communication. I will try to detect some special char, unfortunately I am not sure if I know how to read by char for serial link in LUA script.

Share this post


Link to post
Share on other sites
21 minutes ago, cheeseburger said:

I will try to detect some special char, unfortunately I am not sure if I know how to read by char for serial link in LUA script.

Don't "read by character". Just accumulate the data checking the each character each time for your terminator. Look up the Lua string library. You can manipulate individual characters as you which. You concatenate strings simply by using the ".." notation, i.e.

string1 = string1 .. string2

adds string2 to string1.

Pete

 

Share this post


Link to post
Share on other sites

Thank you, I noticed one strange thing and maybe where is problem. Now I tried in FSUIPC only read the strings without any reaction. When I send some string to serial link from arduino, sometimes I get only "alti" or something similar as I said. Problem is that next part of string "meter:1000" I get when I turn with rotar again, and usually i get rest of string with new one - "meter:1000\naltimeter:1100". The problem is in LUA script, because I tried to send strings also to other COM port at the same time, and strings are correct, only in LUA are incorrect. This is my code in LUA.

 

serial_wait = 100
dev = com.open("COM3", 9600, 0) --com, speed, handshake

if dev == 0 then
    ipc.display("Could not open device port")
    ipc.exit()
end

serial_string = ""

function readSerial(handle, string)
	serial_string = serial_string .. string
	ipc.log("com: " .. serial_string)

	n = com.test(dev)
	ipc.log("DATA AVAIL: " .. n)
	while(com.test(dev)>0) do
		ipc.log("READ NEXT DATA...")
		news, num = com.read(dev, 10000, 10)
		ipc.log("NEXT DATA " .. news)
		serial_string = serial_string .. news
	end

	ipc.log("SerialString: " .. serial_string)

end

event.com(dev, 10000, 1, "readSerial")	

also com.test is always 0, why?

Is any chance how to solve it? :/ Thank you very much.

Edited by cheeseburger

Share this post


Link to post
Share on other sites
1 hour ago, cheeseburger said:

The problem is in LUA script, because I tried to send strings also to other COM port at the same time, and strings are correct

These are other COM receptors, where, exactly. Running in FS?

Lua is interpreted. It is also not given full reign over the processor so that plug-ins do not cause FS performance to drop. Don't forget that, whilst being a separate thread, it is part of the FS process. It is likely that more data arrived whilst you are processing/reading the stuff you were notified about. You won't get another "event" signalled whilst you are in the event function.

The logging takes time, too -- it needs to call upon other threads to do that function.

1 hour ago, cheeseburger said:

also com.test is always 0, why?

You are testing it just after receiving the data, assuming there was no delay between the data arriving and the event being triggered. That will vary with FS performance and other activities.

As you've now added \n (new line) as a terminator for each block, why aren't you using that in the event.com call? Then each call into your function would contain one block.

event.com(dev, 10000, 1, '\n', "readSerial")

You could then simplify the function enormously, so:

function readSerial(handle, string)
	ipc.log("com: " .. string)
end

You only now need to process that string. You don't need "serial_string" any more.

BTW, 10000 for a max forces FSUIPC to allocate that much memory. Do you really intent to have such large amounts of data arriving in any block? I think you should make that a realistic maximum, not a fictional one.

Pete

 

  • Upvote 1

Share this post


Link to post
Share on other sites

I use Arduino UNO. There is possibly use only one serial. However I use software serial ( https://www.arduino.cc/en/Tutorial/SoftwareSerialExample ) , so I connected second arduino, and send string at the same time to serial link(FSUIPC) and to other Arduino. Data from second arduino I read by putty terminal. I agree 10 000 is very much, I have only tried it if it will change something in my problem. I will try use terminator in event.com. I would like to have one more question. Which baudrate do you recommend? In documentation is mentioned 115200 for VRInsight, also 4800 or 9600. I use own pushbuttons, rotary encoders and I want to use SPI segment displays. Thank you very much :)

 

Share this post


Link to post
Share on other sites
3 hours ago, cheeseburger said:

In documentation is mentioned 115200 for VRInsight, also 4800 or 9600

Speed isn't everything. Just choose the highest valid speed which gives reliable results. Normally on a USB-converted connection the baud rate is more a formality than a true indication or control of speed.

Pete

 

Share this post


Link to post
Share on other sites

Thank you very much. I think my previous problem is solved, but there is one more. When I quickly turning rotary encoder, I get something like this

 


  1266526 LUA.0: com: alt:6300

  1266931 LUA.0: com: alt:6400
alt:6500

  1266994 LUA.0: com: alt:6600
alt:6700

  1267025 LUA.0: com: alt:6800

I still only read the strings. It seems like I get two string at once. Is this normal or not? At morning it works great, but now it is again bad :/

Share this post


Link to post
Share on other sites
1 hour ago, cheeseburger said:

I still only read the strings. It seems like I get two string at once. Is this normal or not? At morning it works great, but now it is again bad :/

Sorry, I an not understanding. Did you use the terminator in the event? Why are you reading the strings when they are supplied for you?

What's the difference on your system between morning and "now"?

Pete

PS I am away soon now, until 20th September.

 

 

  • Upvote 1

Share this post


Link to post
Share on other sites

This is my LUA and arduino code:

serial_wait = 100
dev = com.open("COM3", 921600, 0) --com, speed, handshake

if dev == 0 then
    ipc.display("Could not open device port")
    ipc.exit()
end

function readSerial(handle, string)
ipc.log("com: " .. string)
end

event.com(dev, 16, 1, '\n', "readSerial")	
void writeOffset(const char* controlName, int value){
  char sendData[16];
  sprintf(sendData, "%s:%d\n", controlName, value);
  Serial.write(sendData);
  Serial.flush(); 
}

This is what I get when I quick turning rotar

 

..
  6516162 LUA.0: com: alt:5400
alt:550
  6516178 LUA.0: com: 0
alt:5600
alt:5
  6516193 LUA.0: com: 700
alt:5800
alt
  6516224 LUA.0: com: :5900
alt:6000
a
  6516240 LUA.0: com: lt:6100
..

I don't know if it was only luck that it works at morning, or I didn't turn it so quick. I didn't change source code. I don't understand, what do you mean by this

Quote

Why are you reading the strings when they are supplied for you?

Thank you so much for you advices.

 

EDIT:

 

I made simple arduino sketch with only one rotar.

#include "rotary.h"

Rotary r = Rotary(6, 7);
int encoderPosCount = 0;

void setup() {
  Serial.begin(115200);
  Serial.flush();
  //Serial.println("Rotary Encoder Debounce");
}

void loop() {
  char result = r.process();
  if (result) {
    if (result == DIR_CCW) encoderPosCount--;
    if (result == DIR_CW) encoderPosCount++;
   
    Serial.println(encoderPosCount*100);
   Serial.flush();
  }
}

 

as well as LUA

dev = com.open("COM3", 115200, 0)

function readSerial(handle, string)
	ipc.log("com: " .. string)
end	

event.com(dev, 16, 1, '\n', "readSerial")	

I get same incorrect data. I will get sometimes more than one block.

 

  7848083 LUA.0: com: 19500

  7848130 LUA.0: com: 19600

  7848192 LUA.0: com: 19700
19800
19
  7848223 LUA.0: com: 900
20000

  7848255 LUA.0: com: 20100

There is some problem with maintaining block, even though I use '\n' in event.com. I really dont know... :(

Share this post


Link to post
Share on other sites

Sorry, I don't have time to investigate this now, catching a flight early in the morning.

For now I suggest you try tmake all your blocks the same size, and read fixed length blcoks. I know that works fine. Remind me after September 20th and I'll check into it then, after I've caught up with the backlog.

Pete

 

Share this post


Link to post
Share on other sites
32 minutes ago, cheeseburger said:

Hello sir, is possible to check problem which I mentioned? Thank you in advance :)

Yes, but not till next week. Sorry, I have a lot to do with the release of P3D 3.4 and other things.

Have you tried the best solution, adopted by most -- that of using fixed length blocks as I suggested?

If you don't really want to try that, remind me next week. But please note that  I am away again for over 2 weeks from Thursday.

Pete

 

Share this post


Link to post
Share on other sites
On 9/22/2016 at 4:35 PM, Pete Dowson said:

If you don't really want to try that, remind me next week. But please note that  I am away again for over 2 weeks from Thursday

I've had a chance to look at this earlier than I expected, and I can't get any wrong results here.  The code for recgnising the occurrent of the chosen end-of-block character is as simple as it sounds, and it just stops copying the characters to the result when it is seen.

So, I'm rather puzzled.

I could maybe try some extra logging in a test version for you, but before that, in case it is something simple, could you try using a visible character as the terminator instead. For instance the character 'X'?

Pete

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • 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.