Automotive and Embedded Networks

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW 2017 XNET CAN Read issue

Solved!
Go to solution

Hi everyone.  I'm decently versed in CAN from my years in automotive and robotics and I have a few years of LabVIEW development under my belt.  I have a LabVIEW program that is sending out two separate CAN frames.  The first vi uses an XNET Create Session set to Frame Out Stream, writes my CAN frame, clears the session then creates another session set to Frame In Stream and reads the streaming data for 15 seconds.  It works great.  The second vi partially works and uses a Create Session set to Frame Out Single-Point, writes my CAN frame, clears the session then creates another session set to Frame In Single-Point then reads that single-point data.  I can see every message I transmit and the corresponding response on the XNET Bus Monitor.  My single-point read is showing the correct frame ID but the payload data is all zeroes yet the bus monitor displays the exact data I should receive which is not zeroes.  I'd appreciate any help I could get on this.

0 Kudos
Message 1 of 11
(6,063 Views)

I don't fully understand the design, but I tend to not open and close sessions all the time.  I generally just open all the sessions I'm going to be needing for my application, then use them and close them all at once on application close.  If you are worried about reading old data you can flush a session (or read everything waiting) then start reading again.  There are also timestamps if needed.  Single point reading is often for things that change quickly, but whos readings individually aren't important.  Like an ECU may send out temperature every 20ms, but for displaying it on the UI it doesn't really matter if I read the single point once a second.  Is that what you are using the single point read for?  If you haven't found it yet I have a blog series on CAN and go over the XNet session types and when you might want to use one or another.

 

http://hooovahh.blogspot.com/2017/05/can-part-6-in-depth-xnet.html

0 Kudos
Message 2 of 11
(6,053 Views)

Good morning Hooovahh,

 

I was under the impression that I had to close one session before starting another.  That’s easy enough to change and will simplify the program.  I was taking single-point as data that is only available when I request it.  I transmit a specific Message ID and Payload then read back the corresponding Message ID and Payload.  That data is only available on the bus when I request it.  I definitely plan to check out your blog, just have to do it on my personal PC as it’s blocked on my work laptop.  Feels odd that I have no problem getting the streaming data.  That data also requires that I send out a specific Message ID and Payload to start the stream.

0 Kudos
Message 3 of 11
(6,030 Views)

For a request and response type of messaging a single point session isn't the best approach.  Obviously a single point write will mean the request goes out periodically and timed by the hardware which isn't great.  But even the single point read isn't what you want because NI's API doesn't allow for you to know when a new frame has came in without polling.  And the data coming in for single point (at least signal) will be the default value when no data has been read which makes it hard to know if the device is sending the default, or if it has never communicated.

 

A better approach for a request/response would be to have a Stream session out, and a Stream session in, or a Stream session out and a Queued session in.  I guess the out session could be Queued as well but that seems unnecessary.  With the Queued session you must specific the Arbitration ID if the frames you want, but once you do that you can have it do a read with a timeout of say 1 second, trying to read 1 frame.  If that frame comes in within one second the function returns immediately with that frame.  Otherwise it times out because you never got your response.

 

Also this sounds an awful lot like ISO15765 for UDS, KWP2000, and a couple of other communication types.  NI has the Automotive Diagnostic Command Set for doing these types of calls on NI hardware.  And I also reimplemented the state machine and code in G so that it can be used with NI hardware or any other hardware.  This is mentioned in Part 8 of the CAN blog.  The code posted isn't a drop in solution for NI hardware, but it is meant to show how the protocol can work with any hardware that supports a streamed frame in and out.

 

Oh and there is a limit to the number of sessions that can be opened for an interface, and globally for the system at once.  I don't remember what it is but it is larger than any application probably needs.  And the limit was increased with some versions of XNet's API.

0 Kudos
Message 4 of 11
(6,022 Views)

Still can't get it to work.  I tried Frame Out Stream with Frame In Stream and I've tried the Frame Out Stream with Frame In Queued.  Same Msg ID (0x0100) and Payload (0x0400) in both.  Neither works.  The bus monitor shows what I received when that ID and Payload are sent, so I know it's working.  My XNET Read is not reading anything.  My original Streaming code didn't have the while loop, I added that to try reading it for 5 seconds.  There are five messages I can send that will give me streaming data, all of those work flawlessly.  I've tried this with two USB-8502's, both have the same problem.

 

Streaming and queued with the bus monitor:

Streaming and Queued payload with bus monitor.jpg

 

Streaming 04 payload

Streaming 04 Payload code.jpg

 

Queued 04 payload

Queued 04 Payload code.jpg

0 Kudos
Message 5 of 11
(5,989 Views)
Solution
Accepted by topic author JamHet

But you are still creating a read session, after performing the write for a request.  It is possible that you send the request, then the device replies, then you create the read session, only to find nothing because it has already sent the reply.  The read will only return stuff that has occurred since the creation of the session. 

 

What I was suggesting you do is create all of your sessions at once before ever performing a read or write.  This could be outside of your loop entirely, or by using data flow to ensure both have started first.  Then use those sessions in your loop as you need performing writes reads etc.  Then outside of your loop once it stops running close all your sessions.

 

Also in your code you currently aren't closing your write sessions.

Message 6 of 11
(5,984 Views)

Thank you for all the help .  Finally got it working  Creating the necessary sessions first then writing and reading worked perfectly.

0 Kudos
Message 7 of 11
(5,964 Views)

During my software testing I always had the XNET Bus Monitor running and capture mode was on so I could verify messages were going out and coming in.  Today was the first time I tested without the Bus Monitor running.  I discovered that without the monitor running I get no data whatsoever.  Seems odd that in order to get data into LabVIEW the bus monitor has to be running.  Is there some strange setting I need to set in LabVIEW?

0 Kudos
Message 8 of 11
(5,902 Views)

That's new to me.  When I run bus monitor it is usually on another port that isn't being used, with a Y cable or ribbon splitting the bus so it can be read independently.

0 Kudos
Message 9 of 11
(5,898 Views)

It makes no sense to me.  I need to find a solution pretty fast.  Didn't know if there was something in my code that I need to set.

0 Kudos
Message 10 of 11
(5,892 Views)