[Gambas-user] using events of serial ports for reading how_?

Tony Morehen tmorehen at ajm-software.com
Tue Aug 7 05:34:55 CEST 2018




-------- Forwarded Message --------
Subject: 	Re: [Gambas-user] using events of serial ports for reading how_?
Date: 	Mon, 6 Aug 2018 20:12:50 -0400
From: 	Tony Morehen <tmorehen at ajmconsulting.ca>
To: 	PICCORO McKAY Lenz <mckaygerhard at gmail.com>



In modern serial communications, there is almost no use for CTS, DCD, 
DSR, DTR,RNG, RTS, all of it at the driver level.  The driver handles 
all handshaking and flow control.  Further, your serial port reads and 
writes are not made directly to the serial port but to buffers in the 
driver.

You must remember that serial port communications are slow. That's the 
reason you have missing or leftover data. The sequence is something like:

1) Printer starts to send a line of data
2) Driver receives a byte, raises a read event
3) Your programs responds, likely before the end of the line, reading 
what's currently in the driver's buffer.
4) Printer finishes sending the rest of the line, triggering more read 
events.

Serial communications tend to be packet-based so your low level read 
routine should read an entire packet before raising a dataavailable event:

If each received byte is independent, say a instrument reading, raise a 
dataavailable event for every byte.

If a packet is fixed-length, raise the event every packet-length bytes.  
Fixed-length packets frequently have sync bytes between packets.  These 
should be ignored.  Decide how to handle partial packets.

Variable length packets have to be handled according to their 
structure.  Some will be packet followed by an end of packet marker.  
Raise the dataavailable event when your program encounters the marker.

Other variable-length packets will inclu


On 2018-08-06 05:10 PM, PICCORO McKAY Lenz wrote:
> um ok make sense that if there's already a event handler why use the 
> manual reading..
>
> the problem its that sometimes i made manual reading an get extra data 
> that are not in the event handler (yep sound quite strange) due i'm 
> managing a fiscal kit printer device
>
> i'll try to use your semaphore, but there's another way maybe using 
> the_CTSChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.ctschange>_
> _DCDChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.dcdchange>_ 
> _DSRChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.dsrchange>_ 
> _DTRChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.dtrchange>_ 
> _RNGChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.rngchange>_ 
> _RTSChange 
> <http://gambaswiki.org/wiki/comp/gb.net/serialport/.rtschange>_
> ??
>
> Lenz McKAY Gerardo (PICCORO)
> http://qgqlochekone.blogspot.com
>
>
> El lun., 6 de ago. de 2018 a la(s) 13:41, T Lee Davidson 
> (t.lee.davidson at gmail.com <mailto:t.lee.davidson at gmail.com>) escribió:
>
>     You will have problems if you try to utilize both an event
>     triggered serial port read and a manual read.
>
>     The SerialPort.Read event is triggered when there is data
>     available to be read. If you read that data in the event handler, the
>     port is cleared and there will be no data available to a manual read.
>
>     If you want to manually read the port, then you should not read
>     the data from it in the SerialPort.Read event handler. Perhaps
>     you do not even need to implement that event handler.
>
>     I could be incorrect since I haven't verified this. But, it seems
>     logical to me that Stream.Blocking would be False by default
>     otherwise an attempt to read the port would hang the application
>     until data is available and that should not be a default behavior.
>
>     I can think of two ways to implement manual reading.
>
>     1. Do not implement a SerialPort.Read event handler, ensure that
>     Stream.Blocking = False, and simply read the port manually
>     understanding that there may be no data available. In this case
>     READ would appear to do nothing, but the application would not hang.
>
>     2. Use the SerialPort.Read event handler to set a flag indicating
>     that data is available and read that flag in your Sub rp()
>     function. For example:
>
>     Private PortDataAvailable As Boolean
>
>     Public Sub SComm_Read()
>             PortDataAvailable = True
>     End
>
>     Public Sub rp()
>             If myDataAvailableBoolean then
>                     ' Do the port reading stuff
>                     ' Read port blah blah blah
>                     ' All data has been read
>                     PortDataAvailable = False
>             Else
>                     Print "No data available"
>                     Return
>             Endif
>     End
>
>
>     ___
>     Lee
>
>
>     On 08/06/2018 12:05 PM, PICCORO McKAY Lenz wrote:
>     > OK hans, and tobias, yes the code in my first mail last week was
>     bad,
>     > now i understant some problems when i read agains the printert
>     > but i need and i want a manual read funtion "also": so i have now:
>     >
>     > the read event for the port, as documents suggest "is triggered"
>     > when data "can be read" so if there's some data to read or available
>     > the event will be executed by itselft, but i want also a manual
>     "rp" method
>     > that read also the port manually, at this point i dont know
>     > if will be sync or async, i have a "sale" class that will be
>     polled into a form,
>     > but as Tobias said i used the Scom_Read
>     > but still need a manual read funtion due the inherits so i have :
>     >
>     > 1) the read event:
>     >
>     > ' this event will be triggered in read operations by the stream
>     when data its available
>     > Public Sub SComm_Read()
>     >    dim buffers as string = ''
>     >   Read #SComm, buffers, Lof(SComm)
>     >    dataread &= buffers
>     > End
>     >
>     > 2) here, how can i code a read manual operation do not conflict
>     if there's already an operation triggered by teh read event?
>     >
>     > i used some code proposed by Tobias but:
>     >
>     > '' generic read port buffer data
>     > Public Sub rp()
>     >    dim  start as date = Now
>     >    dim buffers as string = ''
>     >   Do
>     >     Wait 0.1
>     >     Read #SComm, buffers, Lof(SComm)
>     >     dataread &= buffers
>     >   Loop Until DateDiff(start, Now, gb.Millisecond) > 500
>     > End
>     >
>     > now i have the problem of locking, as Tobias said I not even
>     sure how Read
>     > behaves when Lof is zero or if the read are just triggered at
>     same time the rp was invoqued!
>     > so then reading would block.
>     >
>     > i dont know how to use the SComm.Blocking = False to make manual
>     polling,
>     >
>     >
>     > Lenz McKAY Gerardo (PICCORO)
>     > http://qgqlochekone.blogspot.com
>     >
>     >
>     > El lun., 6 de ago. de 2018 a la(s) 09:59, PICCORO McKAY Lenz
>     (mckaygerhard at gmail.com <mailto:mckaygerhard at gmail.com>
>     <mailto:mckaygerhard at gmail.com <mailto:mckaygerhard at gmail.com>>)
>     escribió:
>     >
>     >     El lun., 6 de ago. de 2018 a la(s) 09:52, Hans Lehmann
>     (hans at gambas-buch.de <mailto:hans at gambas-buch.de>
>     <mailto:hans at gambas-buch.de <mailto:hans at gambas-buch.de>>) escribió:
>     >
>     >         have a look at the chapters and the projects... under
>     https://www.gambas-buch.de/doku.php?id=k24:k24.1:k24.1.5:start!
>     >
>     >     THANKS HANS! now reading...
>     >      isend this mail to the list.. maybe you send too quickly
>     and forgett to do!
>     >
>     >
>     >
>     >
>     >
>     > ----[ Gambas mailing-list is hosted by
>     https://www.hostsharing.net ]----
>     >
>
>     ----[ Gambas mailing-list is hosted by https://www.hostsharing.net
>     ]----
>
>
>
> ----[ Gambas mailing-list is hosted byhttps://www.hostsharing.net  ]----




More information about the User mailing list