News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Serial Communications

Started by msmith, December 30, 2005, 05:06:33 AM

Previous topic - Next topic

msmith

Is there any way to receive an event when a character arrives in the UART?

The discontinued WMCOMMNOTIFY event apparently did this before it was discontinued.

MichaelW

eschew obfuscation

msmith

Michael,

According to MSDN, "The WaitCommEvent function should be executed as an overlapped operation so the other threads of the process can perform I/O operations during the wait."

So if I don't use an overlapped operation, the WaitCommEvent will block.

I don't wont to use overlapped I/O, so the WaitCommEvent will not help me.

Originally, MS had WM_COMMNotify which was similar to every other OS that I am familiar with. Too bad they took it out.

If you type in "Serial Communications" to GOOGLE, you will see that many people feel the same way.

Mike

P1

AFAIK, I have seen several OEMs ( of equipment connected to serial ports ) go to custom drivers to gain control lost in Win32 API.

Otherwise, you are limited to what is in the Win32 API.

Could you share some more detail on what you are doing???  I support several Comm port apps ( Though, I do it with mixed languages. ) , so I'm curious to find out.

Regards,  P1  :8)

msmith

P1,

Thanks for the interest and advice.

Quote
Could you share some more detail on what you are doing???  I support several Comm port apps ( Though, I do it with mixed languages. ) , so I'm curious to find out.

The answer is twofold.

First I am developing a high-performance BASIC compiler which uses FASM as a backend. This means I need to offer communications capability for the users of the compiler.

Second, I am a user of the compiler, and I am developing a data aquisition system for Plastic Molding Machines to archive and analize the shot data from the machines. The machines output 1 to 2K data blocks of unsolicited data with no handshaking at 9600 Baud.

In some cases these machines are equipped with wireless transmitters which transmit to a "server" radio that then encodes their data into a 57600 KBaud stream. We then demultiplex this data stream to make it appear that the data came from 16 individual machines. In this case we use RTS/CTS handshaking.

The communication is working fine right now by polling in a dedicated thread. This works fine, but I would rather use received char events.

Regards,

Mike

P1

Quote from: msmith on December 31, 2005, 04:05:36 AMSecond, I am a user of the compiler, and I am developing a data aquisition system for Plastic Molding Machines to archive and analize the shot data from the machines. The machines output 1 to 2K data blocks of unsolicited data with no handshaking at 9600 Baud.

In some cases these machines are equipped with wireless transmitters which transmit to a "server" radio that then encodes their data into a 57600 KBaud stream. We then demultiplex this data stream to make it appear that the data came from 16 individual machines. In this case we use RTS/CTS handshaking.

The communication is working fine right now by polling in a dedicated thread. This works fine, but I would rather use received char events.
Are you working with RJG ???  Or you custom capturing output straight from the Press ???  What are the makes of your Presses you are capturing from ???  In case you had not guessed, I work for a custom molder myself.

The simplest solution, if you are still wanting event control at the character level, is to setup a WIN98SE as intermediate collector to pass data to the local network ( or media for offline analysis. ).  As an option, the Win98SE, can be setup as a VM session as well.

Regards,  P1  :8)

P1

Quote from: msmith on December 31, 2005, 04:05:36 AMFirst I am developing a high-performance BASIC compiler which uses FASM as a backend. This means I need to offer communications capability for the users of the compiler.
If this becomes to much of a job, checkout:  http://www.powerbasic.com/  Built from the ground up from assembly.  Does inline so well, it will convert you.

Regards,  P1  :8)

msmith

P1,

Quote
If this becomes to much of a job, checkout:  http://www.powerbasic.com/  Built from the ground up from assembly.  Does inline so well, it will convert you.

I know that hutch and now you are a fan of PowerBASIC, so I don't want to start a flame. OmniBasic has been around over 10 years, and has always existed as a c output compiler. Even as such, it ran circles around PowerBASIC. If you have access to old (9 years?) newsgroup archives you can see for yourself. OmniBasic has always had macros and in these newsgroup posts you will see that the PowerBASIC people poo-pooed them. Now years later, when they have them, there the best thing since sliced bread. One of the PowerBASIC users at that time accused OmniBasic of being on steroids. Dave Navarro, then on the PowerBASIC staff, had kind words to say about it.

OmniBasic will be released in the near future as an assembler output compiler, and is even faster than the old OmniBasic that always beat PowerBASIC. It has based variables, inline asm, tables, pointers, and much much more. It is a higher level compiler then PowerBasic in that you can approach it with absolutely no knowledge of the Win32 API (not even knowing what a handle is) yet you can do low level things if you desire including inline asm without declaration (the assembler opcode set and directives are keywords just like the BASIC keywords). Like PowerBASIC, it generates very small executables.

