HBCOMM

1,093 views
Skip to first unread message

DaNiElMaXiMiLiAnO

unread,
Aug 4, 2011, 4:47:01 PM8/4/11
to Harbour Users
Hi
compile TEST.PRG in C:\hb31\contrib\hbcomm\tests
sending data to the comm port, but reading it does not receive any
data. I do something wrong?
there is any modification in the library that causes this?
I have installed HB3.1
Regards/Saludos

Hola :
compile Test.prg dentro de C:\hb31\contrib\hbcomm\tests
envio datos hacia el puerto comm, pero al leer el mismo no recibe
ningun dato. hago algo mal?
hay alguna modificacion en la libreria que causa esto?
tengo instalado HB3.1

DaNiElMaXiMiLiAnO

matt johnson

unread,
Aug 4, 2011, 5:33:29 PM8/4/11
to harbou...@googlegroups.com
I have not able to read serial data also. I have held off on updating from 2.0 because of this.

--- On Thu, 8/4/11, DaNiElMaXiMiLiAnO <danielma...@yahoo.com.ar> wrote:

> --
> You received this message because you are subscribed to the
> Google
> Groups "Harbour Users" group.
> Unsubscribe: harbour-user...@googlegroups.com
> Web: http://groups.google.com/group/harbour-users
>

Viktor Szakáts

unread,
Aug 4, 2011, 5:46:05 PM8/4/11
to harbou...@googlegroups.com
Please note that Harbour 2.0.0 didn't have HBCOMM support at all.

Now it's simple .prg wrapper over core portable serial functions, so 
if they don't work, pls look them up and try to fix them, or replace 
them with core or hbct serial API calls.

Viktor

Viktor Szakáts

unread,
Aug 4, 2011, 5:49:10 PM8/4/11
to harbou...@googlegroups.com
Some more food for thought:

If anyone bothers to look up contrib/hbcomm/comm.prg, 
she could find some revealing comments in it:

F.e.:

/* NOTE: INCOMPATIBILITY.
         In contratry to original HBCOMM, here <cData> must be passed by reference.
         HBCOMM could corrupt HVM because of its buggy way of returning data.
         [vszakats] */
/* Fetch <nCount> chars into <cData> */
FUNCTION INCHR( nPort, nCount, /* @ */ cData )

Rest is worth reading, too.

Viktor

DaNiEl MaXiMiLiAnO

unread,
Aug 4, 2011, 6:18:48 PM8/4/11
to harbou...@googlegroups.com
Victor says "Some more food for thought:"

Thanks: take it into account next time
 
Saludos
                DaNIEl MaXiMiLiAnO


De: Viktor Szakáts <harbo...@syenar.hu>
Para: harbou...@googlegroups.com
Enviado: jueves, 4 de agosto de 2011 18:49
Asunto: Re: [harbour-users] HBCOMM

Viktor Szakáts

unread,
Aug 4, 2011, 6:50:55 PM8/4/11
to harbou...@googlegroups.com, DaNiEl MaXiMiLiAnO
I'd be helpful to see whether the quoted incompatibility comment 
helped fixing your serial code. Please remember original HBCOMM 
implementation had a serious memory corruption bug, which is not 
replicated in Harbour's implementation. Though this could only be 
done by adding this slight incompatibility.

Viktor

DaNiEl MaXiMiLiAnO

unread,
Aug 4, 2011, 6:58:29 PM8/4/11
to harbou...@googlegroups.com
Victor:
               my question is this thread in HMGforum, but also helps me in an application that also manages ports mine communications

Victor:
              mi consulta viene por este hilo dentro de HMGforum, pero me ayuda tambien en una aplicacion mia que tambien maneja puertos comunicaciones
http://hmgforum.com/viewtopic.php?f=24&t=2043
Regards/Saludos
DaNiElMaXiMiLiAnO
 
Saludos
                DaNIEl MaXiMiLiAnO

CC: DaNiEl MaXiMiLiAnO <danielma...@yahoo.com.ar>
Enviado: jueves, 4 de agosto de 2011 19:50
Asunto: Re: [harbour-users] HBCOMM

