From: CKL on
Hi tcl gurus

There is now 2 weeks that I try to find a solution to my problem

The problem is relative simple to understand.
My PC have to control a serial device.
But The PC has to be the Master and the device a Slave.
So there is a Handshaking mechanism

I use, to simulate the serial port, the free "Virtual Serial Ports
Emulator" : http://www.eterlogic.com/Products.VSPE.html
I virtually connect com1 and com2, to simulate a loopback
Run the below tcl code, and use "Tera Term" terminal emulator, to
enter characters, and to read it on my shell

In the example below, to allow to enter chars in the terminal the
delay and timeout are long enough to play manually with the program

So in the example
Every 5 seconds
Check to see is something is available on the serial port:
For this
* Enter in FreeRunningRead Mode
* write "RTR" (Request To Read message) on serial port
* Read the answer message from the device.
if message is Acknowledged by AKR (Acknowledge Read) message, exit
mode, and enter in "Waiting" mode
or
* Wait maximum 2s for an answer. If delay passed, issue by displaying
"Timeout message", exit mode, and enter in "Waiting" mode

FreeRunningRead Mode
PC Device
---------------- RTR ---------------> o
<-------------- Message -------------
<-------------- AKR ----------------

This is easy.

The problem is now, that during all this time, there can be an
asynchronous event, which could interfere.
This event will try to write a data message to the serial port, and
must be acknowledged by AKW

ForcedWrite Mode
PC Device
--------------- Message ------------->
<--------------- AKW ----------------

And here is the issue.
Before to write the message, I must be sure that I'm outside:
FreeRunningRead Mode
Trying to play with after, vwait in all the direction, I pass now more
then 2 weeks to find a solution, but Without success :-((
It seems that my approach seems not to be good.

Please, if someone have a little bit time to analyse my program.

Thanks in advance


set chid [open com1: r+]
fconfigure $chid -mode "9600,n,8,1" -blocking 0 -buffering none -
translation binary
fileevent $chid readable [list serial_receiver $chid]

set mode Waiting
set MessageRead ""
set LoopTime 5000
set Timeout 2000

set cnt 0

proc serial_receiver { chan } {
global mode
global MessageRead
global FreeRunningRead_Result
global ForcedWrite_Result

set data [read $chan]
append MessageRead $data

if {$mode == "ForcedWrite"} {
if { [string range $MessageRead end-2 end] == "AKW"} {
set ForcedWrite_Result AKW
}
} elseif {$mode == "FreeRunningRead"} {
if { [string range $MessageRead end-2 end] == "AKR"} {
set FreeRunningRead_Result AKR
}
}

}

proc FreeRunningRead { chid } {
global mode
global MessageRead
global Timeout
global FreeRunningRead_Result
global ForcedWrite_Result

set mode "FreeRunningRead"

puts "Start FreeRunningRead"
puts -nonewline $chid "RTR"
puts -nonewline $chid \x0D
puts -nonewline $chid \x0A

set MessageRead ""
after $Timeout { set FreeRunningRead_Result TimeOut }
vwait FreeRunningRead_Result

switch $FreeRunningRead_Result {
"TimeOut" {
puts " FreeRunningRead TimeOut"
}
"AKR" {
puts " FreeRunningRead = $MessageRead"
}
}

puts "Stop FreeRunningRead"
set mode "Waiting"
}

proc ForcedWrite { chid } {
global mode
global MessageRead
global Timeout
global FreeRunningRead_Result
global ForcedWrite_Result
global cnt

if {$mode == "FreeRunningRead"} {
vwait $FreeRunningRead_Result
}

set mode "ForcedWrite"
puts "Start ForcedWrite"

set cnt [expr $cnt + 1]
puts -nonewline $chid "Message Write $cnt"
puts -nonewline $chid \x0D
puts -nonewline $chid \x0A

set MessageRead ""
after $Timeout { set ForcedWrite_Result TimeOut }
vwait ForcedWrite_Result

switch $ForcedWrite_Result {
"TimeOut" {
puts " ForcedWrite TimeOut"
}
"AKW" {
puts " ForcedWrite = $MessageRead"
}
}

puts "Stop ForcedWrite"
set mode "Waiting"

}


wm protocol . WM_DELETE_WINDOW { exit }
button .b1 -text Quit -command {exit}
button .b2 -text Write -command {ForcedWrite $chid }
pack .b1
pack .b2

set HS_Loop 0
while {1} {
if {$mode == "Waiting" } {
after $LoopTime { set HS_Loop 1 }
vwait HS_Loop
FreeRunningRead $chid
} else {
after $LoopTime { set HS_Loop 1 }
vwait HS_Loop
}
}
From: dave.joubert on
On Dec 8, 11:47 pm, CKL <christian.klugesh...(a)gmail.com> wrote:
> Hi tcl gurus
>
> There is now 2 weeks that I try to find a solution to my problem
>
> Trying to play with after, vwait in all the direction, I pass now more
> then 2 weeks to find a solution, but Without success :-((
> It seems that my approach seems not to be good.
>

Looking at your code, I think a re-design is called for.

There are 2 design criteria that your code does not meet, that are
characteristic of a working design:

1) Instead of waiting on multiple different variables, you should wait
on the fewest number of possible variables, preferably only one. That
way every routine can (a) check what the current state is (b) you can
never end up in 'two states at once' (c) any routine that changes the
state can do so globally

2) Since you have expected events and unexpected events, you should:
a) always only 'block' on expected events, never on unexpected events.
b) buffer all your un-expected events (while waiting for expected
events) by putting them in a queue.
Only then handle the unexpected events queue when you are no longer
waiting for expected events.

