LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Trim a single bit from a byte?

Solved!
Go to solution

OK so im a mechanical guy, not a programming guy so lets start there.  I just learned how hexadecimals work and have limited experience in LABview.  I have been searching this topic for days, maybe its just my vocabulary but I havent found anything.

 

I need to analyze a signal coming from a CAN system.  I dont have the can device yet but I'm accessing position sensors on the system.  They come in as 8-bit hexadecimal messages.  I am currently simulating this message as a string in LABview so i can get one part of my program ready.  The manufacturer has given me example code that requires concatenating two bytes but I only need 3 of the bits to be concatenated. (one needs the last bit trimmed and the other 2 need the first bit trimed.)  I have already concatenated the two bytes necessary but cannot figure out how to get rid of an individual bit.  I need to do this as hex values to get the proper measurements.  I know my programming grammar is probably a bit off so let me give you an example.

 

Example String of Hex Values

03 23 F6 21 B4 C4 74 F6

 

The first sensor requires bits 3 &4 (21 & b4)

In this case they are required to be in the order 4,3 and drop the first bit to receive 421 as the needed hex value.  So far I have made an input string to simulate the incoming CAN message with that 8bit hex values.  I then use string subset to isolate the individual bytes and finally concatenate to get them in the correct order and end up with B421.  I cannot figure out how to drop the "B" bit or replace with a zero.  I can only replace the full byte.

 

Is there an easier way to do this.  I plan to use the example VI to receive the CAN messages which outputs to a string, hence why I am using strings.

 

Thank you in advance for the help.  I am going crazy trying to figure this out.

 

Also if any other details are necessary please let me know

0 Kudos
Message 1 of 28
(9,397 Views)

@jpc335 wrote:

I just learned how hexadecimals work and have limited experience in LABview.


Yup, else you would spell it LabVIEW 😄


@jpc335 wrote:

 

Example String of Hex Values

03 23 F6 21 B4 C4 74 F6

 

The first sensor requires bits 3 &4 (21 & b4)


These are bytes, not bits. Is this a hexadecimally formatted string (containing the ASCII characters 0-F and maybe space) or is this a binary string? What is the display format of the string indicator?

 

It would be easiest of you could attach a small VI containing a tpyical string as diagram constant. Then tell us the output you want. (e.g. a three character hexadecimally formatted string). There is no 12bit datatype. What does the instrument expect?

0 Kudos
Message 2 of 28
(9,382 Views)
Solution
Accepted by topic author jpc335

Here is my VI.  Yes they are formatted as hexadecimal strings.  I am just trying to get part of the programming done before I get to the testing site.

 

I was told by the manufacturer that the 3 bit hexadecimal string can then be converted into usable numbers.  So if its faster/easier to replace the first byte with a 0 or turn it into a 3 bit hex string.  Either will work.

 

Thank you for responding so fast I should have posted here yesterday haha.  I haven't used LabVIEW  for about 5 years and that was just basic stuff so I'm getting back into the swing of things.

0 Kudos
Message 3 of 28
(9,354 Views)

1. It helps a lot if you show the display type on your strings (Right-click->Visible Items->Display Style).  You should do the same for your numerics (except it is called Radix).

2. You are referring to BYTES, not BITS.  There is a big difference (8 bits in a byte).  And you are asking to mask off the most significant NIBBLE (4 bits).  So here is how I would handle this.  Use String Subset to get the bytes from the string you need.  Then use Unflatten From String to convert to a U16 (2 bytes, unsigned integer).  Since your least significant byte (LSB) is listed first, you will want to use Little Endian.  Then we just mask off the MSN (Most Significant Nibble) by using an AND with 0x0FFF.



There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 4 of 28
(9,340 Views)

I have a feeling this is exactly what I want to do, and after reading the help section I can just use the big-endian to do the one that is disimiliar.  I tried to integrate this into my code as well as do it stand alone.  I keep receiving error 74 and I think it has something to with constants I'm using.  What type of constant does the 0x0FFF go into? and the UI6 indicator? The times I didnt receive the error I returned 0's.  And using an indicator it happened after the unflatten.  I think it has to do with my constants though.

 

Thank you in advance for your Help!

0 Kudos
Message 5 of 28
(9,270 Views)

Here's another way to do this, using some Hex and Byte/Word functions.  Note that to see that this is doing what you want, be sure to display Byte Array and (hi.lo) in Hex.

CAN Do.png

