Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

translating a binary input through a RS232 connection


JDeventer Jun 29, 2015 03:08 PM

Hello everybody
I’m seeking help for translating a binary serial input through a RS232 connection into COM1 of my CR3000.
My CR3000 unit is communicating with two spectrometers from Droplet Measurement Technologies (FM-100, PCASP-X2) connected to COM1 and COM2. The sensors expect a Poll command in order to send out data via RS232:

Const FM100_Poll = CHR(27) + CHR(02) + CHR(29)+CHR(00) ‘ESC BS Chksm NL

The manual of the spectrometers states that all communications between an interface and the sensors is binary. Thus I choose the SerialOutBlock Command:
For a check, I entered the terminal emulator (sniffer) mode of the CR300 and I see that within one scan rate (1 sec) the COM1 transmits the poll command and receives a bunch of data:

T 18:39:40.00 1B 02 1D 00
R 18:39:40.02 40 08 3B 08 9E 0E 61 09 00 08 7C 0C FA 07 40 09 00 00 00 00
R 18:39:40.02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.02 00 00 00 00 00 00 00 00 00 00
R 18:39:40.04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 18:39:40.04 00 00 00 00 00 00 00 00 00 00
R 18:39:40.05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 03

As you can see from the HEX character codes, several of these are non-printable characters. I believe that the nulls at the end result from non-realistic conditions of measurement in our lab (it counts and sizes fog droplets in the air…). It’s plausible that only the first few parameters the response structure should contain values > 0.

Now I tried to translate the input string with the following CR3000 program:

‘’’’’’’’’’’’’’’’’’’’’’’’
Public datain As String * 400 'raw input from sensor
Public dataHex As String * 1000 'raw input as hex string
Public dataHextmp As String * 100 'raw input as hex string
Public dataBytes As Long 'number of bytes received from sensor
Public dataHexLen As Long 'length of hex string
Dim datalng As Long
Dim i As Long

SerialOpen (Com1,38400,0,0,10000) ‘Maxed out the buffer just to make sure, that I don’t lose bytes
Scan(1,sec,1,0)
dataHex = "" 'initialize hex string
SerialOutBlock(Com1,FM100_Poll,4)

Do While SerialInChk (Com1)
dataBytes = SerialInBlock(Com1,datain,400)
For i = 1 To dataBytes
datalng = datain(1,1,i)
dataHex = dataHex & FormatLong(datalng, "%02x")
Next i
Loop
dataHexLen = Len(dataHex)
If dataHexLen Then CallTable(FM100)
NextScan
EndProg
‘’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

However, sampling the variable dataHex doesn’t seem to deliver plausible results:
dataHex = 2147483648 (these exact characters are repeated for serveral times, see HexLen)
dataHexLen = 1003
dataBytes = 192

From the FM-100 Manual, I understand that the Unit works with a C-Code and delivers data structures containing parameters which are defined in three different ways:
‘int’ & ‘unsigned’ 16 bits long
‘char’ & ‘unsigned char’ 8 bits long
‘unsinged long’ 32 bits long

The first parameters of the FM-100 output structure is an array of type ‘unsigned’ which means (according the the manual) 16 bit long. It contains 8 values, in the range of 2000-2600. I Have a running VBasic software, which we used as a datalogger previously. Hence, I know, that the first Parameter must be ‘2112’ and the second ‘2013’
How we got these values in VBasic:
We defined an array as type integer and copied the FM 100 output structure (which if I ‘sniff’ it in VBASIC is the same as the Hex code printed above) into it:

Private Type typFM100Ints
ints(0 To 97) As Integer
End Type
CopyMemory FM100Ints, ByVal COMBufferFM100, Len(COMBufferFM100)
For i = 0 To 7
FM100Data.AD(i) = FM100Ints.ints(i)
Next i
debug.print(FM100Data.AD(1))
2112

So far, I was not able to reproduce these values with my CR3000 programm. I guess, that I still have to figure out, which exact data types are coming into the COM1. The function FormatLong needs a long value as input. Thus I tried this by defining datalng as Long and then in the loop by putting each character step for step into that long variable. However, the source of each character (the variableis datain is a string, maybe this is the problem?.
I Hope some of the experts here have clues or ideas for me?

Best Regards
Julian

* Last updated by: JDeventer on 6/29/2015 @ 9:12 AM *


JDavis Jun 30, 2015 03:52 PM

You just about have it all working. I believe you are just missing using the ASCII command to return the ASCII value of the characters:

datalng = ASCII(datain(1,1,i))


Unsigned 16 bit integers are not too difficult to process. Here is one way:

'FirstValue is of type Long
FirstValue = ASCII(datain(1,1,1)) * 256 + ASCII(datain(1,1,2))

The other way to handle the integers is to use MoveBytes:

Erase(FirstValue) 'Make sure the variable is empty to start
'MoveBytes uses 0 based offsets
MoveBytes(FirstValue,3,datain,0,2)
'FirstValue should now show the correct value

PS. Use & to concatenate strings. It works way better than using the + sign.


JDeventer Jul 13, 2015 05:03 PM

JDavis,
thanks for your response, it helped alot.
One issue I encountered in processing the Integers was that you have to swap bytes, whenever the first byte is larger than the second one, except, the second one is < 8.

In other words: Byte_with_lower_value * 265 + Byte_with_higher_value

With the "MoveBytes" function I sometimes ended up getting wrong values, so I wrote alot of If loops. Is there an easier way?
While this routine works for instrument #1 (FM 100) I encountered some new problems for the second one(PCASP-X2 which uses the same RS232 Settings and Commands)

Again I sniffed the COM1 of my CR3000 and the Poll as well as the Answer command are correct (double checked with the original software of the manufacturer)

T 17:33:50.00 1B 02 1D 00
R 17:33:50.02 C6 0A D3 07 78 07 17 03 AB 09 F9 08 EF 0E F8 0C 09 18 00 00
R 17:33:50.02 00 00 22 00 13 00 0E 00 06 00 11 00 04 00 05 00 06 00 03 00
R 17:33:50.02 03 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 17:33:50.02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
R 17:33:50.02 00 00 00 00 00 00 00 00 00 00
R 17:33:50.03 00 00 00 00 00 00 00 00 00 00 00 00 8B 06

Now for this instrument, the answer is binary but each byte is sent as a HexNumber. So Byte 1/2 is: Hex C6 = Dec 198 and Hex 0A = Dec 10
As above, swapped bytes:
256 * 10 + 198 = 2758 (which is the correct value, again checked with original software)

So far so good.
Unfortunately I'm unable to bring the sniffer response from above into a Variable:

Public dataIn As String * 400 'raw input from sensor
Public dataBytes As Long 'number of bytes received from sensor
dim tmp3 as string

SerialOutBlock(Com1,PCASP_Poll,4)

dataBytes = SerialInBlock(Com1,dataIn,400)

tmp3 = ""
For i = 1 To dataBytes
tmp3 = tmp3 & FormatLong (ASCII(dataIn(1,1,i)),"%02x")
' tmp3 = tmp3 & ASCII(dataIn(1,1,i))
Next i

Sample(1,tmp3, String)

When I logg the variable tmp3 this is wat is stored in the datatable:
"2015-07-13 17:51:01",618,"0a07780717030908100f0c2"
You can see that nearly every second byte is missing.
Any idea why this happens?

Help on this will be much appreciated
Best Regards
Julian

Log in or register to post/reply in the forum.