LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Converting hex string to hex array

Solved!
Go to solution
Highlighted

@pratikpade wrote:

Please refer to my attached VI. I am continuously sending 0x25 and and trying to convert it to array but I am receiving a blank array. Please let me know if you find the problem


First, what is the exact protocol of the serial communications?  Your use of the Bytes At Port concerns me since this means you are not using the protocol set up by the instrument.  This almost always leads to partial messages or messages that are mixed together, both causing loss of data and/or misinterpretations.  So let's take care of how you are reading your data and that just might fix the rest of your issues.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
0 Kudos
Message 11 of 20
(251 Views)
Highlighted

@pratikpade wrote:

What i want to do is implement a kind of DAC. When a value is read eg 0x25, the analog value is calculated as:

(Analog value)=(0x25/4095)x3.3

(Analog value)=0.020.


Based on your math, it should actually be closer to 0.03.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
0 Kudos
Message 12 of 20
(250 Views)
Highlighted

Hi crossrulz,

 

Thanks for helping me out. I am using the usart protocol. With frame as 1 start bit, 1 stop bit, no parity bits and 8 data bits, with 9600 baud rate. I am using the bytes at port property node to input the bytes to be read by Visa read. Do you suggest I use something else? 

Also for the VI you built, I am facing the same problem.

Analog value= ((hex i/p)/4095)x 3.3

and not Analog value ((decimal i/p)/4095) x 3.3

 

when the we use hex string to byte array, it changes the representation from hex to digital. Thus:

Analog values you got = 37/4095 x 3.3= 0.029

Analog values I want = 25/4095 x 3.3 = 0.020

 

Thanks a lot for your inputs!

0 Kudos
Message 13 of 20
(235 Views)
Highlighted

I'm almost certain you want 37/4095 * 3.3.

 

You're reading from an Arduino, right? 4095 is likely the number of bits in your ADC- a 12-bit ADC has 4096 (decimal) unique counts. Those are also typically ratiometric, and I bet you're running off a 3.3V supply voltage.

 

Your input will return a value between 0 and 4096, and you need to scale that from 0 to 3.3 V. If you use decimal values, this works, as you divide your reading by the total range (to get a 0-1 value) then by the actual max value (to get real world units). You need to talk to whoever gave you that formula.

 

Also- please do some reading on what decimal and hex is. It will help you understand this issue instead of just trying to convert things around until it "looks" right.

 

You're *almost* there to getting this working 🙂

0 Kudos
Message 14 of 20
(231 Views)
Highlighted

Hi Bert,

Yes I made a mistake i was dividing hex by decimal. hence your solution works. I am able to receive data now. But I am facing a further problem. I am sending uint 16 data from my microcontroller and doing arimthmatic on it and then plotting it. But the problem I am facing is in Read Visa.

for input string of: 08c9, 08c9 08c9, 0869.

It is reading: 08c9 08c9 c908 c908.

 

i.e the byte reading goes wrong. I checked the output of my mcu on terminal and it is correct. Please can you let me know why does this problem occur? I tried reading faster, reducing loop delay, reading more bytes at a time. But nothing helps.

Thanks for all the help and efforts

0 Kudos
Message 15 of 20
(219 Views)
Highlighted

You basically lost a byte.  I don't think you actually lost in in the serial stream, but your code discarded it.

 

First.  DON'T USE BYTES AT PORT!  It is the wrong thing to use 99% of the time.  Please reread Crossrulz's message #10.

 

It looks like you really want 2 byte values.  You are talking about 4096 which is the number of different values represented ina 10 bit instrument.  So you'll need 2 bytes to give you 16 bits to have enough binary digits  "bits" to represent that 10 bit value.  So I don't understand why are converting the values to U8 integers and proceeding to do the math on that.  You are never treating pairs of bytes as U16 integers.  What is likely happening is that on some iterations you might be reading an even number of bytes, but on some iterations, you might be reading an odd number which throws off the byte order in later reads.

 

Even more likely is that you left the Serial Configure at its default settings of enabled termination character as line feed character (x10).  Since x10 is a potentially valid data byte,  and very likely considering you have x08's in there, it will be interpreted as a termination character and will end the read.  That would throw off the byte order in later reads.

 

