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.

problem in reading hex string from sensor


vk Dec 27, 2011 07:50 AM

hello, I have sensor which takes 1 byte hex command and provides 11 byte hex out string.In response, first byte is command itself followed by 10 bytes with NO CRLF. I have difficulties in reading instring, often it comes NAN,zero or unprintable characters. (Please see code below)NBytesRetuned give variable number ranging from 0 to 11. buffer too varies 0,5,10 etc. Bit_strings ()are always NAN. I tried almost all options of searialin/out etc and followed some of the post, but it seems nothing is working around. Any help... Thanks
--------------------
Public NBytesReturned
Public ZeroBytes As Boolean
Public Instring As String *10
Public buffer As Long
Dim command As String
Public bit_string(11)
Alias bit_string(1)= 0E
--- -- ---

SerialOpen(Com1,38400,0,0,200)
'Delay(0,10,msec)
SerialFlush(COM1)
Scan (100,mSec,3,0)
command = "0E"
SerialOutBlock(Com1,command ,1)
buffer = SerialInChk(COM1)
NBytesReturned = SerialInBlock(COM1,Instring,30)
SerialInRecord ( Com1,Instring,"0E",11,0,NBytesReturned,01)
If NBytesReturned = 0 Then
ZeroBytes = True
ContinueScan
Else
ZeroBytes = False
EndIf
SplitStr(bit_string(2),Instring,"",10,8)


aps Dec 29, 2011 02:05 PM

Before trying to help can you clarify what you mean by a 1 byte Hex command and 11 byte hex out string.

Do you mean you send a single byte and expect 11 bytes back. I ask because you seem to be trying to send two bytes "0E" not one. Is the "0E" supposed to be the hex representation of the single binary byte (decimal equivalent being 16)?

Also can the 0E value appear in the string returned from the sensor after the first character?

If it can it may be best to send the prompt and wait until enough characters have been sent. Then grab 11 characters. Do you know how quickly the sensor should respond or rather the longest time it should take to send the response in full?


vk Dec 29, 2011 04:40 PM

Andew:

Thanks for reply and sorry for confusions. you are right I am sending single byte(decimal equivalent 14)command and expecting 11 bytes back from the sensor. In the returned string first byte is "0E" itself as header info followed by next 10 bytes. sensor takes about 14 ms to respond once it receives command byte i.e. "0E". I can try out putting delay after serial out block but what puzzles me, why buffer and "Nbytereturned" always keep changing even though I cleared com1 buffer "serialflush(com1)".

vk


aps Dec 29, 2011 05:36 PM

Part of your problem may be caused if your program is run in pipeline mode where the Serialoutblock and Serialinrecord run in a special timed thread which is used in programs that need tight timing.

I could show you how to make that work but there will be an issue if the response from the sensor can include the &h0E character after the first character which could confuse Serialinrecord.

I modified your program somewhat below. Hopefully this should work if I understand the setup correctly. It sends the command byte then waits for 20 msec then picks up the response. It uses Serialinblock which can cope with any byte stream. I have forced Sequentialmode to ensure the timing is as you would expect it. This also shows how to read out the bytes into float variables avoiding possible issues if one of the bytes is a null character (binary zero).

Good luck....

'CR1000 Series Datalogger

Public NBytesReturned
Public Instring As String *11
Dim command As String, i
Public bytevals(11)

'Force sequentialmode to avoid issues with timing
SequentialMode


BeginProg

SerialOpen(Com1,38400,0,0,200)
command = CHR(&h0E)

Scan(100,mSec,3,0)
'Start with a clean slate each time
SerialFlush(Com1)
Instring=""
'Send the command byte
SerialOutBlock(Com1,command ,1)
'Wait at least 20 msec for the response
Delay(1,20,msec)
'Hopefully 11 bytes will now be available to read
NBytesReturned=SerialInBlock(Com1,Instring,11)
'Now read the individual bytes out into a variable array, one per byte
'You need to do this in a special way to avoid issues if one of the
'bytes is character zero which is treated as a string terminator to most
'standard string functions
If NBytesReturned = 11 Then
For i = 1 To 11
bytevals(i) = ASCII(Instring(1,1,i))
Next i
EndIf
NextScan
EndProg


vk Dec 30, 2011 05:49 AM

Andrew:
Thank you very much.It is working now as I expected.I could run it in pipeline mode as well, but I am not sure in longer run if pipeline gives some timing error. "Instring" in above code gives single unrecognizable character that occasionally blinks. Now I would like to implement it for check sum. Bytes 10 and 11 are checksum MSB and LBS respectively. I am looking for some help in that too ... Thanks&Rgd/vk


aps Dec 30, 2011 12:39 PM