It comes standard with colorized editor, GUI program builder, event dropdowns, grid control, console and GUI compiler and many other features that are in-house and 3rd party addons with PB.


The old OmniBasic and the new compiler are both self compiling. That is to say that OmniBasic source code is OmniBasic. This is not true of PowerBasic.

The real test of any compiler is whether is is powerful enough to write a compiler such as itself, and the choice of the compiler writer of which language to write his compiler in is a test of his idea of what a good language really is.

Quote
Are you working with RJG ???  Or you custom capturing output straight from the Press ???  What are the makes of your Presses you are capturing from ???  In case you had not guessed, I work for a custom molder myself.

RJG is used to analize details of parameters of a molding cycle by adding transducers to the press. I'm sure you know this. What we do as you aluded to, is capturing shot data from Toyo molding machines. For machines that are not Toyo, we install a PLC and capture selected data and encode it into Toyo format.

Quote
The simplest solution, if you are still wanting event control at the character level, is to setup a WIN98SE as intermediate collector to pass data to the local network ( or media for offline analysis. ).

We currently run a VB program that is both a host and client (depending on the config file settings) that collects data on one host and is accessed by any number of clients. We are currently converting the host function to a box running an OmniBasic program that gathers the data more efficiently.

Thanks again for your help and suggestions.

Regards,

Mike

msmith

P1,

What kind of presses do you work with and what kind of monitoring software do you use.

Regards,

Mike

P1

Van Dorn, Toshiba and Krauss Maffei.

We have some older RJG Software Monitors.  Mostly transducers hooked up to PLCs.  I have written some monitoring software to collect data.  We do this for mostly automotive parts, but not normally for other product.

Regards,  P1  :8)

msmith

#10
Quote
Van Dorn, Toshiba and Krauss Maffe

I'm familiar with Van Dorn and Toshiba, but not Krauss Maffe.

I just tested my new data aquisition using polling in a thread, and I am able to receive 57600 with no handskaking.

Other programs that are are already running do not seem to be adversly affected, but loading new programs or even opening a file dialog is painfully slow. It appears that putting new processes in the queue is where the slowdown mostly occurs.

Two nights ago, I tried changing the task priority to a higher priority and it almost froze the system. It took forever to have any response to the exit buttton, so I tried to invoke the task manager. It took forever. So now I just run the thread at the default priority.

The fact that the thread slows down the loading of other programs etc. will not hurt us in this dedicated server application, but for general purpose use it leaves much to be desired. It seems like the unix type systems are much better at process multiplexing and threads and the like than Windows.

My partner noticed that when the program is running with the thread at default priority, the CPU Usage display stays at 100%.

In an earlier post you mentioned something about custom drivers. Are they available? How do they signal your process in an event or interrupt? How much do they cost?

In case you are wondering, I don't have a real Toyo here in the room. I use another computer to send captured shots. <g>

I was hoping that someone sold an addon to Windows that would restore the WM_COMMNOTIFY event.

The last problem in my server project is the strange way that VB stores structures. On the 2D arrays, they store in the form col/row even though the programmer provides row/col. Even worse, they alway allocate on more dimension in an array than specified. In this case arrays inside of types specified at 16, allocate 17.

One other problem in the project is the need to work with MS DateTime. So far I have not been able to locate these functions in MSDN, but they must be there.
(I just found them)

Regards,

Mike

MichaelW

I suspect that the high CPU utilization is due entirely to inefficiencies. Perhaps you could do better with a thread, that uses WaitCommEvent, that receives, filters, and buffers the characters, and periodically generates an event that triggers a transfer of multiple characters.




eschew obfuscation

zooba

It (the high CPU) may also be due to the fact that it's constantly polling and never deferring. Put a 'Sleep 0' command in there and it'll probably drop to near zero :U

msmith

MichaelW,

I may be mistaken, but, the way I understand WaitCommEvent without overlapped I/O results in a block situation. If this is true then is is not much different than what I am already doing with ClearCommError and examining the cbInQue member of the COMSTAT structure. I am receiving multiple characters if they are available in the recieve buffer. In other words, I am receiveing the nuber of characters in the cbInQue member. All of this is inside a thread.

zooba,

I put in the Sleep 0 you suggested an all is well as far as the process hogging is concerned. BTW, the CPU usage still shows 100%

With the Sleep 0 in the code, the SetThreadPriority situation is as follows:

normal (0) works fine
min (-2) works fine
belownormal (-1) works fine
abovenormal (1) hogs
max (2) hogs

Thanks to both of you.