Claudia Neumann

unread,
Aug 5, 2011, 7:00:45 AM8/5/11
to harbou...@googlegroups.com, DaNiEl MaXiMiLiAnO
Hi!

I just succeeded to program COM port communication with hbwin ( win_com:init(),
win_com:write(), win_com:read() and win_com:close() ) on WinXP.

Regards

Claudia


Am Freitag August 5 2011 schrieb DaNiEl MaXiMiLiAnO:
> Victor says &quot;Some more food for thought:&quot;


>
> Thanks: take it into account next time
>
> Saludos
> DaNIEl MaXiMiLiAnO
>
>
> ________________________________

> De: Viktor Szakáts &lt;harbo...@syenar.hu&gt;


> Para: harbou...@googlegroups.com
> Enviado: jueves, 4 de agosto de 2011 18:49
> Asunto: Re: [harbour-users] HBCOMM
>
>
> Some more food for thought:
>
> If anyone bothers to look up contrib/hbcomm/comm.prg,
> she could find some revealing comments in it:
>
> F.e.:
>
> /* NOTE: INCOMPATIBILITY.

> In contratry to original HBCOMM, here &lt;cData&gt; must be passed


> by reference. HBCOMM could corrupt HVM because of its buggy way of
> returning data. [vszakats] */

> /* Fetch &lt;nCount&gt; chars into &lt;cData&gt; */

Viktor Szakáts

unread,
Aug 5, 2011, 7:08:01 AM8/5/11
to harbou...@googlegroups.com, DaNiEl MaXiMiLiAnO
Hi Claudia,

Thanks for your report, however it's important to see that HBWIN COM 
functions are not using Harbour core serial API, so they are something 
different, it's a more limited set of functions and most importantly they 
are not portable.

I'd be interested to see tests using HBCOMM API, after making the 
suggested modification in API calls.

Viktor

Przemysław Czerpak

unread,
Aug 5, 2011, 7:58:14 AM8/5/11
to harbou...@googlegroups.com
On Fri, 05 Aug 2011, Claudia Neumann wrote:

Hi,

> I just succeeded to program COM port communication with hbwin ( win_com:init(),
> win_com:write(), win_com:read() and win_com:close() ) on WinXP.

It's not portable windows only library so we suggest to no
use it.

Harbour has native portable serial port support.
It's set of hb_com*() functions which are part of RTL
which works very well with windows, dos, os2 and *nixes.
I use it extensively with many different serial devices
with different OS-es.
In HBCT3 we have also CTIII compatible set of COM_*()
functions which internally use core HBRTL hb_com*() C API.
This both interfaces are officially supported by us.
In contrib we have also HBTPATHY and HBCOMM libraries.
These are PRG level wrappers to HBRTL HB_COM*() interface
HBTPATHY implements some small subset of Clipper's Telepathy
library functions which is enough for many programs.
HBCOMM is wrapper to old serial port library distributed for
Harbour and xHarbour which from the beginning is very buggy
and never reached production state though it was extensively
promoted in the past. We had to fix some critical bugs in
this wrapper and it's possible that such fixes exploited
bugs in users code, i.e. when users made sth like:

cData := " "
INCHR( nPort,, cData )

instead of:

cData := " "
INCHR( nPort,, @cData )

BTW Viktor, were can I find original HBCOMM code to check
for other possible differences?

best regards,
Przemek

Claudia Neumann

unread,
Aug 5, 2011, 8:25:13 AM8/5/11
to harbou...@googlegroups.com
Hi Viktor,

is hbcomm working on Linux? I tried some time ago (2 years?) hbcomm in xHarbour
on Linux and it wouldn't work. So I made my own lib especially for use with card
reading devices.

Regards

Claudia

Przemysław Czerpak

unread,
Aug 5, 2011, 8:57:08 AM8/5/11
to harbou...@googlegroups.com
On Fri, 05 Aug 2011, Claudia Neumann wrote:

Hi Claudia,

