Just another Perl shrine | |
PerlMonks |
Re^3: RS232 and Tk with threadsby Marshall (Canon) |
on Jan 05, 2022 at 00:38 UTC ( [id://11140147]=note: print w/replies, xml ) | Need Help?? |
Yes, these simple USB to pseudo RS-232 devices can work well. It depends upon what you are talking to. Update: The incompatibility issue with voltage levels is complicated. see next post for more discussion of this.
I haven't ever used Perl to talk to a RS-232 device on Windows, but have done it in other languages and other O/S'es. The reason to use non-blocking calls is that you don't want your GUI to "freeze" and become unresponsive to mouse clicks. If the processor is off in serial port la-la land, then it won't be processing GUI events. I will allow that perhaps you get a version working with blocking calls and then come back later and refine that so that the GUI doesn't "Freeze". However a lot of applications have some kind of "Stop", "Restart", "Abort" button and you want that button to "work" when needed! I presume that you got the timed routine to display something every 1/2 second? $receive_T->repeat(5000,\&Receive2); While the processor is running Receive2(), it is not processing GUI events. As long as Receive2() runs fast enough, the user won't notice any difference in the GUI at all. In this case, Receive2() does some simple job and then returns way faster than a human is even physically capable of fully pushing a mouse button. We want the same thing (really fast return to GUI business) to happen with the serial port polling routine.
From the documentation: If you use the 2nd call which specifies a $count, the processor will stay inside of the streamline() method until that number of characters are received. If the thing you are talking to is not particularly chatty, that could be an entire day! 9600 baud is about 1 char/ms. By comparison it takes maybe 50ms for you to blink your eyes. If I am stitching together voice prompts and there is more than about a 20ms variation between segments, you can hear the difference quite easily. So if your application is a stimulus/response situation, say you send a 6 byte command and get back a 10 byte fixed length response, the blocking I/F could still work out ok, because xmit,rcv and processing is less than 20ms and that is so fast the human won't know that the GUI wasn't working during that 20ms interval. Note: there does appear to be a mechanism to abort blocking calls after a specified timeout. Now if you are listening to be asked to do some command, you might wait for days before a 6 byte command shows up. The user will definitely know that the GUI has gone "bye-bye" while it is waiting for this command to arrive via the serial port. The first of these reading methods, $gotit = $PortObj->streamline; works differently. The documentation is poor, but my guess is that you either get: undef, "" (null string) or some number of characters in the string, "abc". In this case, streamline() will return its result right away without any "waiting". I suspect (without any documentation) that undef means that some kind of error occurred. I presume most of the time you will get "", null string, no character received and then there is nothing to do. If you are polling every second, there could be 1,000 characters there. So for Receive3(), untested of course, So when using non-blocking I/O polling, there will not be any while(1){} loop. That is an infinite loop and you could be in there for a long time! I think undef means an error that shouldn't be ignored? This code will find out whether that is true or not. I just printed to the console. You know how to update the GUI and I leave that part to you with the guidance that updating the GUI is a very "expensive" operation - meaning consumes lots of MIPS. Maybe you don't want to update the GUI on a per character basis? However, here it could very well be that it is just fine to do an update per character. Just making you aware that the GUI is "expensive". I've seen programs that spend fully 1/2 of the computer power updating a progress bar too often. When updating the display only when it will change dramatically increases performance. Ok, now call Receive3() at some interval (which I think you know how to do now) and see what happens. The serial port package has all sorts of tricky "wait for X to happen" features. Those are blocking calls. You may wind up having to do some of these functions yourself. I have no idea what my ($found, $end, $obattern, $instead) = $ob->lastlook; does. Update: I don't think that you need to use threads. If you used a separate thread for the serial port, then you could put in blocking calls because even if that thread "blocked", it would not freeze the main GUI thread. But you would still need the paradigm of a non-blocking call to ask the serial port thread whether it had some result to report or not. I think you will be fine with a single thread as long as you don't have any while(1){} loops. Update2: I am not sure what your moniker of "Marjacktablet" means, but I suggest that you register as Monk - that process is free and non-fattening. There are a lot of advantages to being a "registered user". When you post as just "anonymous Monk", it is hard for me to see perhaps other perhaps related questions and responses that you have had. When I post a direct response to your question, you will be able to see that you have a new reply without having to find the exact thread from x days ago. So there are advantages and I recommend you do it.
In Section
Seekers of Perl Wisdom
|
|