Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

poll serial port

Status
Not open for further replies.

reggler

Programmer
Nov 13, 2008
63
CA
Hi There,

I need to include polling of the seruial port into my application. There's a whole lot going on there but as soon as I receive a ceertain string, I want to execute a certain proc. I will receive this string about 5 - 10 minutes after i hasd sent out a specific request overthe com port. Is there a poll function in TCL that allows me to poll the port 's handle for its data?
How would I do that?

Thank you!
Ron
 
Read up on the open statement, particularly the section on serial communication:
AS help said:
SERIAL COMMUNICATIONS
If fileName refers to a serial port, then the specified serial port is opened and initialized in a platform-dependent manner. Acceptable values for the fileName to use to open a serial port are described in the PORTABILITY ISSUES section.

The fconfigure command can be used to query and set additional configuration options specific to serial ports (where supported):

-mode baud,parity,data,stop
This option is a set of 4 comma-separated values: the baud rate, parity, number of data bits, and number of stop bits for this serial port. The baud rate is a simple integer that specifies the connection speed. Parity is one of the following letters: n, o, e, m, s; respectively signifying the parity options of ``none'', ``odd'', ``even'', ``mark'', or ``space''. Data is the number of data bits and should be an integer from 5 to 8, while stop is the number of stop bits and should be the integer 1 or 2.
-handshake type
(Windows and Unix). This option is used to setup automatic handshake control. Note that not all handshake types maybe supported by your operating system. The type parameter is case-independent.
If type is none then any handshake is switched off. rtscts activates hardware handshake. Hardware handshake signals are described below. For software handshake xonxoff the handshake characters can be redefined with -xchar. An additional hardware handshake dtrdsr is available only under Windows. There is no default handshake configuration, the initial value depends on your operating system settings. The -handshake option cannot be queried.

-queue
(Windows and Unix). The -queue option can only be queried. It returns a list of two integers representing the current number of bytes in the input and output queue respectively.
-timeout msec
(Windows and Unix). This option is used to set the timeout for blocking read operations. It specifies the maximum interval between the reception of two bytes in milliseconds. For Unix systems the granularity is 100 milliseconds. The -timeout option does not affect write operations or nonblocking reads. This option cannot be queried.
-ttycontrol {signal boolean signal boolean ...}
(Windows and Unix). This option is used to setup the handshake output lines (see below) permanently or to send a BREAK over the serial line. The signal names are case-independent. {RTS 1 DTR 0} sets the RTS output to high and the DTR output to low. The BREAK condition (see below) is enabled and disabled with {BREAK 1} and {BREAK 0} respectively. It's not a good idea to change the RTS (or DTR) signal with active hardware handshake rtscts (or dtrdsr). The result is unpredictable. The -ttycontrol option cannot be queried.
-ttystatus
(Windows and Unix). The -ttystatus option can only be queried. It returns the current modem status and handshake input signals (see below). The result is a list of signal,value pairs with a fixed order, e.g. {CTS 1 DSR 0 RING 1 DCD 0}. The signal names are returned upper case.
-xchar {xonChar xoffChar}
(Windows and Unix). This option is used to query or change the software handshake characters. Normally the operating system default should be DC1 (0x11) and DC3 (0x13) representing the ASCII standard XON and XOFF characters.
-pollinterval msec
(Windows only). This option is used to set the maximum time between polling for fileevents. This affects the time interval between checking for events throughout the Tcl interpreter (the smallest value always wins). Use this option only if you want to poll the serial port more or less often than 10 msec (the default).
-sysbuffer inSize
-sysbuffer {inSize outSize}
(Windows only). This option is used to change the size of Windows system buffers for a serial channel. Especially at higher communication rates the default input buffer size of 4096 bytes can overrun for latent systems. The first form specifies the input buffer size, in the second form both input and output buffers are defined.
-lasterror
(Windows only). This option is query only. In case of a serial communication error, read or puts returns a general Tcl file I/O error. fconfigure -lasterror can be called to get a list of error details. See below for an explanation of the various error codes.
SERIAL PORT SIGNALS
RS-232 is the most commonly used standard electrical interface for serial communications. A negative voltage (-3V..-12V) define a mark (on=1) bit and a positive voltage (+3..+12V) define a space (off=0) bit (RS-232C). The following signals are specified for incoming and outgoing data, status lines and handshaking. Here we are using the terms workstation for your computer and modem for the external device, because some signal names (DCD, RI) come from modems. Of course your external device may use these signal lines for other purposes.