> is hbcomm working on Linux? I tried some time ago (2 years?) hbcomm in xHarbour
> on Linux and it wouldn't work. So I made my own lib especially for use with card
> reading devices.

Please forget about HBCOMM. This library was never working correctly.
Current HBCOMM in Harbour SVN is wrapper to native serial port support
in Harbour. It should work but is not bug compatible with original
implementation so existing code has to be updated in some cases.
Instead of HBCOMM use native Harbour serial port functions which are
part of Harbour RTL.
Below is list of PRG level serial functions: HB_COM*().
You can also use COM_*() functions from HBCT library.
Both interfaces use the same low level C code from Harbour RTL and
they work on all platforms (DOS, Win, OS2, *nixes).

BTW This CT3 COM implementation is more completed then the commercial
one sold by xHarbour.com. It also works on all platforms.

best regards,
Przemek

// #include "hbcom.ch"
HB_COMCLOSE( nPort ) --> lSuccess
HB_COMDISCARDCHAR( nPort, nChar | cChar ) --> lSuccess
HB_COMERRORCHAR( nPort, nChar | cChar ) --> lSuccess
HB_COMFLOWCHARS( nPort, nXONchar | cXONchar, nXOFFchar | cXOFFchar ) --> lSuccess
HB_COMFLOWCONTROL( nPort, @nOldFlow [, nNewFlow] ) --> lSuccess
HB_COMFLOWSET( nPort, nFlow ) --> lSuccess
HB_COMFLUSH( nPort, [ nType = HB_COM_IOFLUSH ] ) --> lSuccess
HB_COMGETDEVICE( nPort ) --> cDeviceName
HB_COMGETDEVICEHANDLE( nPort ) --> nHandle | F_ERROR
HB_COMGETERROR( nPort ) --> nError
HB_COMGETOSERROR( nPort ) --> nError
HB_COMINIT( nPort, nBaud, cParity, nSize, nStop ) --> lSuccess
HB_COMINPUTCOUNT( nPort ) --> nCount
HB_COMINPUTSTATE( nPort ) --> nState
HB_COMLASTNUM() --> nLastPortNumber
HB_COMLSR( nPort, @nValue ) --> lSuccess
HB_COMMCR( nPort, @nValue, nClear, nSet ) --> lSuccess
HB_COMMSR( nPort, @nValue ) --> lSuccess
HB_COMOPEN( nPort ) --> lSuccess
HB_COMOUTPUTCOUNT( nPort ) --> nCount
HB_COMOUTPUTSTATE( nPort ) --> nState
HB_COMSENDBREAK( nPort, [ nDuration = 50 ] ) --> lSuccess
HB_COMSETDEVICE( nPort, cDeviceName ) --> lSuccess
HB_COMSETERROR( nPort, nError ) --> NIL
HB_COMRECV( nPort, @cBuffer, [ nLen = LEN( cBuffer ) ], [ nTimeout = 0 ] ) --> nBytesRecv
HB_COMSEND( nPort, cBuffer, [ nLen = LEN( cBuffer ) ], [ nTimeout = 0 ] ) --> nBytesSent

Viktor Szakáts

unread,
Aug 5, 2011, 9:35:33 AM8/5/11
to harbou...@googlegroups.com
Hi Przemek,

