Jump to content

Help with serial communication at 8192 baud


Recommended Posts

First, an explanation of what I'm attempting to accomplish:

I need to open Com1 (or any com port) at 8192 baud 8N1, send a command in hex (F4570100B4), and recieve a string of reply also in hex (F4950124810B0C350...00005FE6FBE) I have shortened the reply as it is irrelevant. This process will loop as fast as possible, typically 10 or so times a second if possible.

My problem is that most solutions I've found point to the CommMg solution which doesn't seem to allow me to use a "non-standard" baud rate (8192). As I haven't got past that hurdle yet, I can't be sure if it can send the hex properly (sending ASCII is a no-go for sure).

I've attempted a workaround using the RealTerm application with some success, but to do so requires me to open RealTerm, start capture to a text file, send my command, recieve my reply, stop capture, open the capture file to read data, then repeat. I'd rather avoid that much overhead as it's not as fast as I'd like, and the capture file seems totally unnecessary, but unavoidable. And it's more processor and memory usage than should be necessary for this task. Also, I've thought of creating a seperate script to handle the data flow to the capture file, but then have the issue that if one script is writing the capture, and the other attempts to open the capture, I get a null or error on the cycle. No good.

So in short, any ideas on how to use autoit to open a com port at 8192 8N1, send hex data, and recieve reply hex to string variable? TIA!

Link to comment
Share on other sites

IMO you can use CommMG.au3 very well for your purpose.

Have a look at how a COM port is set:

Func _CommSetPort($iPort,ByRef $sErr,$iBaud=9600,$iBits=8,$iPar=0,$iStop=1,$iFlow=0)

you can change the baud rate very easy; just change the default value of 9600.

About sending/receiving hex strings? of course you can do it. You will send/receive strings of characters - build your string accordingly and you will get the expected answer.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

I was put off by a statement in the CommMg file as follows:

$iBaud - integer: the baud rate required. allowed values are one of

; 50, 75, 110, 150, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 10400,

; 14400, 15625, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 256000

Has anyone had success setting baud to a rate other than specified? I would have tried it, but did the worst... trusted the manual. I'll at least give it a shot to see if it'll work.

Link to comment
Share on other sites

You get 'undefined baud rate' if you try 8192. Commg.dll does not support non standard baud rates.

Maybe try a hardare solution, I understand some usb serial port adaptors allow nonstandard baud rates. Using "baud rate spoofing" so you can select standard baud rate and remap it to your baud rate (or near enough) by changing the uart clock divisor. See here.

Link to comment
Share on other sites