You probably have solved this one too following on from the advice in the other thread. The sensor in question has a non-standard checksum which requires you to convert all the values returned into signed integers and summate them all, along with the header byte, then you would compare that to the checksum value send with the message which has also been converted to a signed integer.

I hacked your program about a bit to correct some of the other errors and show the checksum calculation (or my guessimate of how it should work based off the manual)

No guarantees...

'CR3000 Series Datalogger
Public NBytesReturned As Long *100
Public Instring(1) As String *100
Public buffer As Long *100
Public roll As Float
Public pitch As Float
Public yaw As Float
Public roll_str_MSB As Long
Public roll_str_LSB As Long
Public pitch_str_MSB As Long
Public pitch_str_LSB As Long
Public yaw_str_MSB As Long
Public yaw_str_LSB As Long
Public header_info
Public time_tik_MSB As Long
Public time_tik_LSB As Long
Public cheksm_MSB As Long
Public cheksm_LSB As Long
Public cheksm As Long

'added new variables and correct types back to Long as needed
Public checksmdigit, datachecksum As Long
Public Checksumgood As Boolean
Public roll_2,roll_3,pitch_4,pitch_5,yaw_6,yaw_7 As Long
Dim rolldigit,pitchdigit,yawdigit As Long
Dim time_tikdigit As Long
Dim euler_convert_factor As Float


Const command = &H0E

'------------------------------------
'SequentialMode
DataTable (attitude,1,-1)
DataInterval (0,1,Min,10)
'Sample (1,roll,FP2)
'Sample (1, pitch,FP2)
'Sample (1,yaw,FP2)
Average(1, roll,FP2,0)
Average(1, pitch,FP2,0)
Average(1, yaw,FP2,0)

EndTable
'-------------------------------------
'Main Program

Function Unsigned16ToSigned (Value As Long) As Long
Const OFFSET_2 = 65536
Const MAXINT_2 = 32767
If Value <= MAXINT_2 Then
Unsigned16ToSigned = Value
Else
Unsigned16ToSigned = Value - OFFSET_2
EndIf
EndFunction


BeginProg
euler_convert_factor = (360.0 / 65536.0)

SerialOpen(Com1,38400,0,0,200)
Delay (0,15,mSec)

Scan (1,Sec,3,0)
SerialFlush(Com1)
'Send the command byte
SerialOutBlock(Com1,CHR(command),1)
'Wait at least 20 msec for the response
'May need to be longer
Delay(1,20,msec)
'Hopefully 11 bytes will now be available to read
NBytesReturned=SerialInBlock(Com1,Instring,11)
'---------------------------------------
header_info = ASCII(Instring(1,1,1))
roll_str_MSB = ASCII(Instring(1,1,2))
roll_str_LSB = ASCII (Instring(1,1,3))
pitch_str_MSB = ASCII (Instring(1,1,4))
pitch_str_LSB = ASCII (Instring(1,1,5))
yaw_str_MSB = ASCII (Instring (1,1,6))
yaw_str_LSB = ASCII (Instring (1,1,7))
time_tik_MSB = ASCII(Instring (1,1,8))
time_tik_LSB = ASCII(Instring(1,1,9))
cheksm_MSB = ASCII (Instring(1,1,10))
cheksm_LSB = ASCII (Instring(1,1,11))
'-----------------------------------
roll_2 = roll_str_MSB *256 'adjust MSB
roll_3 = roll_str_LSB
rolldigit = Unsigned16ToSigned(roll_2 + roll_3)
roll = rolldigit *euler_convert_factor

pitch_4 = pitch_str_MSB *256
pitch_5 = pitch_str_LSB
pitchdigit = Unsigned16ToSigned(pitch_4 + pitch_5)
pitch = pitchdigit *euler_convert_factor

yaw_6 = yaw_str_MSB *256
yaw_7 = pitch_str_LSB
yawdigit = Unsigned16ToSigned(yaw_6 + yaw_7)
yaw = yawdigit *euler_convert_factor

time_tikdigit = Unsigned16toSigned(time_tik_MSB*256 + time_tik_LSB)

checksmdigit = Unsigned16toSigned(cheksm_MSB*256 + cheksm_LSB)
'----------------------------------

datachecksum = header_info+rolldigit+pitchdigit+yawdigit+time_tikdigit
Checksumgood = (datachecksum = checksmdigit)

CallTable attitude
NextScan
EndProg


vk Dec 31, 2011 07:10 AM

Andrew,
Andrew: thanks for all the help that you made it finally working with "true" check sum and I will take this opportunity to wish you all the best in every sphere of life and prosperous New Year 2012. Thank you very much.vk

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