You should be reading this 2 bytes at a time.  Get rid of "Bytes at Port".  Then typecast that string to get a U16.  There is still one potential problem.  When you get the first byte, you really have not idea if it is the first byte of a new pair that belong together, or the second byte of the previous pair of bytes.  If the first byte is wrong, you'll need to discard that and read one more.  But the question is how does your serial protocol let you know that you have proper pairing of bytes?

0 Kudos
Message 16 of 20
(216 Views)
Highlighted

Hi Ravensfan,

Thanks for your help. I got rid of the bytes at port, however there was no significant change. For reading the bytes, I could find string to byte array and not string to word array. As for the problem of byte order I tried something, please take a look at the VI. Though the idea is not good, I was able to get the work done. I tried transmitting and receiving a sine wave of close to 100 Hz. Please find the image. However I was not able to read higher frequency sine waves. Will increasing the baud rate help?

I disabled the termination character after your comment. I will try the typcast to u16 later and let you know.

Thanks a lot

Download All
0 Kudos
Message 17 of 20
(207 Views)
Highlighted

That's because String to Word Array doesn't exist.

 

As I said, use typecast.  Wire an array of U16 to the top.

 

You still don't have a robust solution for determining if your bytes are correct.  In once case, you are determining the number of bytes you received and then flushing bytes.  In the other, you are swapping bytes or not based on whether one array is greater than the other.  What does that even mean?  Swapping bytes won't work because you'll be matching the most significant byte of one datum with the least significant byte of a different.  Now you've paired them up and they have nothing to do with each other.

 

Have you read the manual and determined the protocol?  How do you know which of the two bytes should be first?  A proper protocol would only send bytes once a request was written to the device.  But yours seems to just continually spit out data since you never write anything out ot tell the vice when to send data.  Let's say you have 3 pieces of data labeled 1 2 3.  And each consists of an "X" byte followed by a "Y" byte.   (I'm using X and Y so you don't confused the following as hex values.)  So if all goes well, you request 6 bytes and get 1A 1B 2A 2B 3A 3B.  Typecast that to a U16 array and you'll have three U16 integers in an array.   But suppose you miss the first byte?  You'll get 1B 2A 2B 3A 3B 4A.   If you pair them up and swap them  you'll be putting together 2A 1B   then 3A 2B.  .....  None of them are accurate. 

 

What reliable method can you use to know that the first byte you receive is actually the first byte?

 

As for your frequency question, I don't know.  I have no idea what device you are using and if it is sampling fast enough to acquire it.  Of course higher baud rates have higher data rates, but that doesn't necessarily correspond to being able to read higher frequencies.  You are bringing a new question into the problem and you haven't even solved your original problem!

 

 Typecast:

serial%20data%20acquisition-1_BD

You can also use Unflatten From String as it allows you to tell it what way to interpret the bytes as most significant or least significant byte first.

0 Kudos
Message 18 of 20
(202 Views)
Highlighted

In this circumstance, I would convert the raw ADC values to their ASCII equivalents on the arduino and transmit them in a message that is terminated with a specific character.

 

Its a very good idea to think about a protocol for data transmission, generally I go for something like the following:

 

Data packet: Termination Character  (you must ensure that packet cannot contain the termination character)

 

or 

 

Fixed sized header: Length of packet: Command number: Payload: Checksum

 

Depends on the application, but you certainly shouldn't just spew bytes. It will bite you later (or now).

 

0xDEAD

0 Kudos
Message 19 of 20
(191 Views)
Highlighted

@deceased wrote:

In this circumstance, I would convert the raw ADC values to their ASCII equivalents on the arduino and transmit them in a message that is terminated with a specific character.


If it were me, I would do all of the conversion from the ADC to floating point on the Arduino itself and then use the Serial.PrintLn() command format the float into a number and send the data.  The PrintLn() also appends a Line Feed, so you use that as a termination character.  Then on the LabVIEW side, you just tell VISA Read to read something like 50 bytes and let it stop when the termination character is found.  Then it is a simple Fract/Exp String To Number to get your data.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
0 Kudos
Message 20 of 20
(179 Views)