Mscomm, Serial ports and bit manipulation

I have just started to investigate the replacement of some seriously old kit with a Windows XP version. I need to read and write data between either a usb/serial port on a new Windows XP machine and connect it to an old controller via an rs-232 cable.

Data is passed between the two in Ascii format and can be as little as one character at a time or up to several hundred characters at a time. I will need to be able to interpret some of the data down to the bit level on receipt.

Having read some of the threads here, it would appear the use of MSCOMM is a viable solution for the serial port communication as the transmissions are in a set send and receive pattern so I wouldn't need to poll the port for data, just wait for the receipt, accept it, process it and send an appropriate reply.

On receipt of any data, it would need to be broken down (some data is held at the bit level within the 1st few bytes of data) and stored somewhere for later retrieval and also displayed to any interested user in a nice windows display format.

Conversely I need to assemble stored data ready to transmit back to the controller, some of which will need bit level manipulation into characters.

Can I achieve all the above just using VB express or do I need an amalgam of products

Please excuse my lack of knowledge this is all very new to me even though I have an IT background.



Answer this question

Mscomm, Serial ports and bit manipulation

  • vincentvdb

    How about....this

    Dim x As Integer
    Dim Bit3 As
    Boolean
    '---- force a specific hexadecimal value
    x = &H14F8
    '---- Get bit 3
    Bit3 = ((x And CInt
    (2 ^ 3)) > 0)
    '---- send the result to the immediate window
    Debug.WriteLine("Bit 3 state is: "
    & Bit3.ToString)
    '---- Get bits 8 to 12 as a hex and decimal number
    Dim Bits8to12 As
    Integer
    '---- The mask for bits 8-12 is 1111100000000 in binary
    '---- or 1F00 in Hexadecimal
    Bits8to12 = (x And
    &H1F00) >> 8
    Debug.WriteLine("Bits 8 to 12: value = " & Hex(Bits8to12).ToString & " (Decimal: " & Bits8to12.ToString & ")")

    That should be pretty close and give you something to work off.



  • jchmack12

    I'm actually pretty glad the serial communication is alive and well in VB2005! It's still used quite extensively in industry.

    Earlier versions of VB (VB Classic, or VB6/5) used the MSCOMM activeX control. VB2005 has the SerialPort control. Unfortunately, I haven't had a chance to play with it yet, since of all the computers I have sitting around none of them have a serial port! (Actually, that's not totally true, there is one but it doesn't have a development environment on it, but there isn't anything to connect it to ).

    The VB2005 control (F1, help) tells m a lot - it works in a very similar way to the old activeX control (in fact, it seems quite a bit more sophisticated).

    Your first test is to have Hyperterminal on on PC (and a serial port, of course), and your development PC (with serial port !), running hyperterminal, and use a null modem serial cable and send characters back and forth.

    Next, play with the serialport control in VB - send characters from a VB application, to hyperterminal on the other PC. Now, even though you may be sending 'characters', you are really sending 'bytes': sending characters just makes it easy to see that your mechanisim is working.

    Once you have the mechanism tested, you are ready to send and recieve streams of bytes. At this point, you may want to think about encapsulating this 'transport mechanism' into a class, control or a DLL.

    Once your transport mechanism is reliable, consider buffering the recieved bytes: develop a reliable storage mechanism, that prevents buffer overruns and loss of data.

    Now, consider the data itself and the protocols in place. You can extract from your buffer one or more bytes to interpret. As Renee says, it is quite easy to manipulate the bits within bytes and words (using the term 'word' to indicate 2 bytes, or 16 bits).

    As a side note: when mentioning 'protocol' here, this is completely different from the serial port protocol: the SerialPort control and how it's configured, as well as the hardware take care of that.

    Only you can determine the protocol in use (it reads like you have a handle on that).

    Bottom line is you should certainly be able to do what you want with VB2005 Express edition. Download it and give it a try - it's definately time not wasted.



  • Ole Gulbrandsen

    Hi I'm an used to write mainframe disk drivers in the old days. Although I think the pentium instruction set and that instruction set are quite different, they are frequently compared.

    I bit twiddled for a living and actually I'm elated with VB's capabilties. They are all built into to the language in ways that may not be obvious. In other words, if you don't bit twiddle to begin with, techniques for VB bit manipulation may not be obvious.

    I've helped a lot of people here with this specific question in conjunction with MSCOMM. (Btw another EXCELLENT resource here on these things is SJWHITLY).

    But I've received questions like "How do I unload a word (a "Short") into bytes for mscomm

    Thats so easy....

    Dim bArray(1) 'Actually two bytes.

    bArray(0) = foo and &hFF

    bArray(1) = foo >>8

    or

    bArray(1) = (foo >>8) and &hFF ' (I think the first will suffice)

    But there you are, there are very sophisticated ways to do bit manipulation in VB2005.

    If you have specific questions, I'll be happy to answer them.



  • Chris Vega

    Stephen,

    Wow, thanks - info overload - got a lot to get my head around. I have just started to download and install VB Express and will certainly be applying myself to it in great detail. I have only ever used VBA within Access 2003 so a lot of it will be new to me, will try the usual reference type books as reading material to gen up on it.

    Not used hyperterminal so that is another long term investigation to try and understand.

    Does this mean I don't need to use MSComm to send/receive data if I use the serial port control in VB.

    I believe that PortMaster has been mentioned in a meeting I had, whereby up to 10 seperate devices could be attached to it and then sent to the XP machine. I would presume the communication would have to include which machine had sent the data and it would therefore be possible to have multiple comms ongoing into the XP machine. Keeping track of that scenario may well be a nightmare.

    Not sure about the rest of the info provided, its over my head at the moment, but will certainly be worth returning to once I've got past the first few points on the list.

    Many thanks for this info.


  • XnakX

    Data storage:

    Your best bet is to have an array of bytes to store your incoming data. Try and think about separating your tasks of data acquisition, data storage, data extraction, data analysis and data presentation.

    You could set up what's called a circular buffer to store your data in. This is an array of values of a predetermined size (usually). When you recieve data (data acquisition of 1 or more bytes you use a pointer into that array of where to put those bytes. Once you have placed them, you move the pointer along that many bytes. This is your write pointer.

    e.g.

    WritePointer = 0
    Recieve 12 bytes.
    Put recieved data into buffer at the writepointer index (=0).
    Move WritePointer along by 12 bytes: WritePointer = WritePointer + 12
    WritePointer is now 12

    Of course we will have to take account of running out of buffer space: we simply wrap back around to the start of the buffer.

    (Also - error checking: what happens if we haven't read all the data, yet )

    Data Extraction:

    We have a ReadRointer. We look at the difference between the ReadPointer and the write pointer and see if we have enough bytes to interpret a message. Basically, we will ignore the buffer until we have enough bytes that composes our fixed message length.

    When we have enough bytes, read those bytes. We may copy them to a structure, discarding the header and tail (or perhaps checking that the header and tail are valid) or copying the bytes to a location (maybe a fixed length array of bytes) ready for analysis.

    Analysis:

    once we have this raw data, now we break it up/assemble it into meaningful data. Things start getting very application specific, here.

    Since you have bytes, you may want to assemble them to an integer (32 bit). Here's a couple of interesting methods (the Marshal() method is quide a good one to look up, with plenty of experimentation room):

    Dim b() As Byte = {1, 0, 10, 0}
    Dim i As
    Integer
    i = System.Runtime.InteropServices.Marshal.ReadInt32(b, 0)
    Debug.WriteLine(i)

    Dim j As Integer
    j = b(0) + b(1) * 256 + b(2) * 65536 + b(3) * (256 * 256 * 256)
    Debug.WriteLine(j)

    Data presentation:

    draw pretty pictures on the screen based on that meaningful data; write out log files; write stuff to databases; other fun stuff .



  • --JC--

    Hi,

    Thanks for the reply, I still am not sure about this so if I could elaborate on the bit manipulation.

    If I receive the following Ascii data how do I break the contents into the required bit pattern I need :-

    LF 31 34 46 38 20 CR ( Hex 14F8) (Binary 00010100 11111000 )

    The Line Feed and Carriage return are ignored.

    I need to break this into bits as follows :-

    Spec definition :- Each set of 4 hex characters represents a 16 bit binary computer word, the most significant bits to the left and the least to the right. The space (20) is to be ignored.

    Bit pattern required to be extracted

    Bit 15 , Bits 13-14 , Bits 8-12 , Bit 7 , Bit 6 , Bit 5 , Bit 4 , Bit 3 , Bits 0-2

    0 00 10100 0 1 1 1 1 000

    Thanks for your time on this it is much appreciated.

    Ace


  • SpawnProduction

    Stephen,

    Absolutely brilliant. I think I understand all that is going on in the code, and I can probably adapt it to fit my requirements.

    The bit manipulation was the biggest headache I believe I would have but it looks very easy to code around.

    As a further probe into my investigation, what would be the best way to store incoming data from the outside source. For example most of the real data is in repeating 5 byte chunks within a LF and CR character, the 5th character being a space to delimit the chunk.

    i.e sample data example in ascii

    DC3 LF 36 37 38 .....CR LF 37 39 46 30 20 30 32 35 38 20 .......CR LF .... CR

    -------- header data ------- -------------- Main data --------------------------------------------

    24 SUB CR DC1

    ---trailer data------

    I was thinking of packing all the data into 4 byte arrays, and then after the message end processing it an array at a time, as no data expands over the 4 bytes.

    Having extracted the data and decided how to store it on a more permanent basis I will need to display the data to the end user in a suitable Windows format. VB should allow me to do this I believe dependent upon how the data is stored.


  • Mscomm, Serial ports and bit manipulation