Sign in to follow this  
Gorkhali

To parse Hexadecimal number to floating integer

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 

Share this post


Link to post
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.

Share this post


Link to post
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!

 

Share this post


Link to post
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)

Share this post


Link to post
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!

Share this post


Link to post
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.   

 

Share this post


Link to post
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.

 

Share this post


Link to post
Share on other sites

? floatValue; ? "myChannel" + c + ".addValue(floatValue)"; or ? fdata would give an error message saying:

"C1000 Channel or function not available"

Share this post


Link to post
Share on other sites

Not at that line.  Please post more detail, such as what line # is giving you that error and what the rest of your code looks like.  Nothing is running in isolation, so I need to see the whole thing.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Sorry for the typo here. But the addition of parenthesis is not helping.

I have been relying on you a lot to solve this issue and thanks for being so helpful so far.

Share this post


Link to post
Share on other sites

That is fine, but more detail would help, such as the exact error message and what line number it is saying it is on, along with what line corresponds to that line number (since you didn't include line numbers).

Share this post


Link to post
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".

 

Share this post


Link to post
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. 

Share this post


Link to post
Share on other sites

I'm guessing you don't have the Timing set to 0 in myChannel1.  Do this, and set the I/O type to D to A.

Please post, or email your full .ctl document.

 

Share this post


Link to post
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

Share this post


Link to post
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
Sign in to follow this