Here is the code segment that does what we have been discussing. It is inside a thread (near the beginning.  It is <unoptimized> code from my compiler in fasm format. The BASIC statements are shown as comments.


; LN:485 BEGIN LOOP
_Lbl106:
; LN:486 FOR CommNum=FirstCommPort TO LastCommPort
mov eax,[FirstCommPort]
mov [CommNum],eax
mov eax,[LastCommPort]
mov [_LopVec2],eax
_Lbl108:
mov eax,[CommNum]
cmp eax,[_LopVec2]
jg _Lbl110
; LN:487 CommBuf=OBComm1(CommNum).INPUTBUFFER
mov edi,OBComm1
mov [!SourceGUIDesc],edi
mov eax, dword [CommNum]
dec eax
imul eax,96
add edi,eax
mov [!SourceGUIDesc],edi
mov [XferCount],0
mov eax,edi
add eax,!CommStatusOffs
invoke ClearCommError, dword [edi+!HandleOffs],CommError,eax
mov edi,[!SourceGUIDesc]
mov eax,[edi+!cbInQueOffs]
cmp eax,0
mov [_IOBuffer+12],0
je _Lbl111
invoke ReadFile, dword [edi+!HandleOffs],[_IOBuffer],eax,XferCount,0
mov [STATUS],eax
mov eax,_IOBuffer+13
add eax,[XferCount]
mov byte [eax],0
_Lbl111:
mov edi,CommBuf
mov esi,_IOBuffer
call __MovStr
; LN:488 Bytes(CommNum)=Bytes(CommNum)+XferCount
mov esi,Bytes-(1*4)
mov eax, dword [CommNum]
shl eax,2
add esi,eax;
mov [_TmpVec1],esi
mov esi,Bytes-(1*4)
mov eax, dword [CommNum]
shl eax,2
add esi,eax;
mov [_TmpVec2],esi
mov edi,[_TmpVec2]
mov eax, dword [edi]
mov edx, dword [XferCount]
add eax,edx
mov esi,[_TmpVec1]
mov dword [esi],eax
; LN:489 IF XferCount>0 THEN
cmp [XferCount],0
jle _Lbl112
; LN:490 FOR RawCharCtr=1 TO XferCount
mov [RawCharCtr],1
mov eax,[XferCount]
mov [_LopVec3],eax
_Lbl113:
mov eax,[RawCharCtr]
cmp eax,[_LopVec3]
jg _Lbl115
; LN:491 CommChar(CommNum)=MID(CommBuf,RawCharCtr,1)
mov esi,CommChar-(1*1)
mov eax, dword [CommNum]
add esi,eax;
mov [_TmpVec1],esi
mov [_TmpVec1+4],1
mov [_TmpVec1+8],0
mov edi,[CommBuf]
mov [_TmpVec2],edi
mov edi,[CommBuf+4]
mov [_TmpVec2+4],edi
mov edi,[CommBuf+8]
mov [_TmpVec2+8],edi
mov esi,_TmpVec2
mov eax, dword [RawCharCtr]
mov edx,1
call __MidStr
mov edi,_TmpVec1
mov esi,_TmpVec2
call __MovStr
; LN:492 CommByte(CommNum)=ASC(CommChar(CommNum))
mov esi,CommByte-(1*1)
mov eax, dword [CommNum]
add esi,eax;
mov [_TmpVec1],esi
mov esi,CommChar-(1*1)
mov eax, dword [CommNum]
add esi,eax;
mov [_TmpVec2],esi
mov [_TmpVec2+4],1
mov [_TmpVec2+8],0
mov esi,[_TmpVec2]
mov al, byte [esi]
mov esi,[_TmpVec1]
mov byte [esi],al
; LN:493 CALL SUB ProcessData
call ProcessData
; LN:494 NEXT RawCharCtr
_Lbl114:
inc [RawCharCtr]
jmp _Lbl113
_Lbl115:
; LN:495 END IF
_Lbl112:
; LN:496 NEXT CommNum
_Lbl109:
inc [CommNum]
jmp _Lbl108
_Lbl110:
; LN:497 SLEEP 0
mov eax,0
invoke Sleep,eax
; LN:498 END LOOP
jmp _Lbl106



msmith

I have now set up my program for hardware handshaking. Hyperterm seems to be ignoring RTS.

The fbits returned after doing a Createfile, GetCommState, and SetCommState show as follows:

With RTS=0 $0011
With RTS=1 $1011
With RTS=2 $2011

This appears to be correct to me.

I selected "hardware handshaking" on the sending computer's Hyperterm.

If I set RTS=0, it should drop the RTS line and Hyperterm should not send anything until the RTS line is raised, but it sends as if it is ignoring my RTS signal.

I am suspicious that Hyperterm uses DSR/DTR handskaking, but searching their docs and using Google, I cannot find out what type of handshaking they use.

I don't have a meter or scope with me, so I can't look at the signals here.

Any help appreciated.