To parse Hexadecimal number to floating integer


Gorkhali

Recommended Posts

Hi, 

My data column has 10 fields consisting of a combination of ASCII text, 4-digit hex and 8-digit hex numbers separated by a comma. I am trying to parse the data by am not successful. However, fixed-point decimals are getting pursed easily. 

For instance, in my data line separated by commas, the fifth data field is an 8-digit hex integer ("4857f0f1"). To purse that data I'm using the following script.

global String datain

device.Instrument1.Purse()

While (1)

try

datain = device.Instrument1.ReadUntil(13) 

Data1.AddValue(evaluate("0x"+(Mid(datain,5,9))))

 

delay (1)

catch(1)

endcatch

 

EndWhile 

Link to comment
Share on other sites

First a small typo: it is Parse(), not Purse()

I would add some ? statements so you can see what it is doing:

datain = device.Instrument1.ReadUntil(13) 
? datain
? mid(datain,5,9)
? evaluate("0x" + mid(datain,5,9))
Data1.AddValue(evaluate("0x"+(Mid(datain,5,9))))

Then you'll likely be able to see what is wrong.  The one thing I see is that your mid() probably should only be 5,8 since it is 8 characters of hex.

Link to comment
Share on other sites

the additional command lines helped me know what actually was going on. 

I have additional questions for you.

My data line is in the form: 

03, 0002, 00003ef7, 0018, 01, 1.996, 0.00142, 37.00, 34.22, c31a0953

When I run the command:

? mid(datain, 62,8)    // I did 62 as this data is at the 62nd position including commas as space

I get: c31a0953

(This is the actual 8 digit hex that I want to convert to 32-digit floating number. So it's good until here.)

Now to do so, I ran the command:

? evaluate("0x" + mid(datain,62,8))

I get: 2147483647

However, this is not what I want. I am looking to get the 32-floating digit answer: -154.036.

Can you please help me with the syntax. 

Thanks!

 

Link to comment
Share on other sites

There is no built in single line way to convert a hex string to a floating point value.  Instead you will have to process each 2 character byte and put it in an array, then use one of the to.float() functions to convert.  I'm guessing rbFloat() which makes c31a0953 into -154 and change.  Something like:

private fdata
for (private i =  0, i < 4, i++)
   fdata = evaluate("0x" + mid(datain,62+i*2,2))
endfor
private floatValue = to.rwFloat(fdata)

Link to comment
Share on other sites

I tried to edit the code and run, but I am not getting the float value pursed in its channel. The other question is with the looping command you have in an earlier post, I will have to create private for every 8-dit hex individually. But I have around 40 of the 8-digit hex integers that I have to convert to a floating-point value. 

Here is an example of one of the data lines:

03, 0002, 00003ef7, 0018, 01, 1.996, 0.00142, 37.00, 34.22, c343ef6c, 48b09b55, 4834423c, 486dc150, c3423a45, 48758f3c, 48011951, 4827deac, c2bd6321, 487189bf, 47fc6640, 48213bd4, c2ab3f0d, 48756a90, 480020b0, 48250060, c2c627a3, 486fdf58, 480007a6, 4828f8c7, c2f23422, 48702856, 47f488a6, 481fa9d0, c38221db, 4883722d, 480480a7, 4830920e, c3893305, 4881ff54, 47ff16d0, 48289c3b, c3301adc, 48880fb4, 4806eb88, 4833d955, c358a903, 48a4f341, 48246cf4, 4857f0f1

(Bold datapoints are in 8 digit hex values which needs to get converted to floating point integer)

My instrument gives one dataset every second. With the individual lopping it will get really tedious. Please help me convert 8-digit hex and purge the data to its individual channel.

FYI, I have created the channel for each data point and the data points which are in the string format are getting purged. Please let me know if I can provide more information.

Thanks!

Link to comment
Share on other sites

Just do another loop around the code I provided and use a little more math in your mid() to determine what value you want to extract.  Finally, if your channels are named numerically, i.e. myChannel1, myChannel2, you can use execute() and addvalue() to stuff the results into those channels:

for (private c = 0, c < 40, c++)
   for (private i = 0, i< 4, i++)
      fdata = evaluate("0x" + mid(datain,62+c*8+i*2,2))
   endfor
   private floatValue = to.rwFloat(fdata)
   execute("myChannel" + c + ".addValue(floatValue)")
endfor

This isn't exact, but a template for you to modify for your use.   

 

Link to comment
Share on other sites

I don't know what you've done, so no guess.  Adding ? statements often helps, such as:

? floatValue

right after the line that calculates that.  And:

? "myChannel" + c + ".addValue(floatValue)"

right before the execute().  Then you can see where you are at.

 

Link to comment
Share on other sites

Here is the complete code:

global String datain 

device.TapB.Purge()

While(1)
  
try 
   
datain = device.TapB.ReadUntil(13)

      Record_type.AddValue(StrToDouble(Parse(datain,0,","))) //This is parsing properly
      Active_spot.AddValue(StrToDouble(Parse(datain,4,","))) //This is parsing properly
      Flow_rate.AddValue(StrToDouble(Parse(datain,5,","))) //This is parsing properly
      Sample_volume_active_spot.AddValue(StrToDouble(Parse(datain,6,","))) //This is parsing properly
      Case_T.AddValue(StrToDouble(Parse(datain,7,","))) //This is parsing properly
      Sample_air_T.AddValue(StrToDouble(Parse(datain,8,","))) //This is parsing properly
      
      for (private c = 0, c < 40,c++)
         for (private i = 0, i < 4, i++)
           fdata = evaluate ("0x" + mid (datain, 62+c*10+i*2,2)
          endfor
        private floatValue = to.rwFloat(fdata)
        execute ("myChannel" + c + ".addValue(floatValue)")
      endfor
      

    delay(1)
    catch()
    endcatch      

EndWhile

Link to comment
Share on other sites

Hi Guru,

When I run the sequence (in an earlier post), I do not get any error message but neither the hexadecimal part of the data line gets parsed into the channels. When I run the code for query (like ? "myChannel" + c + ".addValue(floatValue)" or ? floatValue ) in the Comm Monitor, I get the error message saying "C1000 Channel or function not available".

 

Link to comment
Share on other sites

FYI, when I change the channel I/O type to special, the data started parsing but the output is not a correct 32-bit floating number. 

The settings of my channel are set to:

channel name: myChannel1

device type: test

D#: 0

I/O type: Special

I am not getting the correct values. Is there something I am missing?

P.S. I am Sujan from Baylor and have been working with Jimmy and Sergio from the UH as well to make it work. 

Link to comment
Share on other sites

As you had asked for, I have attached the .ctl file herewith. FYI, for this set of the instrument, I have been working on the sequence named TapB_parsing. As per your last suggestion, I tried changing the channel setting (time set to 0 and I/O : D to A ), the data stopped getting pushed to the channel. Only when I set the I/O type to Special the data gets pushed to the channel, however, the converted hex decimal does not match with its exact 32-bits floating-point value. I have also attached the instrument manual if that helps you to fix it (pages 30-32 has the data field description).
 
I had sent the same .ctl file in an email as well. Please let me know if I can provide more information.

ELPaso_v5-TestTAPComm.ctl

TAP_Model 2901 System Manual Rev 11.pdf

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.