Provided you follow (1) religiously, (2) can be made more complicated
by pushing and popping state on a stack.

Dave



From: CKL on
On 9 déc, 10:46, "dave.joub...(a)googlemail.com"
<dave.joub...(a)googlemail.com> wrote:
> On Dec 8, 11:47 pm, CKL <christian.klugesh...(a)gmail.com> wrote:
>
> > Hi tcl gurus
>
> > There is now 2 weeks that I try to find a solution to my problem
>
> > Trying to play with after, vwait in all the direction, I pass now more
> > then 2 weeks to find a solution, but Without success :-((
> > It seems that my approach seems not to be good.
>
> Looking at your code, I think a re-design is called for.
>
> There are 2 design criteria that your code does not meet, that are
> characteristic of a working design:
>
> 1) Instead of waiting on multiple different variables, you should wait
> on the fewest number of possible variables, preferably only one. That
> way every routine can (a) check what the current state is (b) you can
> never end up in 'two states at once' (c) any routine that changes the
> state can do so globally
>
> 2) Since you have expected events and unexpected events, you should:
> a) always only 'block' on expected events, never on unexpected events.
> b) buffer all your un-expected events (while waiting for expected
> events) by putting them in a queue.
> Only then handle the unexpected events queue when you are no longer
> waiting for expected events.
>
> Provided you follow (1) religiously, (2) can be made more complicated
> by pushing and popping state on a stack.
>
> Dave

Hi Dave

Thanks for the proposed criteria
I will try to follow your rules, and remodel completely the program.
Nevertheless, I think that the second point: "buffer all your un-
expected events" will not be easy.
I have no idea for the moment, how to store these events ??

Will be a hard think and not evident, and will see what I will propose
in the next 2 weeks :-)

In all the case, I suspected, when I wrote the message, that I would
have to take the problem in an different way.

Ok Lets go .....

Thanks for now Dave

Regards

Christian


From: dave.joubert on
Hi Christian,

On Dec 9, 6:00 pm, CKL <christian.klugesh...(a)gmail.com> wrote:
>
> Nevertheless, I think that the second point: "buffer all your un-
> expected events" will not be easy.
> I have no idea for the moment, how to store these events ??
>
>
> Christian

The obvious way may be the easiest:

set todoBuffCount 0
..
..
..
While

if {$mustBuffer} {



From: Uwe Klein on
CKL wrote:
> On 9 d�c, 10:46, "dave.joub...(a)googlemail.com"
> <dave.joub...(a)googlemail.com> wrote:
>
>>On Dec 8, 11:47 pm, CKL <christian.klugesh...(a)gmail.com> wrote:
>>
>>
>>>Hi tcl gurus
>>
>>>There is now 2 weeks that I try to find a solution to my problem
>>
>>>Trying to play with after, vwait in all the direction, I pass now more
>>>then 2 weeks to find a solution, but Without success :-((
>>>It seems that my approach seems not to be good.
>>
>>Looking at your code, I think a re-design is called for.
>>
>>There are 2 design criteria that your code does not meet, that are
>>characteristic of a working design:
>>
>>1) Instead of waiting on multiple different variables, you should wait
>>on the fewest number of possible variables, preferably only one. That
>>way every routine can (a) check what the current state is (b) you can
>>never end up in 'two states at once' (c) any routine that changes the
>>state can do so globally
>>
>>2) Since you have expected events and unexpected events, you should:
>>a) always only 'block' on expected events, never on unexpected events.
>>b) buffer all your un-expected events (while waiting for expected
>>events) by putting them in a queue.
>>Only then handle the unexpected events queue when you are no longer
>>waiting for expected events.
>>
>>Provided you follow (1) religiously, (2) can be made more complicated
>>by pushing and popping state on a stack.
>>
>>Dave
>
>
> Hi Dave
>
> Thanks for the proposed criteria
> I will try to follow your rules, and remodel completely the program.
> Nevertheless, I think that the second point: "buffer all your un-
> expected events" will not be easy.
> I have no idea for the moment, how to store these events ??
>
> Will be a hard think and not evident, and will see what I will propose
> in the next 2 weeks :-)
>
> In all the case, I suspected, when I wrote the message, that I would
> have to take the problem in an different way.

Have you looked into expect?
look into the exp_background command.

Couple of years ago I had to "connect" to lab scales that could
be commanded but also emmited loadcell values in second intervals
( actually programmable )

I matched all input from the scales in the background
evaluating incoming messages ( value or cmd reply )
setting state information in elements of an array variable.

All outgoing messages were queued and "timed" via state info in the same array.

uwe

 |  Next  |  Last
Pages: 1 2 3 4 5
Prev: ANNOUNCE: Jeszra ZERO-ONE
Next: PureTkGUI v0.9.0 is out