As picaxe has said, I did in fact get an error, undefined baud rate. I'm wondering, if the error is due to the way commg.dll is written, is it logical to say that a different dll could solve the issue? If I was able to get RealTerm to apply the correct baud (8192) it stands to reason it's dll (TDLio.dll available from http://sourceforge.net/projects/realterm) or similar (io.dll also allows odd baud rate) should fix the issue. I do realize the calls to it won't be the same as ComMg, which presents a problem as I know very little about that.

Due to the hardware I'm using, USB is out of the question, and baud spoofing hardware might be an option, but not in the near future. I must say, it's a frustrating situation, as I can seem to get all the pieces I need, just not at the same time... I have a dll that does all I need, just wrong baud rate. And I have a dll that allows the baud I need, but don't know enough coding to use it... Any ideas to get one of the other dll's called to make a connection and send/rec?

Thanks for the suggestions thus far though!

Link to comment
Share on other sites

For anyone interested I've reached a crossroads withtwo possible options:

-(Currently building) Using RealTerm I can use AutoIt to send control commands via ActiveX. RealTerm can be ran at any baud, and can send/rec hex. The actual capture part is a bit clunky, but I'm working on that currently. RealTerm has command line ability, but for the machine this script will run, it's not fast enough to be of use. The ActiveX control seems to resolve this.

-(Not attempted yet) Using a DLL known to run at odd baud rates, directly call it's functions from autoit. This appears it could be a very low overhead high speed option. I however am not proficient enough with this part of things to get very far. I'll need to get the functions available for a given dll (which I've done) and figure out how to properly send the command from autoit to pass correct variables, etc. The issue on this path is understanding a given DLL and AutoIt's abilities with DLLs to send useful functions and pull it all together. This is the path I'd like to follow ultimately, but the first option seems to be a decent bandaid for now.

If anyone can give me some pointers on DLL functions, etc. I'd really appreciate it! Till then, thanks for the help I got already.

Link to comment
Share on other sites

For anyone interested I've reached a crossroads withtwo possible options:

-(Currently building) Using RealTerm I can use AutoIt to send control commands via ActiveX. RealTerm can be ran at any baud, and can send/rec hex. The actual capture part is a bit clunky, but I'm working on that currently. RealTerm has command line ability, but for the machine this script will run, it's not fast enough to be of use. The ActiveX control seems to resolve this.

-(Not attempted yet) Using a DLL known to run at odd baud rates, directly call it's functions from autoit. This appears it could be a very low overhead high speed option. I however am not proficient enough with this part of things to get very far. I'll need to get the functions available for a given dll (which I've done) and figure out how to properly send the command from autoit to pass correct variables, etc. The issue on this path is understanding a given DLL and AutoIt's abilities with DLLs to send useful functions and pull it all together. This is the path I'd like to follow ultimately, but the first option seems to be a decent bandaid for now.

If anyone can give me some pointers on DLL functions, etc. I'd really appreciate it! Till then, thanks for the help I got already.

I'm a bit lost as to why you haven't posted a question in the example scripts thread for my udf which I would have thought would be the obvious thing to do if you've tried it out. I am certain to notice it there but I only just happened to see your problem here.

I could easily add a custom baud rate. No one has asked so far.

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

I'm a bit lost as to why you haven't posted a question in the example scripts thread for my udf which I would have thought would be the obvious thing to do if you've tried it out. I am certain to notice it there but I only just happened to see your problem here.

I could easily add a custom baud rate. No one has asked so far.

I didn't mean to offend if I have done so. I didn't realize yours would be able to use "nonstandard" bauds. Would it be possible to allow the input of any baud? If not, the only odd bauds I need at the moment are 8192 and 160. Just curious, is the current limitation in the UDF or the DLL? Also, as I haven't been able to set the proper baud, I didn't proceed. With your UDF will I be able to send as hex data (F4570100B4 or $F4 $57 $01 $00 $B4 depending on where you see it) NOT as ascii.

Thanks for your help! I would have asked before but I'm used to other forums where I would have quickly got a reply saying if I didn't like how it was written I should rewrite it myself. I just didn't want to step on any toes.

Edit: I read your UDF a bit more. To send the hex I need, I think I got my answer.

_CommSendByte(244)

_CommSendByte(87)

_CommSendByte(1)

_CommSendByte(0)

_CommSendByte(180)

Does this appear correct? And also, how would I best grab the response as hex (F495012481.....D3 [typically 63-70 bytes])? Should I use

$Input = _CommGetstring()

Then translate ascii to hex? Or would a better option be

$count = _CommGetInputCount()

then loop $count times with

$char = _CommReadByte()

or maybe even better

_CommReadByteArray(?,$count) (I'm not sure how to properly use this one...)

Sorry to get long winded on an edit, just getting the pieces together.

Edited by DrJeseuss
Link to comment
Share on other sites

I didn't mean to offend if I have done so. I didn't realize yours would be able to use "nonstandard" bauds. Would it be possible to allow the input of any baud? If not, the only odd bauds I need at the moment are 8192 and 160. Just curious, is the current limitation in the UDF or the DLL? Also, as I haven't been able to set the proper baud, I didn't proceed. With your UDF will I be able to send as hex data (F4570100B4 or $F4 $57 $01 $00 $B4 depending on where you see it) NOT as ascii.

Thanks for your help! I would have asked before but I'm used to other forums where I would have quickly got a reply saying if I didn't like how it was written I should rewrite it myself. I just didn't want to step on any toes.

Edit: I read your UDF a bit more. To send the hex I need, I think I got my answer.

_CommSendByte(244)

_CommSendByte(87)

_CommSendByte(1)

_CommSendByte(0)

_CommSendByte(180)

Does this appear correct? And also, how would I best grab the response as hex (F495012481.....D3 [typically 63-70 bytes])? Should I use

$Input = _CommGetstring()

Then translate ascii to hex? Or would a better option be

$count = _CommGetInputCount()

then loop $count times with

$char = _CommReadByte()

or maybe even better

_CommReadByteArray(?,$count) (I'm not sure how to properly use this one...)

Sorry to get long winded on an edit, just getting the pieces together.

Don't worry DrJeseuss, you didn't offend me, I just thought that you could have asked and got an easy yes or no and saved yourself some time.

I can write a mod to the dll and the udf so that any baud rate can be given, up to 256000 say.

The _CommSendByte bits you showed are correct.

Here is a quick example of _CommSendByteArray (see also post 96 and 97 of the udf thread).

$Bytes = 0xF495012481
$Numbytes = BinaryLen(Binary($Bytes))
$Struct = DllStructCreate("byte[" & $Numbytes & "]")

DllStructSetData($Struct, 1, $Bytes)

_CommSendByteArray(DllStructGetPtr($Struct1), $Numbytes1, 1)

Unfortunately I'm in the middle of packing for a holiday, (with an impatient wife in the background) so I can't make the changes to the dll now. I'll be back in 10 days. Then I'll do that change.

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

What a good idea to ask Martin muttley

If you can't wait for him to get back. You might want to try this test script I've cobbled together from some VB examples and an AutoIt example from DaleHolm using Netcomm ocx (distributable version of MScomm32 ocx from here). It baudrate spoofs, when I use standard baudrates and is supposed to work with non standard baudrates but I can't test.

; 
; Netcomm ocx from here - http://home.comcast.net/~hardandsoftware/NETCommOCX.htm
;
; params (com_port_number, "baudrate,parity(Odd,Even,None),charsize,stopbits", "spoof_baud_rate")
SetBaud("1", "2400,N,8,1", "8192")

Exit

Func SetBaud($pCom, $sSettings, $sSpoofRate = "", $iWait = 30000)

    $tDCB = DllStructCreate( _
        'int DCBlength;int BaudRate;int fBitFields;int wReserved;byte XonLim;byte XoffLim;' _
        & 'byte ByteSize;byte Parity;byte StopBits;byte XonChar;byte XoffChar;byte ErrorChar;' _
        & 'byte EofChar;byte EvtChar;int wReserved1' )
    DllStructSetData($tDCB, 1, DllStructGetSize($tDCB))

    $oCom = ObjCreate ("NETCommOCX.NETComm")
    If IsObj($oCom) Then
        With $oCom
            .CommPort = $pCom
            .Settings = $sSettings
            .PortOpen = True
            .InBufferCount = 0
        EndWith
    Else
        MsgBox(262144 +16, "NetCommOCX Error", "Can not create NETCommOCX.NETComm object")
        Exit
    EndIf
        
    $aGetRet = DllCall("kernel32.dll", "int", "GetCommState", "hwnd", $oCom.CommId, "ptr", DllStructGetPtr($tDCB))
    If @error Then
        MsgBox(262144 +16, "GetCommState Error", "DllCall failed with @error=" & @error)
        Exit
    EndIf
    If $aGetRet[0] = 0 Then
        MsgBox(262144 +16, "GetCommState Error", "Could not read current state of port " & $pCom)
        Exit
    EndIf

    If $sSpoofRate <> "" Then
        DllStructSetData($tDCB, 2, $sSpoofRate) ; put new baudrate in struc
        
        $aSetRet = DllCall("kernel32.dll", "int", "SetCommState", "hwnd", $oCom.CommId, "ptr", DllStructGetPtr($tDCB))
        If @error Then
            MsgBox(262144 +16, "SetCommState Error", "DllCall failed with @error=" & @error)
            Exit
        EndIf
        If $aSetRet[0] = 0 Then
            MsgBox(262144 +16, "SetCommState Error", "Could not set BaudRate to " & $sSpoofRate)
            Exit
        EndIf               
    Else
        MsgBox(262144 +16, "No SpoofRate", "SppofRate param missing")
        Exit
    EndIf
    
    $sOut = "244,87,1,0,180"    ; comma separated binary values to send
    ;$sOut = "Type some characters, finishing with OK"
    MsgBox(262144, "Netcomm Com" & $pCom & " Test", _
        "Sending '" & $sOut & "' to Com" & $pCom & @CRLF _
        & @CRLF & "Type some chars followed by 'ok {CR}' on your terminal" _
        & @CRLF & "or wait for the " & $iWait/1000 & " sec timeout.")
    
    ;$oCom.Output =  $sOut & @CRLF
    $aOut = StringSplit($sOut, ",")
    For $i = 1 To $aOut[0]
        $oCom.Output = Chr($aOut[$i])
    Next
    
    $sComInBuffer = ""
    $iBegin = TimerInit()
    While 1
        If $oCom.InBufferCount Then
            $sComInChars = $oCom.InputData
            ; echo received chars
            $oCom.Output = StringReplace($sComInChars, @CR, @CRLF)
            $sComInBuffer &= $sComInChars
            $iBegin = TimerInit()   ; reset timer on received chars
            If StringInStr($sComInBuffer, "ok") Then
                MsgBox(262144, "Received Data", $sComInBuffer)
                ConsoleWrite(@LF & $sComInBuffer & @LF)
                ExitLoop
            EndIf
        EndIf
        If TimerDiff($iBegin) > $iWait Then
            MsgBox(262144, "Error", "No response from COM" & $oCom.CommPort & " in " & $iWait/1000 & " secs")
            ExitLoop
        EndIf
        Sleep(20)
    WEnd    
    $oCom.PortOpen = False
    $oCom = 0
    
EndFunc
Edited by picaxe
Link to comment
Share on other sites

Picaxe, I hesitate to try your idea just yet. Martin was kind enough to rewrite his dll just before holiday. I have tried it, but hit a snag. I'm unsure if it's the new version causing the issue, or if it's my code. I've posted on his UDF thread a description of my problem. Maybe you see something I've missed? Thanks for the support thus far.

BTW: Does your name picaxe refer to the picaxe microcontroller? or just coincidence?

Link to comment
Share on other sites

Picaxe, I hesitate to try your idea just yet. Martin was kind enough to rewrite his dll just before holiday

No probs, I understand.

BTW: Does your name picaxe refer to the picaxe microcontroller? or just coincidence?

Yep, the "555 timer" replacement muttley

Checked out your code, there must be something in the new dll as you suggest. You might consider

;~ Wait to recieve command
While 1
    While 1
        $NumBytes = _CommGetInputCount() ;Count number of characters in buffer
        If $NumBytes > 0 Then ExitLoop;if characters exist continue
    WEnd
    $Struct2 = DllStructCreate("byte[" & $NumBytes & "]") ;create struct2 based on buffer size
    $ComIn = _CommReadByteArray(DllStructGetPtr($Struct2), $NumBytes, 1)
    $ComIn = DllStructGetData($Struct2, 1)
    MsgBox(0, 'Data recieved', $ComIn) ;display bytes received
    $Struct2 = 0 ;clear struct2 from memory
    If $ComIn = "0xF4570100B4" Then ExitLoop
WEnd
I haven't tried it, but it should work. the default for ExitLoop is the current loop. Edited by picaxe
Link to comment
Share on other sites

Yep, the "555 timer" replacement muttley

PIC chips Rule!!

Just wondering what hardware your working on?

Also, as you forum name implies, you no doubt have a work area with pics, pcbs, soldering iron, etc, so why did you not just knock up a quick breadboard pcb with a 16F874a (or similar with USART), and do the baud conversion in real time?

I expect part of your answer may be that you dont what to make hardware for an enduser, but im just curious as i have found using a combination of Autoit and PIC's a very potent combination (sometime i just laugh Mwaaahahahha... :) )

Sione

Perilous to all of us are the devices of an art deeper than we ourselves possess.

Link to comment
Share on other sites

Picaxe,

Martin has fixed the DLL and she's working beautifully. I've got some details to work out on my end for error detection, but in the short time I had to hack some things together, not too bad. Hats off to Martin. It appears the trouble before was due to the modified DLL being based on an older release missing the SendByteArray and ReadByteArray additions. As far as the ability to select any baud, it seems to be just fine. And thanks for the ExitLoop call. I was bugeyed from a rather long day staring at the screen. Often wierd workarounds end up in there as my brain shuts down... Usually they don't get caught until much later, if at all.

And who can't love a Picaxe. It's much cheaper than the Stamp line, nearly as powerful, and MUCH better than a 555. muttley

SIone,

As far as the hardware side, I'm connected to a MAX232 chip on perfboard. As you suggest, I do have chips, iron, etc close at hand, but the nature of this project requires the ability to connect at several baud rates, a few of which are considered as "non-standard". So while a hardware solution could have worked, it wouldn't have been as easily compatable in the future as things progress.

And I'll agree, AutoIt and Pics are a perfect match. I'm hoping to pick up a few 433 wireless modules soon to play with. I'd like to have a picaxe on the PC to muscle data around, and at the other end of the wireless, the picaxes doing the busy work here and there. Much more helpful than a nest of wires!

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...