I used the Harbour MiniGui implementation as the base.
(it may be different from xhb implementation, which I don't know)

this repo:
   cvs -z3 -d:pserver:anon...@hmgs-minigui.cvs.sourceforge.net:/cvsroot/hmgs-minigui co -P minigui

then this dir:
   minigui/SOURCE/HbComm

It consists of a 3rd party, win-only serial code in C++ plus 
some C glue for Harbour.

Viktor

Claudia Neumann

unread,
Aug 5, 2011, 8:37:42 AM8/5/11
to harbou...@googlegroups.com
Hi Przemek,

okay, will look into that.

Regards

Claudia

Claudia Neumann

unread,
Aug 8, 2011, 4:45:23 PM8/8/11
to harbou...@googlegroups.com, Przemysław Czerpak
Hi Przemek,

I need help because I can't get the /dev/ttyS0 initialized.
System: Linux Debian Squeeze.

nkvkcom := 1
lresult := hb_comInit( nkvkcom, 9600, "E", 8, 1 )

lresult is .f.

The Code I normally initialize the serial port in Linux is:

port = open (device, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (port < 0) return ERR_INVALID;
if(tcgetattr(port,&tios)==-1)err(1,NULL);
tios.c_iflag&=~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|
IUCLC|IXON|IXANY|IXOFF|IMAXBEL);
tios.c_oflag&=~OPOST;
tios.c_cflag&=~(CSTOPB|PARODD|CRTSCTS);
tios.c_cflag|=PARENB|CLOCAL;
tios.c_lflag&=~(ISIG|ICANON|XCASE|ECHO);
tios.c_cc[VTIME]=0;
cfsetspeed(&tios,B9600);
if(tcsetattr(port,TCSANOW,&tios)==-1)err(1,NULL);
if(tcflush(port,TCIOFLUSH)==-1)err(1,NULL);
flags=fcntl(port,F_GETFL);
if(flags==-1)err(1,NULL);
if(fcntl(port,F_SETFL,flags&~O_NONBLOCK)==-1)err(1,NULL);
if(flags==-1)err(1,NULL);

How should I code it in Harbour? I tried modfications of rtl/hbcom.c but didn't
succeed.

How about /dev/ttyACM0 or /dev/ttyUSB0 with 115200 Baud? Some devices use
virtual COM port and are mapped to these devices by the kernel.

Best regards

Claudia

Przemysław Czerpak

unread,
Aug 8, 2011, 7:55:39 PM8/8/11
to harbou...@googlegroups.com
On Mon, 08 Aug 2011, Claudia Neumann wrote:

Hi Claudia,

> I need help because I can't get the /dev/ttyS0 initialized.

> System: Linux Debian Squeeze.
> nkvkcom := 1
> lresult := hb_comInit( nkvkcom, 9600, "E", 8, 1 )
> lresult is .f.

Before you can initialize the port you have to open it, i.e.
lresult := hb_comOpen( nkvkcom ) .and. ;


hb_comInit( nkvkcom, 9600, "E", 8, 1 )

> The Code I normally initialize the serial port in Linux is:


> port = open (device, O_RDWR | O_NOCTTY | O_NONBLOCK);
> if (port < 0) return ERR_INVALID;
> if(tcgetattr(port,&tios)==-1)err(1,NULL);
> tios.c_iflag&=~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|
> IUCLC|IXON|IXANY|IXOFF|IMAXBEL);
> tios.c_oflag&=~OPOST;
> tios.c_cflag&=~(CSTOPB|PARODD|CRTSCTS);
> tios.c_cflag|=PARENB|CLOCAL;
> tios.c_lflag&=~(ISIG|ICANON|XCASE|ECHO);
> tios.c_cc[VTIME]=0;
> cfsetspeed(&tios,B9600);
> if(tcsetattr(port,TCSANOW,&tios)==-1)err(1,NULL);
> if(tcflush(port,TCIOFLUSH)==-1)err(1,NULL);
> flags=fcntl(port,F_GETFL);
> if(flags==-1)err(1,NULL);
> if(fcntl(port,F_SETFL,flags&~O_NONBLOCK)==-1)err(1,NULL);
> if(flags==-1)err(1,NULL);
> How should I code it in Harbour?

Harbour open serial devices in raw mode by default.

> I tried modfications of rtl/hbcom.c but didn't succeed.

Please leave it as is or you create new problem yourself and then
you will look for workarounds just lik in case of euro char ;)
If you think that some functionality is missing please inform
me about it on this list.

BTW do you know why you had problem with euro char?
Hint: look at the difference between CP850 and CP858.

> How about /dev/ttyACM0 or /dev/ttyUSB0 with 115200 Baud? Some devices use
> virtual COM port and are mapped to these devices by the kernel.

