LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Select specific bytes from a hex string, combine them and convert the result to its decimal value

Solved!
Go to solution

I am LabVIEW novice and I am working in LabVIEW 2018 using the NI-VISA driver to communicate with a serial device using modbus hex commands over a UART USB cable. The sensor contains registers that I am access for the information stored on them. When I issue the command to access a certain register, I get a response back in the form of a hex string. The bytes I want to combine are the 4th and the 5th because together they spell out the decimal value I wish to show. I then send that decimal number into an array which saves to a text file every iteration of my while loop. The problem I am having is selecting the 4th and 5th bytes from the string and converting them as one number. I tried using and index array to select the two bytes, but it is only allowing me to save 1. I tried using the offest under the scan value and hex string to decimal functions, but I was probably doing the sytnax wrong.  I have attached screenshots of my front interface, block diagram and the VI itself. Any help would be greatly appreciated.

0 Kudos
Message 1 of 8
(1,774 Views)

@vanceblake wrote:

The bytes I want to combine are the 4th and the 5th because together they spell out the decimal value I wish to show.


 

You probably need to be much more specific what you mean by "spell out" Do the two bytes correspond to two formatted decimal characters? Do the represent a 16bit integer in binary? Big endian or little endian?

 

Your processing of the raw received string makes little sense.

 

Can you instead reduce your example VI to a simple diagram that contains a typical value of the read buffer (run the VI until it contains data. Stop, right-click the terminal and "Create constant"). Now place that constant into a new VI and tell us what kind of result you expect. Do you have a link to the manual of the instrument?

 

 

There are a lot of things wrong here, for example why are you creating an ever-growing array in a feedback node that you continuously write to a measurement file. After N iterations, the fist element will exist N times! Why isn't there a define loop rate? Why is the front panel and diagram maximized to the screen? Why do you configure the serial port with ever iteration instead of once before the loop? Why are your default values so weird (e.g. byte count=0)? etc.

0 Kudos
Message 2 of 8
(1,760 Views)

@vanceblake wrote:

The bytes I want to combine are the 4th and the 5th because together they spell out the decimal value I wish to show..


So, in your example picture (1504 0201 DE08 FB) which one is byte #4? (i.e. is the first byte #0 or #1, for example). Do you want "x01DE" or "xDE08"? Is this an signed or unsigned integer? What is the byte order?

 

Maybe play around with something similar to the following:

 

altenbach_2-1638921505362.png

 

 

Message 3 of 8
(1,755 Views)

There are also several ready made Modbus libraries which solve these problems already for you. If you startup VIPM and search for Modbus you should see them.

Rolf Kalbermatter
My Blog
Message 4 of 8
(1,692 Views)

Hi Altenbach thanks for your help. The bytes I need are x01DE in that order. It is an unsigned integer because the sensor measures gas ppm and that value can only be 0 or positive. Does the method you've shown below work for both positive and negative numbers as long as I change the integer indicator type or another setting? Also, could you please list the functions by name that are shown in your screenshot? I'm very green when it comes to using LabVIEW, and I'm still finding my way around the functions and tools palettes. Thanks again

 

Also, realize that the serial configuration should be outside the while loop. The reason I left it inside was that the example I found on youtube and was following along with had it that way. I did see that the feedback node re-copies all the values that came previously, but I figured I would fix that problem after I could get the correct value written to the file. If you have a way to just write the current requested number from the loop and append it after the previous value that would be greatly appreciated! There is no defined loop rate because I don't know how to do that yet and I'm not sure I need to do that because I am continously requesting the gas ppm value, until I decide to stop the program. The byte count is set to zero because when I took the screenshot the file had just been opened and I hadn't set it yet. It should be 16. If I post again in the future I will make sure my screenshots reflect the nature of my problem correctly. Finally, I don't know how the front panel got maximized like that and have been trying to fix it. 

0 Kudos
Message 5 of 8
(1,677 Views)
Solution
Accepted by topic author vanceblake

@vanceblake wrote:

Hi Altenbach thanks for your help. The bytes I need are x01DE in that order. It is an unsigned integer because the sensor measures gas ppm and that value can only be 0 or positive 


String position, file position, array indices are all zero based, so the first element is #0. To get x01DE, you need to get the string subset starting with 3 and size=2.

If you know it is an unsigned integer, you need to wire a U16 constant to the top of "unflatten from string". Just place any numeric diagram constant and "right-click...representation...u16".

 

(Note that I underlined the name of the only two functions used. find them and read their help.)

 

altenbach_0-1638982627573.png

 

Also make sure to use the terminology correctly. Let's look at your subject line "Select specific bytes from a hex string, combine them and convert the result to its decimal value". The word "hex string" is incorrect. You have a binary string that you chose to display in hex format. That's just cosmetic and does not change the string data. "Hex string" is often used to describe a string that only contains the ASCII characters 0...F, which dos not apply to your case. You bytes can be anything from 0...255. The word "decimal" is also used incorrectly. Decimal is again a formatting convention displaying the numeric datatype using characters 0..9, decimal delimiter, etc. This will happen if you write it to a text file and how it is displayed by default in an indicator. All you need to do is cast the existing bits into a defined numeric datatype. the word "decimal" is just a cosmetic property to display it.

 

You are obviously brand new using LabVIEW, so there will be a learning curve. I would recommend the learning resources listed at the top of the forum, not some random YouTube video of often very questionable quality. There is a lot of garbage out there and you need more experience to tell the difference. 😄

 

To continuously write the last value, it helps to use lowlevel file i/o. Open the file before the loop, with each iteration, keep writing the new value nicely formatted followed by a linefeed. LabVIEW will automatically keep track of the file position and append. Once the loop has finished, close the file.

 

(Using high level file IO will open and close the file during each operation and needs to find the end before writing. This involves the OS and is expensive!)

 

To define the loop rate, you would just place a short wait (e.g. 100ms for a 10Hz loop rate.

 

In any case rolfk is probably one of the biggest expert here, so consider his advice and find these libraries. I am more of a hardware-free bit-twiddler. 😄

 

0 Kudos
Message 6 of 8
(1,665 Views)

Hi Altenbach and rolfk, thanks for both of your help! I will be searching for the libraries rolfk mentioned because I need all the help I can get lol. I would have replied individually to each of you but I'm only allowed to post twice in a 24hr period, so I had to save my responses in case more follow up was needed. 

 

I will try to implement the method you suggested below for writing and saving to the file. I will also work on making sure I use the correct terms going forward because I know it become hard to parse what I mean otherwise.

 

When you say place a short wait, does the wait go outside the loop or inside of it?

Thanks again for all the help!

0 Kudos
Message 7 of 8
(1,617 Views)

@vanceblake wrote:

When you say place a short wait, does the wait go outside the loop or inside of it?


 

Everything goes with the dataflow principle.

 

  • If the wait is outside the loop, it will execute exactly once in parallel to the loop when the program starts and nothing will be noticeable. The loop will start immediately, wait outside or not. The loop will immediately spin as fast as it possibly can. Not good!
  • If the output of the outside wait function is wired to the loop boundary, the loop will start once the wait has completed because you created an artificial data dependency. After that, the loop will spin as fast as it possibly can. Not good!
  • Dataflow dictates that the loop cannot go to the next iteration until all code in it has completed. All independent code fragments inside the loop will run in parallel as much as possible. In a typical program, the wait is the slowest independent part and will thus directly determine the loop rate. Good!

 

0 Kudos
Message 8 of 8
(1,614 Views)