TXD(output)
Transmitted Data: Outgoing serial data.
RXD(input)
Received Data:Incoming serial data.
RTS(output)
Request To Send: This hardware handshake line informs the modem that your workstation is ready to receive data. Your workstation may automatically reset this signal to indicate that the input buffer is full.
CTS(input)
Clear To Send: The complement to RTS. Indicates that the modem is ready to receive data.
DTR(output)
Data Terminal Ready: This signal tells the modem that the workstation is ready to establish a link. DTR is often enabled automatically whenever a serial port is opened.
DSR(input)
Data Set Ready: The complement to DTR. Tells the workstation that the modem is ready to establish a link.
DCD(input)
Data Carrier Detect: This line becomes active when a modem detects a "Carrier" signal.
RI(input)
Ring Indicator: Goes active when the modem detects an incoming call.
BREAK
A BREAK condition is not a hardware signal line, but a logical zero on the TXD or RXD lines for a long period of time, usually 250 to 500 milliseconds. Normally a receive or transmit data signal stays at the mark (on=1) voltage until the next character is transferred. A BREAK is sometimes used to reset the communications line or change the operating mode of communications hardware.

_________________
Bob Rashkin
 
well yes i saw this thank you, so am i supposed to sit in a while loop and wait until my $serial::rxBuffer contains a certain value?
Wouldn't take this 100% cpu? How can i give control back to the Windows(OS) queue and just come in and check every - let's say - 10msec?

Thaks,
Ron
 
Okay, I figured this out. Now my next problem:
How can I search a specific stfing in a text widget? I've been searchuing around but haven't found anything.... I have 100s of lines in this widget and I look for a string somwewhere on a line, any clues?
What I've found out so far is that the text content is a list, one item per line....
so what i would do is something like:

for { set i 1 } { [$i <= MyTextBox.NumItems]&&[flag==-1] } { incr i }
{
set flag [string first MyTextBox.Item,[$i] "Pass: 11"]
}

But how can I do this in TCL? As you may see I'm a C programmer who's been thrown into a TCL/TK project - Can anyone help?

Thank you!
Ron
 
Okay,

I think I found something:
while {[GUI::serialMon.text search "Pass: 11" end]==-1}
{
finaltest::delay 100
}
now the problem is the interpreter keeps telling me
"wrong # args: should be "while test command""
and i can't figure oiut why - anyone?

Thanks a lot!
 
There are lots of ways to search for patterns in strings. What do you want to return? That is, do you want to know which line it's in, that it's there at all, what comes after it? Which method is most appropriate depends on how you want to proceed.

I think I would take all the text in the text widget into a string:
Code:
set strT [[red]<your text name (like .frame1.text1)>[/red].get 0.0 end]

Now you can make a list of lines (if lines are important to you):
Code:
 set lstT [split $strT \n]

Now you can find where in any string a particular sub-string is in various ways. As you found, string first ... is a good way:
Code:
set indx [string first [red]$<stringVariable> <search string>[/red] ]
You can also use regexp (exotic and elegant but not always the best tool) to tell you exactly how the match was made if the search string is a pattern:
Code:
set boolVar [regexp {<search string>} $<string variable> matchVarName]
There are ways to make the regexp quite flexible and it returns '0' if no match found so its return can be used as a boolean.

_________________
Bob Rashkin
 
GREAT, thanks a lot Bob!
Uhm, okay this derived to my code looks like
Code:
while {rslt == -1}
    {
        set str [GUI::serialMon.text.get 0.0 end] ;#load content from console window into $str
        set rslt [string first $str "Pass: 11"] ;#search for the string "Pass: 11" in $str
        finaltest::delay 100
    }
but the interpreter tells me this:
Code:
wrong # args: should be "while test command"
wrong # args: should be "while test command"
    while compiling
"while {rslt == -1}"
    (compiling body of proc "BIS_Test::Start", line 605)
But why? What is wrong with my while clause? :eek:
 
Should be while {[red]$[/red]rslt == -1} maybe?

_________________
Bob Rashkin
 
I thought "yeah, that must be it" but....:
Code:
wrong # args: should be "while test command"
wrong # args: should be "while test command"
    while compiling
"while {$rslt == -1}"
    (compiling body of proc "BIS_Test::Start", line 605)
    invoked from within
 