I start with the Hex string you used in your example,  NI has a "Spreadsheet String to Array" function that will break strings like this apart into arrays of (in this case) bytes (be sure to specify U8 as the Array Element on the lower left input of this function).  Note that I specify a Hex format (%x) and show a Space Constant as the separator.  If you run this Snippet (drag the Image from the Forum to your Block Diagram -- it will magically become LabVIEW code), you'll see that the U8 Byte Array has 03, 23, etc. (if you remember to display it as Hex).  Now I extract two Bytes, index 4 and 3.  To get rid of the high 4 bits, I "and" the high with Hex 0F (the leading zero usually doesn't show), remembering that F is binary 1111, so it "keeps" only the low 4 bits.  The last function is Join Numbers (found on the Numeric, Data Manipulation Palette) which combines two Bytes into a 16-bit Word.  The result, when viewed as Hex, is, as expected (and hoped) 421.

 

Bob Schor

 

0 Kudos
Message 6 of 28
(9,236 Views)

You mentioned that "the example VI to receive the CAN messages ... outputs to a string" - which example is this? Which CAN card are you using to read the CAN packets? All of the CAN adapters I've used have the option to get the packet as an array of bytes. If you have that option, your code might be simpler (index array -> build number -> mask with AND).

 

Even easier would be if you can use a CAN database. You define the packet contents and when you read from the channel, all of the work you're trying to do in code is done for you automatically.

 

In the code you posted, there is no reason to use string subset to get one character at a time, when you actually want two. Set the length to 2. Using little-endian versus big-endian swaps the bytes for you. The 0FFF constant goes into a 16-bit (U16) numeric constant; right-click it and show the radix, then set the radix to hex. What you have now is an enumeration that actually has a value of 0, so it masks off everything (it's just that you've assigned the name "0X0FFF" to the value 0).

0 Kudos
Message 7 of 28
(9,199 Views)

@jpc335 wrote:

 

I was told by the manufacturer that the 3 bit hexadecimal string can then be converted into usable numbers.  So if its faster/easier to replace the first byte with a 0 or turn it into a 3 bit hex string.  Either will work.

 


You want to break yourself of this misuse of bit ASAP.  A bit is a single 1 or 0.  Hex requires 4 bits to find the values.  The purpose of hex is to reduce the number of bits you must write out so things are easier to read.

 

0000 - 0

0001 - 1

1010 - A

1111 - F

 

When you have two hex digits, you have 8 bits, or a byte.  You're talking about two entirely different conversations when you ask how to extract a bit or a byte.  It's generally easier to pull out the byte.

 

You'll also want to be careful with words like "third."  You're not looking for the third byte.  You're looking for the fourth byte.  WIth zero-indexing, it could be the byte at index 3.  But, you're creating confusion when you use third to mean fourth.

 

In terms of solving your problem, it sounds like you're going to have a string of characters.  At this point, it's relatively meaningless to view them as hex.  The environment sees them as a string and will operate on them as such.  You can use string parsing VIs to remove the parts of the string you don't care about.  If the format always looks like what you showed us, it wouldn't be hard to traverse through the string by looking for spaces.  From there, you'd need to worry about whether you need the values to be in a numeric type or if string is still sufficient.  But, you should handle splitting off only the string values representing the two bytes you're worried about.  Once you can do that, you can take the next steps.

0 Kudos
Message 8 of 28
(9,134 Views)

@natasftw wrote:

@jpc335 wrote:

 

I was told by the manufacturer that the 3 bit hexadecimal string can then be converted into usable numbers.  So if its faster/easier to replace the first byte with a 0 or turn it into a 3 bit hex string.  Either will work.

 


You want to break yourself of this misuse of bit ASAP.  A bit is a single 1 or 0.  Hex requires 4 bits to find the values.  The purpose of hex is to reduce the number of bits you must write out so things are easier to read.


Now the OP has you doing it.  I'm sure you mean "characters".



There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 9 of 28
(9,093 Views)

@jpc335 wrote:

What type of constant does the 0x0FFF go into? and the UI6 indicator?


They are all U16.  For the constant, it is just a numeric constant that I changed the represenation to be a U16, showed the radix, and changed it to view in hex.  Same thing for the indicator.

 

EDIT:

Now that I actually am looking at your code, you are still making things way too difficult on yourself.

1. No need for 2 String Subsets and then a Concatinate String.  You can just use a single String Subset, just like I showed in my snippet.

2. You used a Ring for your mask whose value can only be 0.  Anything AND 0 will always result in 0.

3. You need to change the representation of the constant that is used for the Unflatten From String's "type" input to be a U16.



There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 10 of 28
(9,090 Views)