Chr(0) and rs232 communication

Recommended Posts

Keymaker 0

Keymaker 0

Below is a script I have been writing to control a DirecTV satellite receiver Set Top Box (STB). The STB requires a sequence of Hex bytes be sent to it via rs232 serial. I am using the MScomm object to communicate with the STB.

The problem is the Chr(0) data character. I can send any other data byte fine and the STB responds accordingly. But for some reason Chr(0) does not transmit properly. I do not think it is the MScomm object, as I have tried NetCommX with the same results.

Has anyone found a workaround for this problem yet? I have scoured the AutoIT forums and found a couple of links where others have reported the same issue:

The relevant part of my code is included in this post. In the data array below, the "0x00" byte is not recognized by the STB but all other data bytes are. Also I can send 0x00" using 3rd party serial programs and the STB responds. SO I think it is some quirk with AutoIT.

Share this post

Link to post

Share on other sites

Keymaker 0

Keymaker 0

I tried to use your dll and UDfFs earlier. The send function (_CommSendByte() ) works and solves my Chr(0) problem. However, I have two problems with your UDF's and DLL:

1. My application will need to use two serial ports (COM1 controls the preamp, COM3 communicates withe the STB). Your UDFs make no provision for using more than one serial port. Whereas with the MScomm object, I can declare as many COMs as I need and address each one individually for reading and writing, e.g., $MsComm1.Ouput to write to COM1 and $MsComm2.Input to read from COM2. Your read and write UDFs are only applicable to the current open serial port declared in the _CommsetPort() function.

2. I can't seem to read any data FROM the Set Top Box using any of your read functions (_CommReadByte(), _CommReadChar(), _CommgetString() ). See my code below using your functions to help me determine what is wrong.

Share this post

Link to post

Share on other sites

martin 69

martin 69

I tried to use your dll and UDfFs earlier. The send function (_CommSendByte() ) works and solves my Chr(0) problem. However, I have two problems with your UDF's and DLL:

1. My application will need to use two serial ports (COM1 controls the preamp, COM3 communicates withe the STB). Your UDFs make no provision for using more than one serial port. Whereas with the MScomm object, I can declare as many COMs as I need and address each one individually for reading and writing, e.g., $MsComm1.Ouput to write to COM1 and $MsComm2.Input to read from COM2. Your read and write UDFs are only applicable to the current open serial port declared in the _CommsetPort() function.

2. I can't seem to read any data FROM the Set Top Box using any of your read functions (_CommReadByte(), _CommReadChar(), _CommgetString() ). See my code below using your functions to help me determine what is wrong.

But if you're going to wait until a character is available then you can just say

_CommReadChar(1);1 (or any value which is not 0) means wait until a character arrives then return it.

EDIT:Forgot your first point.

Yes you are correct that my UDF/dll only deals with one serial port at a time. I will see what is involved in dealing with more than one port. But even if I decide it's simple it will take me some time to produce a solution.

Share this post

Link to post

Share on other sites

martin 69

martin 69

Yes you are correct that my UDF/dll only deals with one serial port at a time. I will see what is involved in dealing with more than one port. But even if I decide it's simple it will take me some time to produce a solution.

I've had a look. To do it the way I would like will take a bit of time.

As a temporary method I could fairly quickly do this

Have two serial ports at once, that is you could use one or the other or both, but you are restricted to 2 ports.

Default is as now. I add a new function in my UDF Func switch($Channel) to switch to channel 1 or 2.

Then any function you use is talking to that channel, setport readbyte etc.

Share this post

Link to post

Share on other sites

Keymaker 0

Keymaker 0

By the way, I've tried what you suggested in the previous post, but still no luck. The read functions all return "0" or "": The script hangs at that point because it never reads any data that is not "0" or "".

My previous method using $MsComm object reliably read the input and gave the correct data. Maybe there is something I'm missing. Also, your flow control choices are hardware or Xon/Xoff, but no choice for "None".

Thanks again for your efforts..

Keymaker.

Edited August 25, 2007 by Keymaker

Share this post

Link to post

Share on other sites

martin 69

martin 69

By the way, I've tried what you suggested in the previous post, but still no luck. The read functions all return "0" or "": The script hangs at that point because it never reads any data that is not "0" or "".

My previous method using $MsComm object reliably read the input and gave the correct data. Maybe there is something I'm missing. Also, your flow control choices are hardware or Xon/Xoff, but no choice for "None".

Thanks again for your efforts..

Keymaker.

OK.

I've produced a version which has the switch idea and has flow = 2 in the setport for no flow control.

Share this post

Link to post

Share on other sites

Keymaker 0

Keymaker 0

Perhaps my DirecTV satellite application is the only one (so far) that needs a strict adherence to NO flow control.

Also, the files you sent me seem to work. I have NOT yet tried the new switch function. I will try it later. Do I implement the switch() function as follows? and is the function name preceded by an underscore (_)?:

_CommSetPort($COM1,$sErr,9600,8,0,1,2); Set up COM1 for DirecTV STB_CommSetPort($COM2,$sErr,9600,8,0,1,2); Set up COM2 for Krell PreampSwitch($COM2)_CommSendByte($data); Write to COM1Switch($COM1)_CommReadChar(); Read from COM2

Share this post

Link to post

Share on other sites

martin 69

martin 69

Perhaps my DirecTV satellite application is the only one (so far) that needs a strict adherence to NO flow control.

Also, the files you sent me seem to work. I have NOT yet tried the new switch function. I will try it later.

Amazing!

Do I implement the switch() function as follows? and is the function name preceded by an underscore (_)?:

_CommSetPort($COM1,$sErr,9600,8,0,1,2); Set up COM1 for DirecTV STB_CommSetPort($COM2,$sErr,9600,8,0,1,2); Set up COM2 for Krell PreampSwitch($COM2)_CommSendByte($data); Write to COM1Switch($COM1)_CommReadChar(); Read from COM2

Regards,

Keymaker

Not quite, although it would be better if it was like that, however this is how you have to do it -

There are 2 channels in the new dll. Channel 1 and channel 2.

If you don't use the switch function then you are using channel 1. If yu use it with 2 as a parameter you are communicating with channel 2. The channel number is not related to the port number by which I mean channel 1 can be connected to COM9 and channel 2 can be COM3; it doesn't matter.

So here is a small example

$set = _CommSetport(2,$result,9600,8,0,1,0);we haven't used the switch so channel 1 is set for COM2

_CommSendByte($data);send a character to COM2

_CommSwitch(2); we are now talking to channel 2

$set = _CommSetport(9,$result,57600,8,0,1,0); so channel 2 is set for COM9

$c1 = _CommGetChar();get a character from channel2, ie from COM9

_CommSwitch(1); go back to channel 1, COM2

_CommSendString("It's 2.00am I.m going to bed!")

_CommClosePort(); closes both ports -(actually don't remember if I did anything in the dll about channel 2)

Share this post

Link to post

Share on other sites

martin 69

martin 69

I finally found and fixed my hardware problem and properly tested the _CommSwitch() function and it WORKS! It would be nice if you can add the ability to use more than 2 serial ports though.

In the meantime, I can get by with two ports. I sincerely thank you for all your efforts to help me resolve my problem.

Thanks again.

Regards,

Keymaker

That's good to hear.

The method I used to add a second channel can be changed to add any number and would take me about 5 minutes, it just isn't the way I intend to do it eventually. So I'll make a new version for the moment with more channels and post that in the first post of my thread for the UDF. I prefer to keep the number of channels as low as I can while I'm using this present method, so if I say 4 will that be enough?