There must be something else going on. The while syntax is correct:
[tt]z:\>tclsh
% set rslt -1
-1
% while {$rslt == -1} {puts $rslt; incr rslt}
-1
%[/tt]
Try executing each line separately in a Tcl shell and see what the actual returns are.

_________________
Bob Rashkin
 
i get the same results as you posted....
my code that I have added looks like
Code:
#[ Ron ]
    set rslt -1
    while {$rslt == -1}
    {
        set str [GUI::serialMon.text.get 0.0 end] #load content from console window into $str
        set rslt [string first $str "Pass: 11"]   #search for the string "Pass: 11" in $str
        finaltest::delay 100
    }
    BIS_Test::Get_Bist_Result
    #[ /Ron ]
Looks correct to me...
 
alright the solution was that the tcl/tk parser f*cked-up. Reformated like that
Code:
while {$rslt == -1}  {
        set str [GUI::serialMon.text.get 0.0 end] ;#load content from console window into $str
        set rslt [string first $str "Pass: 11"]   ;#search for the string "Pass: 11" in $str
        finaltest::delay 100
    }
i don't get that error but instead this one:
Code:
invalid command name "GUI::serialMon.text.get"
    while executing
"GUI::serialMon.text.get 0.0 end"
Is this because there's no .get method in the text object? What is this about? It doesn't say a whole lot. Thank you!
 
The text widget does, indeed, have a get method, but "you're not in [red]C[/red]ansas anymore". It seems you're refering to the widget by the namespace in which it was created. Windows (that is, widgets) are designated with a path refering to the main window (aka "."). These references are, if you like, inherently global. You need to explicitly refer to the path of the text widget. Somewhere in your code you must have declared the widget with something like text .frame.subframe...widgetname ... (where I hope "widgetname" is not "text" as that might lead to problems). It is that reference: .frame.subframe...widgetname that has the get command (method).

_________________
Bob Rashkin
 
in fact, I think the widget name is "text", the definition looks like:
Code:
set twidget [text .serialMon.text \
            -font {courier 8} -bg white -yscrollcommand [list .serialMon.yscroll set]]

and with .serialMon.text.get i get
Code:
invalid command name ".serialMon.text.get"
invalid command name ".serialMon.text.get"
    while executing
".serialMon.text.get 0.0 end"
 
My mistake. Sorry, I was language garbled the first time around. The syntax is .serialMon.text get 0.0 end (note the space instead of the dot).

_________________
Bob Rashkin
 
Okay great! I have precautously renamed the text widget to "cons" but my while loop doesn't quite seem to work - i will look into that tomorrow. I'm on Eastern time so for me it's time to go home.

Thanks anyways for your assistance buddy! :) And remember: C++ansas still rules the world :p
 
Hello, anyopne there still?

Uhm I inserted some debug information into my code, I get following in my text window:
Code:
Pass: 11
***count: 121 - rslt: -1***
with this code:
Code:
while {$rslt == -1}  {
	    incr count 1
        set str [.serialMon.cons get 0.0 end]     ;#load content from console window into $str        
        set rslt [string first $str "Pass: 11"]   ;#search for the string "Pass: 11" in $str
        .serialMon.cons insert end "\n***count: $count - rslt: $rslt***\n"
        finaltest::delay 1000
    }
I guess this means my search command doesn't quite work, any idea why that's not going as expected?
rslt stayed -1 even after a few more loops...any idea what's going wrong here? :eek:

Thanks again,
Ron
 
even this returns -1
Code:
set test "ljkghlkjhPass: 11kljhyljkhkljh"
    while {$rslt == -1}  {
	    incr count 1
        set str [.serialMon.cons get 0.0 end]     ;#load content from console window into $str        
        set rslt [string first $test "Pass: 11"]   ;#search for the string "Pass: 11" in $str
        .serialMon.cons insert end "\n***count: $count - rslt: $rslt***\n"
        finaltest::delay 1000
    }
so there must be something wrong with this search procedure....
 
it says:

[string first string1 string2 ?startIndex?
Search string2 for a sequence of characters that exactly match the characters in string1. If found, return the index of the first character in the first such match within string2. If not found, return -1. If startIndex is specified (in any of the forms accepted by the index method), then the search is constrained to start with the character in string2 specified by the index.


So the parameters have to be the other way round in the string first call ;) - for futyure reference ;)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top