Keymaker Posted August 25, 2007 Share Posted August 25, 2007 (edited) Hello forum,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:http://www.autoitscript.com/forum/index.ph...0&hl=chr(0).Unfortunately they did not have have any solutions.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.Regards. expandcollapse popup#include <Constants.au3> #include <string.au3> #include <Misc.au3> #include <array.au3> ;----------------------------------------------; ; Make tray item ;----------------------------------------------; Opt("TrayOnEventMode",1) Opt("TrayMenuMode",1) TraySetClick(16) TraySetIcon(@ScriptDir & "\Images\Transmitting.ico") $Exit = TrayCreateItem("Exit") TrayItemSetOnEvent($Exit,"ExitEvent") ;----------------------------------------------; ; Setup Serial Port(s) ;----------------------------------------------; Local $COM1 = 1 $MsComm1 = ObjCreate("MSCOMMLib.MsComm") ;$MsComm1 = ObjCreate("NETCommOCX.NETComm") With $MsComm1 .CommPort = $COM1 ; Set COM1 port for ... .Settings = "9600,N,8,1"; 9600 Baud, 8 bits, 1 stop, No parity .InputMode = 0 ; 0 = TEXT MODE, 1 = BINARY MODE .Handshaking = 0 .InBufferSize = 512 .InputLen = 1 .PortOpen = 1 .NullDiscard = 0 EndWith Dim $satCMD[8] ;--------------------------------------------------------- ; TEST program stars here ;--------------------------------------------------------- $satCMD[0] = 7 ; Ch244 $satCMD[1] = "0xFA" $satCMD[2] = "0xA6" $satCMD[3] = "0x00" $satCMD[4] = "0xF4" $satCMD[5] = "0xFF" $satCMD[6] = "0xFF" $satCMD[7] = "0x0D" ;SendSatCommand($satCMD) MsgBox(0, "OK", "Response from STB was : " & SendSatCommand($satCMD), 3) Exit ;----------------------------------------------; ; Satellite receiver command function ;----------------------------------------------; Func SendSatCommand($CommandArray) Local $SUCCESS = 244, $COMMAND_OK = 240, $PARAMETERS_OK = 242 Local $response Const $CMD_TIMEOUT = 500; 500 milliseconds $i = 0 Do $i = $i + 1 SatSend($CommandArray[$i]) ;MsgBox(0, "", "Command is : " & $CommandArray[$i], 2) Until $CommandArray[$i] = "0x0D" ;@CR ; Wait for response 0xF0 = 240 = command acknowledged $time = TimerInit() Do Sleep(5) Until $MsComm1.InBufferCount Or TimerDiff($time) > $CMD_TIMEOUT $response = SatReceive() If $response <> $COMMAND_OK Then Return "Error 1 " & $response ; Wait for response 0xF2 or 0xF4 = parameters received $time = TimerInit() Do Sleep(5) Until $MsComm1.InBufferCount Or TimerDiff($time) > $CMD_TIMEOUT $response = SatReceive() If $response = $SUCCESS Then Return "Success!" If $response <> $PARAMETERS_OK Then Return "Error 2 " & $response ; Wait for the 0xF4 response, "command successful". $time = TimerInit() Do Sleep(5) Until $MsComm1.InBufferCount Or TimerDiff($time) > $CMD_TIMEOUT $response = SatReceive() If $response = $SUCCESS Or $response = 0 Then Return "Success!" Return "Error 3 " & $response EndFunc ;----------------------------------------------; ; Tray function ;----------------------------------------------; Func ExitEvent() Exit EndFunc ;------------------------------------------------------; ; Serial data ouput function to Satellite receiver ;------------------------------------------------------; Func SatSend($data) With $MsComm1 .OutBufferCount = 0 .InBufferCount = 0 If .PortOpen = True Then .Output = Chr($data) EndIf EndWith EndFunc ;-----------------------------------------------------; ; Serial data input function from Satellite receiver ;-----------------------------------------------------; Func SatReceive() $DataIn = "" With $MsComm1 If .PortOpen = False Then .PortOpen = True EndIf If .InBufferCount Then $DataIn = .Input ;Data EndIf EndWith Return Asc($DataIn) EndFunc Edited August 25, 2007 by Keymaker Link to comment Share on other sites More sharing options...
martin Posted August 25, 2007 Share Posted August 25, 2007 (edited) Unfortunately they did not have have any solutions.The link you gave was for a thread started by AutoitSteve, and he did get a solution, and it was from me. It was as a result of that thread that I produced my serial COMs UDF commg.dllThere are possibly other solutions.EDIT: Welcome to the forums! Edited August 25, 2007 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 25, 2007 Author Share Posted August 25, 2007 Thanks for the reply Martin. 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. Regards, Keymaker expandcollapse popup#include <Constants.au3> #include <CommMG.au3> #include <string.au3> #include <Misc.au3> #include <array.au3> ;----------------------------------------------; ; Make tray item ;----------------------------------------------; Opt("TrayOnEventMode",1) Opt("TrayMenuMode",1) TraySetClick(16) TraySetIcon(@ScriptDir & "\Images\Transmitting.ico") $Exit = TrayCreateItem("Exit") TrayItemSetOnEvent($Exit,"ExitEvent") Local $COM1 = 1, $COM3 = 242, $SuccessFlag, $response, $sErr Const $CMD_TIMEOUT = 500 ; 500 milliseconds Dim $command[6] $command[0] = 0xFA ; "0xFA" = Command prefix $command[1] = 0xA5 ; "0xA5" = user command $command[2] = 0x00 ; "0x00" = switch toggle $command[3] = 0x01 ; "0x01" = remote button $command[4] = 0xF7 ; "0xF7 = menu command $command[5] = 0x0D ; "0D" = @CR ;----------------------------------------------; ; Setup Serial Port(s) ;----------------------------------------------; _CommSetPort($COM1, $sErr, 9600, 8, 0, 1, 0) ;----------------------------------------------; ; Send MENU command ;----------------------------------------------; MsgBox(0, "TEST", "Click OK to send MENU command ") $i = -1 Do $i = $i + 1 _CommSendByte($command[$i]) Until $command[$i] = 0x0D ;@CR Do Sleep(5) Until _CommGetInputcount() <> " " ; Data available? $response = _CommReadChar() MsgBox(0, "OK", "Final return value was : " & $response) Exit ;----------------------------------------------; ; Tray function ;----------------------------------------------; Func ExitEvent() Exit EndFunc Link to comment Share on other sites More sharing options...
martin Posted August 25, 2007 Share Posted August 25, 2007 (edited) Thanks for the reply Martin. 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. Regards, Keymaker expandcollapse popup#include <Constants.au3> #include <CommMG.au3> #include <string.au3> #include <Misc.au3> #include <array.au3> ;----------------------------------------------; ; Make tray item ;----------------------------------------------; Opt("TrayOnEventMode",1) Opt("TrayMenuMode",1) TraySetClick(16) TraySetIcon(@ScriptDir & "\Images\Transmitting.ico") $Exit = TrayCreateItem("Exit") TrayItemSetOnEvent($Exit,"ExitEvent") Local $COM1 = 1, $COM3 = 242, $SuccessFlag, $response, $sErr Const $CMD_TIMEOUT = 500 ; 500 milliseconds Dim $command[6] $command[0] = 0xFA ; "0xFA" = Command prefix $command[1] = 0xA5 ; "0xA5" = user command $command[2] = 0x00 ; "0x00" = switch toggle $command[3] = 0x01 ; "0x01" = remote button $command[4] = 0xF7 ; "0xF7 = menu command $command[5] = 0x0D ; "0D" = @CR ;----------------------------------------------; ; Setup Serial Port(s) ;----------------------------------------------; _CommSetPort($COM1, $sErr, 9600, 8, 0, 1, 0) ;----------------------------------------------; ; Send MENU command ;----------------------------------------------; MsgBox(0, "TEST", "Click OK to send MENU command ") $i = -1 Do $i = $i + 1 _CommSendByte($command[$i]) Until $command[$i] = 0x0D ;@CR Do Sleep(5) Until _CommGetInputcount() <> " " ; Data available? $response = _CommReadChar() MsgBox(0, "OK", "Final return value was : " & $response) Exit ;----------------------------------------------; ; Tray function ;----------------------------------------------; Func ExitEvent() Exit EndFunc Haven't tried your script but this bit is wrong Do Sleep(5) Until _CommGetInputcount() <> " " ; Data available? it should be Do Sleep(5) Until _CommGetInputcount() <> "0" ; Data available? 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. Edited August 25, 2007 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
martin Posted August 25, 2007 Share Posted August 25, 2007 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 thisHave 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.Would that be any help? Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 25, 2007 Author Share Posted August 25, 2007 (edited) That would help greatly! 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 Link to comment Share on other sites More sharing options...
martin Posted August 25, 2007 Share Posted August 25, 2007 That would help greatly!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.I'll PM you with a link. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 25, 2007 Author Share Posted August 25, 2007 Thanks for the prompt solution martin. Regards, Keyamker Link to comment Share on other sites More sharing options...
Keymaker Posted August 26, 2007 Author Share Posted August 26, 2007 It works! No flow control ( Flow control = 2) fixed the problem. 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 Preamp Switch($COM2) _CommSendByte($data) ; Write to COM1 Switch($COM1) _CommReadChar() ; Read from COM2 Regards, Keymaker Link to comment Share on other sites More sharing options...
martin Posted August 26, 2007 Share Posted August 26, 2007 It works! No flow control ( Flow control = 2) fixed the problem. 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 Preamp Switch($COM2) _CommSendByte($data) ; Write to COM1 Switch($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) ; and closes the dll Hope that makes sense. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 28, 2007 Author Share Posted August 28, 2007 Martin, I have not had a chance to test the new _CommSwitch function yet. I appear to be having a hardware issue with my COM2 port. I'll report back after I've resolved the problem. Regards, Keymaker Link to comment Share on other sites More sharing options...
martin Posted August 28, 2007 Share Posted August 28, 2007 Martin,I have not had a chance to test the new _CommSwitch function yet. I appear to be having a hardware issue with my COM2 port. I'll report back after I've resolved the problem.Regards,KeymakerOK, I'm interested to find out.I've done some test of my own and I'm feeling confidentish. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 30, 2007 Author Share Posted August 30, 2007 Martin, 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 Link to comment Share on other sites More sharing options...
martin Posted August 30, 2007 Share Posted August 30, 2007 Martin,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,KeymakerThat'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? Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Keymaker Posted August 30, 2007 Author Share Posted August 30, 2007 Yes, I think 4 channels would be enough... Thanks again. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now