LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Serial Communication Problem (PIC24 to RS-232)

Dear all,
 
Thank you for taking the time to read my post.
 
I am using Labview 8.0 on Pentium D 3.4Ghz, 2GB of RAM.
I am also using a microcontroller PIC24 (on the Explorer 16 development board), which I have programmed to acquire data (from a potentiometer) at a rate of about 5 kHz (using a 10-bit ADC, thus I have 50 kbps of data). The serial setting for the pic have been programmed to be 115200, 8 data bits, no parity, 1 stop bit.
 
What the PIC does is it padds the 10 bit ADC to 16-bits. I then sends over the Data 8-bits at a time. 
 
I have written a VI to read this data from the RS232 port (Settings 115200 8-N-1). The problem is that the data I get are not 'really' correct. What I think happens is that because data is comming 8-bits at a time, the Type Cast VI converts sometimes the wrong two bytes.
 
What I mean, is that it converts the string into LSB+MSB format instead of MSB+LSB.
 
What also seems to happen is that the Type Cast VI confuses a no string value for a zero. I then coverts lets say MSB+0, which the Type Cast VI converts to a totally different number than the actual voltage on the development board.
 
I do not know why the above problem could happen. It could be because the bytes arrive slightly delayed and this somehow affects the Type Cast VI.
 
I would be very grateful if anyone can post any comments/ideas about what might be going wrong+possible solutions.
 
I have attached a print screen of the errorneous data as well as my VI in LV 8.0.
 
Regards
Alex
 
 
 
 
 
Download All
0 Kudos
Message 1 of 7
(3,603 Views)
I don't understand the purpose of the for loop in your code. If there are 2 bytes available, the loop will run twice but you are discarding the first byte read. Why don't you just set the VISA Read for 2 bytes. Which raises another issue. Since the device is presumably sending data all of the time, you don't know the byte order since you can't synchronize the VISA Read with anything. You'll probably have to do a couple of single byte reads, convert and then test if the data makes any sense. If it doesn't, read one more byte, discard that, and then start reading 2 bytes at a time.
Message 2 of 7
(3,596 Views)

Hi Dennis,

Thanks for your reply.

"Why don't you just set the VISA Read for 2 bytes."

I have tried to set the Visa Read to read 2-bytes at a time but I still get the same problem.

"Since the device is presumably sending data all of the time, you don't know the byte order since you can't synchronize the VISA Read with anything."

I have though of this issue as well but could not really think of a solution to the problem. Either do something in Labview or change the C code in the PIC. You suggested:

"You'll probably have to do a couple of single byte reads, convert and then test if the data makes any sense. If it doesn't, read one more byte, discard that, and then start reading 2 bytes at a time."

I am afraid my knowledge of Labview is just above the Basics 1&2 courses and I would not know how to implement the above.

Would it be simpler to send a synchronizing byte after/before each data byte? This approach would require some synchronization handling in Labview as well. It would also reduce the maximum data rate of the rs232 communication, would it not?
 
Do you have any examples of what you suggest above (in LV8.0). Sounds like you have done something similar before and have much more experience from me.
 
If not then how would I go about doing initially some "single byte reads", if i want to read two bytes at a time. Are you suggesting some sequence structure?
 
Also, it might be a bit difficult to understand if the "data makes any sense", since the errorneous data I get, is always between the 3.3 - 0V (3.3V are applied between the potentiometer  and ground). As I previously, I think the two different bytes are 'fused' together in the wrong order.
 
However, I still dont understand where/how/why the two bytes are fused in the wrong order.
 
Also, you finally suggested "If it doesn't, read one more byte, discard that, and then start reading 2 bytes at a time.". Would this require some sequence stracture as well?
 
I would be grateful if you could post some examples or try and explain the solution a bit more in detail.
 
All the best
Alex
0 Kudos
Message 3 of 7
(3,569 Views)

The simplest thing would be to have a single byte transmitted after the two data bytes. With the VISA Configure Serial Port, you would enable the termination character and set the term character to be equal to this single byte you would append. The problem is the byte cannot be a valid data byte. When data is transmitted as text, it's common to use a CR or LF character as the termination character. The x0A and x0D of LF and CR are liable to be valid data and this would ruin the whole synchronization.

I don't have an example handy but I think there have been some posted to the forum. You might want to try some searches. An approcah to take would be a state machine. In the first state, read 2 bytes, concantanate them together and do a type cast to get a number. I don't know if you are sending an unscaled integer or a floating number. Type cast to whatever is appropriate. You could then wire this number to an In Range and Corece function. If the number is in range, go to a state where you continuously read 2 bytes and the conversion to a number. If it's not in range, go to a state where a VISA Read is set to return only 1 byte. Don't do anything with the returned byte, just jump to the continuous read state.

Message 4 of 7
(3,565 Views)

Hi Dennis,

Thanks for your fast reply. I am aware of the 'software' flow control you have suggested and the problems that might occur with using it.

As for your suggestion of using a state machne, it is of course a sound idea. However, I do not have much expereicnce of implemented state machine and I am certain that there must be a simpler solution to my problem (or that I am overlooking something).

I would like to ask you this. How would I go about implementing a small rooutine of creating an array of the incoming data and then removing each byte one by one (maybe even at predifiend increments). I would like to do this as I am under the impression that it is the Type Cast that is creating all these problems.

Would it be much to ask for a small example, if you have time.

Thanks Dennis you are a star!

All the best

Alex 

0 Kudos
Message 5 of 7
(3,557 Views)

Not sure if this is what you are looking for. I just created a for loop to read 1 byte x number of times. The resultant string array is then wired to another for loop that type casts the string to a U8.

Message Edited by Dennis Knutson on 07-12-2007 12:08 PM

Message 6 of 7
(3,556 Views)

Thanks Dennis for your shift reply.

Though this is not exactly what I think I want, It gave me some ideas, which I will try out.

One more thing. If Visa Read reads only one byte at a time it will overflow pretty quickly. I think I am thus forced to have the bytes at port output connected to the VISA Read.

Thanks for your time and I will get back to you with more questions.

All the best

Alex

0 Kudos
Message 7 of 7
(3,543 Views)