Look at the list of hb_com*() functions I attached to my previous email.

? hb_comGetDevice( 1 )
hb_comSetDevice( 1, "/dev/ttyUSB0" )
? hb_comGetDevice( 1 )
? hb_comOpen( 1 ) .and. ;
hb_comInit( 1, 9600, "E", 8, 1 )

You have HB_COM_PORT_MAX (256) slots you can use for it, i.e.:
hb_comSetDevice( 200, "/dev/ttyACM0" )
? hb_comOpen( 200 ) .and. hb_comInit( 200, 9600, "E", 8, 1 )

In the future I'll add also new function:
hb_comOpenDev( <cDeviceName> ) -> <nPort>
If you need it now you can implement such function using simple FOR
loop. hb_comOpen() returns .F. for already open ports.

best regards,
Przemek

Claudia Neumann

unread,
Aug 9, 2011, 1:02:46 PM8/9/11
to harbou...@googlegroups.com, Przemysław Czerpak
Hi Przemek,

Am Dienstag August 9 2011 schrieb Przemysław Czerpak:
> On Mon, 08 Aug 2011, Claudia Neumann wrote:
>
> Hi Claudia,
>
> > I need help because I can't get the /dev/ttyS0 initialized.
> > System: Linux Debian Squeeze.
> > nkvkcom := 1
> > lresult := hb_comInit( nkvkcom, 9600, "E", 8, 1 )
> > lresult is .f.
>
> Before you can initialize the port you have to open it, i.e.
> lresult := hb_comOpen( nkvkcom ) .and. ;
> hb_comInit( nkvkcom, 9600, "E", 8, 1 )

Okay, now I get the port opened. I can send data to the port, but still can't
get anything back. The card reader won't answer. There still must be something
wrong with the communication. As I said, I have a working C lib, so I have to
compare the parameters.


> Harbour open serial devices in raw mode by default.
>
> > I tried modfications of rtl/hbcom.c but didn't succeed.
>
> Please leave it as is or you create new problem yourself and then
> you will look for workarounds just lik in case of euro char ;)
> If you think that some functionality is missing please inform
> me about it on this list.
>
> BTW do you know why you had problem with euro char?
> Hint: look at the difference between CP850 and CP858.

Oh, that is working fine for me. Modification of src/codepage/cpde850.c didn't
do anything, because somehow src/rtl/cdpapi.c was the file, that was executed. I
put several modifications in cdpapi.c like Euro, §, µ, ¼ and ½ and that works
fine along with german umlauts.

> In the future I'll add also new function:
> hb_comOpenDev( <cDeviceName> ) -> <nPort>
> If you need it now you can implement such function using simple FOR
> loop. hb_comOpen() returns .F. for already open ports.

Fine, will test that if I get the communication with the card readers working.
If I get it going, I will tell you.

Best regards

Claudia

Przemysław Czerpak

unread,
Aug 9, 2011, 1:36:45 PM8/9/11
to Claudia Neumann, harbou...@googlegroups.com
On Tue, 09 Aug 2011, Claudia Neumann wrote:

Hi Claudia,

> Okay, now I get the port opened. I can send data to the port, but still can't

> get anything back. The card reader won't answer. There still must be something
> wrong with the communication. As I said, I have a working C lib, so I have to
> compare the parameters.

Have you set flow control?
How did you check that you can send data?

> > BTW do you know why you had problem with euro char?
> > Hint: look at the difference between CP850 and CP858.
> Oh, that is working fine for me. Modification of src/codepage/cpde850.c didn't
> do anything, because somehow src/rtl/cdpapi.c was the file, that was executed. I
> put several modifications in cdpapi.c like Euro, §, µ, ¼ and ½ and that works
> fine along with german umlauts.

So you still do not understand what is wrong and you are "fixing" working
code introducing serious bugs and the problem is trivial to solve.
It also means that you ignored my messages in which I was asking you to
set correct codepage. The fact that modifications in "EN" CP from
src/rtl/cdpapi.c gives you any effect confirms that you are still using
wrong CP in your code.
Probably you are still have in you code sth like:
HB_CDPSELECT( "DE" )
and "DE" CP does not exist in Harbour VM so default "EN" is used.
When we introduce unicode string items to HVM all such hacks can create
serious troubles, i.e. index corruptions so I suggest to look for real
solution. Sooner or later you will have to make it.

> > In the future I'll add also new function:
> > hb_comOpenDev( <cDeviceName> ) -> <nPort>
> > If you need it now you can implement such function using simple FOR
> > loop. hb_comOpen() returns .F. for already open ports.
> Fine, will test that if I get the communication with the card readers working.
> If I get it going, I will tell you.

I'm waiting for your results.

best regards,
Przemek

Przemysław Czerpak

unread,
Aug 9, 2011, 3:12:10 PM8/9/11
to Claudia Neumann, harbou...@googlegroups.com
On Mon, 08 Aug 2011, Claudia Neumann wrote:

Hi Claudia,

> lresult := hb_comInit( nkvkcom, 9600, "E", 8, 1 )


> The Code I normally initialize the serial port in Linux is:
> port = open (device, O_RDWR | O_NOCTTY | O_NONBLOCK);
> if (port < 0) return ERR_INVALID;
> if(tcgetattr(port,&tios)==-1)err(1,NULL);
> tios.c_iflag&=~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|
> IUCLC|IXON|IXANY|IXOFF|IMAXBEL);
> tios.c_oflag&=~OPOST;
> tios.c_cflag&=~(CSTOPB|PARODD|CRTSCTS);
> tios.c_cflag|=PARENB|CLOCAL;
> tios.c_lflag&=~(ISIG|ICANON|XCASE|ECHO);
> tios.c_cc[VTIME]=0;
> cfsetspeed(&tios,B9600);
> if(tcsetattr(port,TCSANOW,&tios)==-1)err(1,NULL);
> if(tcflush(port,TCIOFLUSH)==-1)err(1,NULL);
> flags=fcntl(port,F_GETFL);
> if(flags==-1)err(1,NULL);
> if(fcntl(port,F_SETFL,flags&~O_NONBLOCK)==-1)err(1,NULL);
> if(flags==-1)err(1,NULL);

This C code is not correct and it's behavior is random.
1) it does not set character size so it can be 5, 6, 7, 8
depending on port parameters set by other application
executed before your code.
2) You enabled parity even on outupt and disabled parity checking on input.
It means that this code can accept some characters even if they are not
correctly received, i.e. due to wrong character size, parity or stop bit
settings so it's possible that correct line parameters are not 8E1 but
sth completly different.

Please fix this code and test corrected version then you should be able
to find exact port setting which should be used with Harbour and other
applications.

best regards,
Przemek

Claudia Neumann

unread,
Aug 9, 2011, 3:34:01 PM8/9/11
to Przemysław Czerpak, harbou...@googlegroups.com
Hi Przemek,

could you give me a short code example howto to use hb_com*() in Linux.
Something like contrib/hbwin/tests/testcom1.prg.

Best regards

Claudia


Am Dienstag August 9 2011 schrieb Przemysław Czerpak:

Viktor Szakáts

unread,
Aug 9, 2011, 4:03:19 PM8/9/11
to harbou...@googlegroups.com, Przemysław Czerpak
Find .prg examples in:

contrib/hbsms
contrib/hbcomm
contrib/hbtpathy 

Viktor

Przemysław Czerpak

unread,
Aug 9, 2011, 4:24:41 PM8/9/11
to harbou...@googlegroups.com
On Tue, 09 Aug 2011, Claudia Neumann wrote:

Hi Claudia,

> could you give me a short code example howto to use hb_com*() in Linux.
> Something like contrib/hbwin/tests/testcom1.prg.

As Viktor show you have such examples in SVN.
Anyhow I'm attaching simple test which make similar operations
to the one in above test but I have just written it and cannot
make any real life tests now so some typos are possible.

best regards,
Przemek

testcom1.prg
Reply all
Reply to author
Forward
0 new messages