Logo

“Is there life before death?” - Graffito


Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 975

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 975

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 975

Warning: mktime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 975

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1163

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/FeedForAll_XMLParser.inc.php on line 1344

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 846

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 847

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 848

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 849

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 917

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 918

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 919

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 920

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 917

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 918

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 919

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 920

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 917

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 918

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 919

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 920

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 917

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 918

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 919

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /home/hooovahh/public_html/rss2html/rss2html.php on line 920
Pic 3

Hooovahh's Blog



CAN Part 3 - XNet and NI-CAN APIs


04/12/2017 07:53 PM

Okay so in Part 1 we discussed the various types of CAN, how they differ from serial, and some hardware options.  In Part 2 we talked more about the data that is sent to and from devices called Frames.  And we also talked about why CAN is so robust of a bus, with built in support for message priority, CRCs, and acknowledgements.  In Part 3 we are going to talk about NI's two main APIs for reading and writing CAN data, NI-CAN and NI XNet.  XNet is a large topic, and will also be covered in more detail later.

Basic NI-XNet Example

With all of that finally out of the way, lets talk about the NI-XNet example on how to read and write frames.  Just like the serial example mentioned earlier, the best place to start is in the Example Finder.  First lets look at a Frame Input Stream which will return all frames read into the buffer since the last read.


Here we see that we first open a session to the hardware to perform a Frame In Stream. Then configure the interface, and then we sit in a loop reading the data, and displaying it as an array of frames, and then convert it to a more easily viewable table.  Notice the 100ms loop rate which doesn't cause lost frames, because the frames that are read in those 100ms will be sitting in the hardware buffer, and transferred over on the next read.  This read has several optional inputs that make for some useful use cases, like setting the number of frames to 1 and timeout to 100ms.  This will cause the read to take at most 100ms, but it will return sooner if a frame is seen by the hardware.

The frame out example is quite similar.


Here we again configure the session for a Frame Out Stream, configure the interface, and then once every 100ms we send out 2 frames.  This is using software timing, and the actual amount of time between writes may vary since this write will write it as soon as the bus is idle.

NI-XNet is a pretty advanced API.  Which is why I'm going to dedicate an entire post on the API and some of the cool custom things it can do later.  But for now just know this is really just the tip of the iceberg when it comes to what this API can do.  Database management, signal and frame conversion, LIN, FlexRay, and sessions types are some of the other topics that you can go into when discussion XNet.  Some of these topics will be covered in much more detail later.  XNet also supports things like echoing written frames, single shot transmission, and high voltage wake-up all through property nodes on the sessions that are opened, or the interface being used.

NI-CAN Example

Earlier I mentioned NI has an older CAN API called NI-CAN.  The most common NI-CAN hardware that uses this API is the NI USB 8473.  This has recently been replaced by the XNet equivalent NI USB-8502 which is an XNet card.  But before then if you wanted a cheap NI USB solution it was going to be the 8473, which uses the older NI-CAN API.  Here is the shipping example which can read frames, and write them using the same session in a similar way to the XNet which would use two sessions.


The example is pretty straight forward and a great starting point for a more complicated application.  You'll notice that the NI-CAN API can write a single frame, at a time as shown here, or has a couple of other functions for sending multiple frames as fast as the bus will allow.  As for the read the technique here is pretty common, where we query how many frames are in the buffer, and then choose to read that many.  Other options include using the ncWaitForState.vi which can wait until a frame is available, before returning, similar to what the XNet Read is capable of.

When looking on the palette NI-CAN is broken up into two separate subpalettes.  Channel API, and Frame API.  Everything we've mentioned so far all falls under the Frame API.  However, not all functions under the Channel API work on all NI-CAN hardware.  The unsupported functions can be replicated with software but is obviously more efficient if the hardware supports it.  Since we haven't covered what the Signal (or Channel) means for CAN yet, just stick with the Frame API which reads from a hardware buffer, and writes to the bus as soon as it is idle.

A few other major differences with NI-CAN and XNet is that XNet has many database functions which make importing, parsing and using database files possible, but might not be intuitive to new developers.  You'll also notice that with NI-CAN only one session can be open to a piece of hardware at a time, while NI-XNet supports having multiple sessions open at once.

Manual Panels

But deploying any actual code, you probably want to know that your hardware is working, and the best place to start is the same place you would go to troubleshoot NI DAQ hardware, MAX.  MAX (Measurement and Automation Explorer) is installed with just about all NI hardware and both XNet and NI-CAN hardware have simple test panels for reading and logging frames, and write in the case of XNet.

NI-CAN Bus Monitor

For NI-CAN you'll want to navigate to the hardware in MAX and then go to the properties first.  The Bus Monitor doesn't change the baud rate and so it must be set before opening it.  Once set open the Bus Monitor.


The bus monitor initializes the hardware when opening it, so you may start to see raw frames come in immediately.  Stop the interface and you'll be able to go to the options and configure a few more things.  The most common thing I use is the Stream To Disk option which logs raw frames as a CSV file with time stamps of when the frames were seen by the hardware.  This is a very useful tool in seeing the playback of what was seen by the hardware.  I wouldn't recommend having end uses use this software, but for debugging issues in communication it works great.

NI XNet Bus Monitor

The XNet Bus Monitor is newer, and a bit more mature.  Open it just like the NI-CAN one from MAX, and configure the hardware.  Here you can specify the baud rate, termination, and optionally specify a database for signal conversion.  Logging is also possible here which will log into a TDMS file that can be converted to other formats later.



Part 4...

So we've learned about various hardware options, and learned about the different bus types and communications in Part 1.  And we've learned a little more about what raw data looks like with CAN in Part 2.  And now we've talked about how to read and write these frames with the two NI CAN APIs.  Next we'll look at other hardware options and their APIs which function very similarly to the NI-CAN API.


CAN Part 2 - CAN Basics


04/12/2017 07:54 PM

In Part 1 we discussed the various types of CAN, how they differ from serial, and some hardware options.  In Part 2 we are going to talk about some more basics on what it means to use CAN and some of its features.

More Serial Comparisons (sorry)

So if you didn't get enough serial and CAN comparisons in the last part then sorry but you're going to hear it a few more times.  But instead of talking about the pros and cons of one or the other I want to talk about what it looks like when you send or receive data.  LabVIEW ships with several good examples on how to send and receive serial data and the one I always tell beginners to look at first is the Simple Serial example found by searching Simple Serial in the Help >> Find Example tool, if you have NI-VISA installed.

Simple Serial Example


Here we see the Simple Serial example and it is quite simple.  We configure our VISA resource and open it, then write a string of data, which is essentially an array of bytes.  We wait some amount of time, we read how many bytes are waiting in the buffer to be read, and read that data as a string which can be thought of as an array of bytes.  And then we close the port and have a basic error dialog.

The thing to realize with serial is we send an array of bytes, and we receive an array of bytes.  There is no defined protocol other than that.  Some manufacturers implement Modbus on serial to get some more structured control, but at the root of it you just are left with bytes coming in and bytes coming out with no way of knowing how many bytes to expect, or if there is a terminating character, or if there is data corruption along the way.  There is also no way of knowing if your data got to the destination, unless there is some kind of reply built into the device you are talking to.  CAN however has more structure to it in the form of the CAN Frame, and more robusness in the form of hardware features that help ensure the message sent gets to the receiver.

CAN Frame

Before we get into the LabVIEW example of CAN lets first understand the type of data we can receive and send.  With CAN in general the data you get and send usually isn't raw array of bytes.  In almost all situations the smallest amount of data you will get from a CAN read function is a single CAN Frame.  This frame contains multiple components of various data types.  At the low level a frame does get transmitted as a series of bits on the bus, which can be viewed with a scope.  But when we are discussing what is sent and received in CAN, the lowest level we will discuss is a frame which is between 41 and 113 bits of data.

All of the data that makes up a frame can be viewed differently through various APIs but the easiest to visualize is the XNet CAN frame, as seen below.

ID / Identifier / Arbitration ID (Scalar U32)

The first component to a Frame that we will discuss is the ID or Arbitration ID.  This is a scalar decimal number, represented as a U32.  The ID can either be 11 bits for a standard frame, or 29 bits for an extended frame.  A single node on the bus can transmit and receive both extended and standard frames at any time.  Furthermore IDs that fit in the first 11 bit range can be extended or standard.  So you can have an ID of 0x01 that is standard, and an ID that is 0x01 that is extended, where the data can be treated differently for each type even though the IDs are the same.

The Purpose of this ID is to categorize the data coming in.  We might want to designate the frame with ID 0x10 as a frame containing status information, and the frame 0x20 containing temperature information.  Or we may choose an ID of 0x30 as the frame we expect to see a request on, and we may choose to use an ID of 0x40 as the frame we send responses on.  It is also quite common for IDs to be assigned to specific devices on the bus.  So if we read a frame with ID 0x50 it might mean that a particular piece of hardware sent it.

One other purpose for the ID is priority.  The higher the CAN ID the higher the priority.  This means if two devices are on the bus ID 0x10 is trying to be transmitted by one device, and another device is trying to send a frame with ID 0x20 then the 0x20 frame will go out, and the 0x10 frame will have to retry later hopefully when either the bus is idle, or a frame with a smaller ID (lower priority) is being sent.  This is often not a concern, since each device on the bus should attempt to minimize the amount of data it sends.  If the bus load reaches 90% or more, dropped frames, and retries might cause frames to not be received by all the nodes on the bus.  More details on priority and re-transmission will be discussed at the end of this post.  But for now lets continue with the Frame contents.

Extended (Boolean)

The second component in the frame we've already talked about.  It is a boolean which indicates if the frame is from an extended ID, or a standard one.  Because the ID is a U32, and only 29 bits at most are used, NI-CAN has chosen to bit mask the ID and an ID with the bit 30th bit true indicates an extended frame.  Other APIs choose to bundle the frame into a cluster, and some have it as a discreet input to a subVI.  This designation of if a frame is extended or standard exists for frames read, and frames to be written.

Payload (Array of U8 Bytes)

Another component of a frame is the actual data, or payload being sent or received.  For all versions of CAN except CAN-FD, the payload can be anywhere between 0 and 8 bytes by whole byte increments.  CAN-FD is a special and can have payloads up to 64 bytes, but not always in 1 byte increments.  Within these 8 bytes we can pack all kinds of information.

Lets say we have 64 relays in our system and we want to send the state of the relay (on or off) out over CAN so other nodes can read it.  We could do this by having 64 different frames, each with its own unique ID.  Or we could choose to have a single ID with 64 bits of information packed into the 8 bytes of payload.

All kinds of other data can be packed into these 8 bytes.  Like maybe we want to report a temperature which ranges from 0 to 10.  If we increments of 1 degree, the minimum number of bits needed would be 4 (2^4 is greater or equal to 10).  But maybe we want to increment by 0.1 and we'll need 7 bits (2^7 is greater or equal to 100).  Or range from -10 to 10 with increments of 0.01 and we'll need 11 bits (2^11 is greater or equal to 2,000).  We'll get into the details about these scaling techniques in a later post.  But for now just know a frame contains data, and it is between 0 and 8 bytes which can contain between 0 and 64 individual pieces of information.

DLC (Scalar U8)

DLC is a number that represents the number of bytes in the payload.  Because arrays in LabVIEW are unbounded, most LabVIEW APIs don't explicitly have a DLC because this information can be found by taking the array size of the payload.

Time (Time Stamp)

Not all APIs provide this, but the good ones do.  This is a scalar Time Stamp, or a scalar double with some kind of defined epoch, to indicate when the frame was received.  This information is ignored on a CAN write since the data generally just goes out as soon as possible.  But even with periodic writing functions the timing is defined by the database (more on that in a later post).

Because many applications aren't running on a deterministic operating system, a common technique is to wait some amount of time, then call the read function, and have it return all the frames that are in the hardware buffer waiting to be read since the last read.  This technique is common on other protocols like TCP and Serial.  The problem with this is if we wait 100ms and then perform a read and get 10 frames back, we don't know for sure how much time is between the first frame and the 10th frame.  All we know for sure is it is less than 100ms.  With the time component in the frame we can know at what time each frame was read by the hardware.  Not necessarily what time the frame was transferred from the hardware buffer.

Frame Type (Enum / Ring)

Not all APIs provide this and it isn't that common of a feature.  But a frame can be of a few different types.  We've so far been talking about the Data Frame, where data is sent out autonomously.  But if one node requested some data, the node replying could choose to send the data as a Remote Frame indicating that the data is intended for the node that requested it.  All nodes on the bus still read this frame like normal, but a node can choose to ignore it, if it didn't recently issue a request for data.

A frame can also be of the Error type, and Overload type.  These are also not very common but have their uses like when a frame is read by a node but some level of corruption was detected.

Echo (Boolean)

When a frame is sent by your hardware, sometimes it can be read back.  This is a great tool for knowing if and when a frame you intended to write, actually made it onto the bus and was read by the other devices on the bus.  An echo is generally a function of the CAN transceiver but not all APIs support it.

Basic Read / Write

We will go into this example more in the next post, but for now this is intended to show the basic way frames are read and written, as compared to the serial example from earlier.



Similar to the serial we have an open function at the start and a close function at the end.  We also have a button to perform a write, and periodically we query the hardware, and return all the frames that it read and display it as a table.  If you are using the NI-CAN API this is a great starting point, and can help identify wiring issues, before you try to use the CAN bus in a large application.

Automatic Re-transmit

CAN has several useful feature built in to the hardware which makes the bus very robust.  The first thing we'll discuss is that the hardware has an automatically re-transmitting feature, for data that didn't reach any other node on the bus.  This re-transmit functionality is built into the hardware and no special software is needed to take advantage of this feature.  If a device writes a message on the bus, and no device sends an acknowledgement, the device will continue to send that frame over and over until it is read, and then acknowledged by a node on the bus.  The only exception to this is if the hardware is told to send the frame once, and not perform the automatic re-transmit.  This is sometimes known as Single-Shot transmission and most APIs support this.  This single-shot mode should be used with caution because as we will learn, lost frames can be a normal occurrence on a CAN bus.  And re-transmitting when the frame is lost is a good thing.

There are two primary sources for a frame to be lost and not reach its intended device, priority, and poor wiring of the bus.  In Part 1 I mentioned the standard way to wire a high speed dual wire bus was with two 120 ohm resistors, and with each node being a short distance from the bus.  For long runs twisted shielded pairs of wires may also be necessary to reduce electrical noise.

Priority

As mentioned earlier in this post, the ID of the frame defines the priority of the message.  And since CAN is full duplex with support for potentially hundreds of nodes, it is possible that two devices on the bus are trying to write at the same time.  What will happen in this case is the higher priority message will be sent out, and a device on the bus will acknowledge it, but the lower priority message won't be read or acknowledge.  As a result the device will wait for the bus to be idle and try to send the message again.  Of course it isn't guaranteed that the second time we write the frame on the bus, that it won't again be lost due to a higher priority frame.  In situations where the bus load is very high, a frame may never go out.  In practice this doesn't happen often.  The intent is to have few high priority messages, since it can preempt other bus traffic.

CRC

When a frame is written to the bus, a 15 bit CRC will also be sent.  This is automatically generated by the transceiver and generally there is no control over it.  When another device on the bus reads the frame it will determine if the message was valid by looking at the CRC that came with the data.  If it fails the CRC check, the device will not send the acknowledgement for receiving the frame.  This partial frame will not be available to software querying the hardware and is usually filtered by the transceiver.  After not receiving the acknowledgement, the original device will re-transmit the frame, hoping it will reach its intended devices.

Part 3...

With the understanding of the various hardware available, and the concept of a CAN frame we can finally start to talk about specific APIs and how to use them.  In Part 3 we will finally look at some NI examples of reading and writing CAN data.



CAN Part 1 - Hardware


03/27/2017 12:12 AM

The CAN bus.  Where do I begin.  I've said before that there are people who spend their entire career working on the CAN bus, and its true.  I'm not one of them but I do work with CAN often, and the more I learn, the more I realize I don't know enough.  So this series of posts is intended to help demystify some of the CAN bus that we use for various communications.  First lets focus narrowly on the hardware, and more specifically we will first focus on the most common CAN setup which is dual wire high speed CAN.  This first entry is going to try to cover the basics, and you won't hear much about how to actually do anything in software.  But this is an important step none the less to understand the differences, wiring techniques, and features of various CAN buses.

Hardware

Before we get started on the discussions of various CAN software and communication protocols.  Lets first talk about what CAN is physically.  This is not CAN:

This is a USB to serial converter.  The 9 pin connector known as DB9 is a common way to connect hardware that communicates over RS-232 and RS-485.  This same DB9 connector is the most common interface you'll find for CAN hardware as well.  But just because they share the same connector, does not mean they communicate with the same protocol.  If you have a DB9 on your computer, it does not mean you have CAN.  If you can manage to shove a USB cable into your ethernet port, don't expect it to work just because it fits.  

There do exist USB to CAN converters like this ValueCAN from Intrepid, with other common competitors like Vector, NI, and Kvaser having similar low cost products.
These look similar to USB to serial converters, but talk very different protocols.  The first major difference between serial and CAN is that with a two wire serial interface you typically only talk to one device at a time.  With the transmit wire on one end, getting wired to the receive on the other. 


With CAN you can connect potentially hundreds of devices together.  This is because each CAN device that is two wire has a CAN-High and a CAN-Low wire.  But instead of swapping wires like serial does, you wire up all the CAN-Highs together, and all the CAN-Lows together.  In a typical two wire high speed CAN setup, you will also have two 120 ohm resistors between high and low on each end of the bus.  

These resistors are optional in some cases and depending on the length and number of nodes, can be replaced by a single 60 ohm resistor, or some other configuration.  With long CAN lines you may get signal reflection, causing corrupt messages.  CAN is pretty robust and even dropped messages will be resent.  So even if you have no resistor in place there is a chance it will work fine.  But if you are getting lots of lost messages or communication issues check that you have the appropriate wiring.

Serial and CAN also vary quite a bit when it comes to their features.  Lets compare RS-232 serial to a dual wire high speed CAN bus.


Serial and CAN Comparison
RS-232 SerialDual Wire High Speed CAN
Dual wire system with TX and RX usually seen as a DB-9.Dual wire system with CAN High and CAN Low usually seen as a DB-9
Only two nodes can ever be on the bus at once.Potentially 100s of nodes.
Things like priority, ACK, checksum, retransmit, end of message, and message length can be done through software.The hardware transceiver supports priority, ACK, CRC, retransmit, end of message, and message length.
Standard baud rates up to 115.2 Kbit, with some support for higher.Standard baud rates up to 1 Mbit, with CAN-FD up to 8 Mbit.
Usually request / response.Usually periodic transmission
Much cheaper to implement, and most industrial PC come with it built in.More expensive to implement.

Requires two termination resistors



Just like how there isn't just one serial protocol, there also isn't just one CAN protocol.  As mentioned earlier the typical CAN setup is with two wires, and the most common baud rate is 500K.  This would be considered High Speed CAN.  There is also Low-Speed, Medium-Speed, CAN-FD, and a few other variants.  There are also CAN setups that are dual wire, and some that are single wire, with the devices on the bus sharing the same ground.

Dual Wire Configurations

In a dual wire configuration, only CAN_H and CAN_L need to be wired unless the specific hardware requires power.  Common shielding and ground are also usually not necessary for testing purposes but maybe desired in long buses or buses when there are many nodes.  Ideally this is with twisted shielded pairs of wires going from one node to the next.  A star-like wiring pattern should not be used, but instead a single long chain of nodes.  The distance from a bus node and the bus should be kept to a minimum.  This sometimes means using 4 wires, CAN_H In, CAN_L In, CAN_H Out, and CAN_L Out.



The highest expected voltage potential between the CAN_H and CAN_L is 5V.

High Speed CAN (Automotive SAE Class C)

Again this is the most common type of CAN bus seen, and is wired using the example from earlier.  Once wired, every node on the bus must be set to the same baud rate which can range from 125K to 1M.



Low Speed Fault-Tolerant (Automotive SAE Class B)

Manufacturers may call this Low Speed, Fault-Tolerant, or LSFT.  This is still a dual wire configuration but each node on the bus has an internal termination.  The baud rate of this type of configuration can vary from 10K up to 125K.

CAN-FD

CAN-FD is relatively new and stands for Flexible Data Rates.  As automotive manufacturers pushed CAN to its limits they realized they wanted ways to send and receive more data and faster.  Several software protocols were made to help with this but at the end of the day the baud rate, and payload size was what was limiting the throughput.  The new CAN-FD still uses the same High Speed CAN wiring scheme and can use the same existing buses.  The only thing that is needed is to have upgraded CAN transceivers on each node on the bus.  With this the baud rates can be increased to 8M, and the payload size can increase up to 64 bytes, while all other CAN interfaces are limited to 8.  (more on that in later posts).

Most CAN hardware is not CAN-FD compatible, but several of NI's hardware is.

Single Wire Configurations

Single wire CAN is as the name implies, needs only a single wire connected between all nodes on the bus.  The only other requirement is that all the nodes be powered from the same ground.  Wiring is simplified because all that is required is the single CAN_H in the diagram below is wired to all the devices, and then all device need the same ground, which is easy to do if all devices get their power from the same source like a battery.  Twisted shielded pairs are not necessary but as a result the stable baud rates are decreased.



Single wire CAN can operate in a slow speed which is 33.3K or a high speed which is 83.8K.

High Voltage Wake Up

A unique feature of the single wire interface is the high voltage wake up.  High voltage in this case is quite relative and just means that the voltage will be at the voltage of the battery which in automotive is typically 13.8 volts but most hardware can range from 9V to 24V.  As mentioned in the dual wire configuration the highest expected voltage between CAN_H and CAN_L is 5V.  In the single wire configuration this is true for the voltage between CAN_H and Ground, except when high voltage is enabled, and then the differential will be VBat.  This allows for some devices on the bus to go into a low power sleep mode and draw very little power.  When the voltage above 5V is seen on CAN_H the device can wake up and start operating again.  When using the high voltage wake up feature it is usually only used for a short time, and then the bus goes back to operating like normal.  This feature is software selectable in both NI and Intrepid hardware.

PC Hardware Options

Now once you know what type of bus you are using, the next thing to be considered is what hardware is needed to connect a bus up to my PC for reading and writing data.

CAN-FD Hardware

If you need a CAN-FD bus then you have only a couple of options with my recommendation being the NI XNet line of hardware, which is in the PCI, PXI, cDAQ, and USB form factors.  There are a few other vendors that have some support like AVT, and Vector, but since their driver support for external interfaces isn't as mature as NI's API I'd stick with them for now.

CAN-FD Hardware
HardwareCostNotes
USB-8502/1 - USB-8502/2$550-$750USB single or dual port high speed, and FD
PCI-8512$1,201Single port, high speed, FD
PCI-8513$1,568Single port, high speed, FD, low speed, and single wire, software selectable
PCI -8512/2$1,806Dual port high speed, and FD
PCI-8513/2$2,285Dual port, high speed, FD, low speed, and single wire, software selectable
PXI-8512$1,167Single port high speed, and FD
PXI-8513$1,524Single port, high speed, FD, low speed, and single wire, software selectable
PXI-8512/2$1,754Dual port high speed, and FD
PXI-8513/2$2,220Dual port, high speed, FD, low speed, and single wire, software selectable transceiver
PXIe-8510$1,987-$4,1221 to 6 ports, high speed, and FD
NI-9862$746cDAQ/cRIO single port high speed, and FD
NI-9860$937-$1,324cDAQ/cRIO single or dual port high speed, and FD

Single Wire Hardware

If you need a single wire CAN interface your options are again limited.  NI has a couple of software selectable transceivers in the PCI or PXI platform only.  Outside of NI I've had success with using the Intripid line of hardware and used the single wire bus on a NeoVI Fire.  The outdated LabVIEW drivers function fine, and the documentation explains how to use the high voltage wake up feature, despite it not being in the LabVIEW driver.  This is a very cost competitive device if multiple buses are needed since it includes 3 dual wire high speed CAN buses, one dual wire medium speed CAN bus, one single wire CAN, and 4 LIN buses, and a few simple analog inputs, for $2,000 in a single USB form factor.  The drivers are done through a Windows compiled DLL so using it on embedded hardware or other operating systems will be quite difficult.  Where the NI solutions clearly work well with any NI platform like cRIO, embedded cDAQ, RT Linux, and others.  Another option might be AVT and their AVT-852 or AVT-853 USB or Ethernet based devices.  I've never used the single wire option on this hardware but looks promising with multiple protocols and interfaces for the lowest price of them all.

Single Wire CAN Hardware
HardwareCostNotes
PCI-8513$1,568Single port, high speed, FD, low speed, and single wire, software selectable
PCI-8513/2$2,285Dual port, high speed, FD, low speed, and single wire, software selectable 
PXI-8513$1,524Single port, high speed, FD, low speed, and single wire, software selectable
PXI-8513/2$2,220Dual port, high speed, FD, low speed, and single wire, software selectable
neoVI FIRE$1,995USB 3 high speed, 1 medium speed, 1 single wire, 1 low speed, 4 LIN
AVT-853~$400Ethernet interface, 1 high speed, 1 high speed or single wire, multiple built in protocols like ISO 15765, J1939 and others

Low Speed Hardware

The options here are again basically just NI's offerings, and Intrepid's neoVI FIRE.  I'm not going to list all the options here, but NI has offerings in PCI, PXI, cDAQ, cRIO, and USB platforms.

High Speed Hardware

If your needs are for the more common dual wire high speed bus, then you are in luck.  Not only do all of the CAN-FD options mentioned earlier work, but there are several other options from NI, and other manufacturers like Kvasar, Vector, and more.  NI has two basic CAN platforms, NI-CAN which is older and NI-Xnet which is newer.  Along with each hardware type is a different API.  The newer XNet hardware can have compatibility drivers installed so that they can use the older NI-CAN API but honestly the XNet API is much easier to work with when you are doing anything other than basic frame reading and writing.  The APIs for other manufactures are basically like the older NI-CAN API with support for reading and writing raw frames and not much else.  The options here and plentiful so I won't list them all, but I will add some of the hardware I've used outside of NI that I've had success with.

Single Wire CAN Hardware
HardwareCostNotes
neoVI FIRE$1,995USB 3 high speed, 1 medium speed, 1 single wire, 1 low speed, 4 LIN
Vector CANcase XL~$1,000USB dual port, high speed
Vector VN1630~$2,000USB dual port, high speed
Kvaser USBCAN Professional$1,100USB dual port, high speed
AVT~$400USB or TCP, multiple built in protocols, and multiple interfaces including analog LIN and CAN
Lawicel CAN232$120USB or RS232, single high speed.
Teensy 3.1/3.2 Microcontroller~$30Custom C++ code needed but the library is available

So with such a large range in price what's the difference?  Are all CAN hardware the same?  Not quite but most might share some of the low level hardware.  The CAN transceiver, which is the actual chip doing the heavy lifting, is likely the same between several manufacturers.  The most common high speed transceiver I've seen is the MCP2551, which is often paired with the MCP2515.  The result is high speed CAN on one side, and SPI on the other.  But if your microcontroller interfaces with the CAN bus like the Teensy line then all that is needed is an MCP2551.

Which to Choose?

So if these two chips are in several of the manufacturers devices why the price difference?  Well NI's offerings generally do CAN-FD and not just high speed, so it is using a different transceiver.  But the main benefit is support, and software tools.  NI wants you to buy NI hardware so you can use it with LabVIEW, Vector wants you to buy Vector hardware so you can use it with their software.  Intrepid is the same way, and Kvaser to some extent.  So while a Vector CANCase may work great with CANAlyzer, expect to pay thousands of dollars, for their software packages.  But we aren't interested in that, what we want is to use our hardware, with our software.  And for that we are at the mercy of whatever drivers are provided.  All the devices I've listed can work with LabVIEW and have some drivers, but the clear winner when it comes to software and support is the NI XNet line of hardware.

Part 2...

So in the next part of this series I'm going to start with the best option, and talk about the NI XNet API along with NI's older NI-CAN API.  We'll also discuss what hardware works with what, and some examples on how to use it.  Then later we'll talk about the other hardware options, and why they are a bit harder to work with.



New Micro, New Project


12/16/2014 03:46 PM

New Micro, New Project

So I've discovered my new favorite microcontroller.  It's the Teensy, and right now it is version 3.1.  I've used the Teensy on a few small projects at work, and love how powerful it is, in such a small form factor, while being cheap, and Arduino IDE compatible.  After using the Teensy on a few projects, I doubt I'll ever go back to an Arduino, unless some new awesome version comes out.

Anyway so I have this time off of work, and I wanted to give my self a project using the Teensy while I am off.  I didn't know what I wanted to do but I had a few ideas.  I saw the powerful audio library made for the Teensy and thought that would be a fun start.  I also saw some neat LED matrix boards and thought about some kind of bright sign of some kind.  And lastly I knew I wanted to incorporate the ESP8266 WIFI chip.  This is the dirt cheap WIFI chip from China that has been getting more support from communities, and figured it would be the cheapest way to add wireless to any microcontroller project, assuming a WIFI network exists in the area to connect to.

So with all this in mind, I decided to make some kind of scrolling marquee sign, which could be updated over WIFI.  Later I decided to add the audio capabilities for performing FFTs, to visualize the audio being played on my TV.

Parts List

Teensy 3.1 Microcontroller $20
16X32 LED Matrix $25 X 2 = $50
SmartMatrix Shield for Teensy $15
5V 10A Power Supply $25
ESP8266 WIFI Module $5
Various small electronic components (LM317T Voltage Regulator, 220 Ohm, 330 Ohm, and 4.7K Ohm Resistors, small perf board, capacitor, and push button) less than $10.

Total $125 or so

Wiring

So the construction of the project is relatively simple.  Put together the SmartMatrix Shield for the Teensy, and attach it to one of the 16X32 LED matrix boards using any of the methods described in the instructions.  Then connect the second matrix board to the other with provided ribbon cable.  Powering this setup is easy because our 10A power supply is more than enough for our LEDs, and plugs right into our shield.

A push button was added to switch between modes, and is mostly optional but I had one and figured I'd put it to use.  Wire it so that between ground, and the DI pin is a relativly large resistor.  I used a 4.7K ohm.  Also in my wiring I used DI 15.  Then wire the 3.3V out of the Teensy to one side of the push button, and the other side goes to DI 15.  Now when the button is off ground will be going to the digital, and when it is pressed the digital will see 3.3V which is a high.

I also wired a headphone jack to A2 so that the audio can be visualized in an audio spectrum.

Lastly the WIFI module.  This needs to be powered by 3.3V, but draws too much for the 3.3V from the Teensy.  I tried some large capacitors and it would some times work, but had other issues and in the end I just bought a LM317T voltage regulator to convert my 5V from my power supply, to the 3.3V the WIFI board needed.  Using a value of 220 Ohm for R1 and 330 Ohm for R2 should give an output of 3.13V, plus a small amount for a compensation current.  A different regulator could be used but this is what Radio Shack had.  Then the TX and RX need to be wired up.

Below is very crude drawing of the wiring.  Note that the 5V and Gnd are wired to the Teensy using the shield, and are only shown to have the wiring make sense and shouldn't be wired up if that shield is used.



Software

In my mind this is where it gets interesting.  So the SmartMatrix boards I bought have a working library and demo which generally was designed to work with a single 32x32 matrix board.  I first had to make sure a single 16x32 worked, then looked into making the software support 16x64.  Luckily some work had been done to support multiple boards being daisy chained together, but they were for much older revisions of the library, which didn't have the audio example I wanted.  So I took the newest revision of the library, and updated it with the changes others had made for the older versions to support the wide display.

After this it looked like all the already made functions for text scrolling, and object drawing works on 16x64.  I then looked at the audio example and modified it to support 32 FFT categories instead of 16.  I also added some tweaks to it to dynamically change the scale to help with varying audio levels, and to try to detect when there is no audio, instead of displaying noise.

Next was the ESP8266.  This supports many AT commands and behaves more or less like a serial port, where commands are issued, and then you then parse each byte one at a time to determine what the reply is.  After some examples I was able to connect to my WIFI and get an IP address.  I then sent the commands to allow it to accept connections on port 4040, and then parsed the requested URL and turned that into the text to be displayed.

With these changes now when I turn on my device, it will connect to my WIFI and start displaying the assigned IP address on the scrolling LEDs.  If I navigate to the IP address like in this example it would update the text to be scrolled to "Hello World."

http://192.168.0.119:4040/Hello_World

This is of course only if my device connected successfully and only if the IP address was correct.  At the moment it doesn't support all special characters, and it replaces all underscores with spaces.  I didn't take the time to support replacing "%20" with a space.  It will continue to scroll that text over and over until new text is sent.  Also at the moment the display is limited to 70 characters or less.

All of the source and libraries used can be downloaded from here.  Arduino IDE version 1.0.6 was used and Teensyduino version 1.20 was used.  You'll need to update the SSID and Password to your network before uploading.

Assembly

To make it look a little better I made a small cage for the hardware.  I used a metal stud normally used in walls, and cut them to the length I needed.  I then used some small chunks of metal and screws to make the cage.  The LED panels have magnets on them so they just stick to the metal cage.  In the cage is all the electronics, and the voltage adapter.  I then can hang it from the wall using two screws.  Below are some images of the assembled cage and lights.

Assembled

Back View

Into Back

With Cage Off

Teensy and WIFI Board

And here are a couple videos of it in action.  The first video just shows how the IP address is shown on startup.  The second video shows the 4 modes, of 'text only', 'audio only', 'text and small audio', and then 'text will full audio'.  The lights are bright and during the day time the text is still very easily readable at 30 feet away.  The video may look odd because the camera is constantly trying to adjust for brightness but it looks normal in person.

LED Matrix Startup


LED Matrix In Action


Improvements

So since making this I know of several things that could be better.  These are all optional and maybe I'll get to them some day.  

  • Microphone 
    • I'd rather use a small microphone and amplifier circuit like this one for detecting sound but didn't order one, and besides I figured the best case for getting the right audio signal would be a hard line from a headphone jack.  This would just make it simpler for the user
  • WIFI page for configuring
    • I would be nice if a web page was made for configuring things like what network and password to connect to on the ESP8266 instead of hard coding it in the sketch.
  • VLC page for current song
    • Right now the device is passive and only updates the text if it is told to.  It would be nice if instead the device looked at a URL and read the current playing song from that.  VLC has this capability and when turned on a basic page gives this information.  It would just take some time to write the code to parse it. The software would also need a way to know what the URL.
  • Maybe make it taller
    • Originally I intended on having two rows of text for the song and artist.  But then realized I'd rather have the audio spectrum and went to one row of text.  If I had bought two 32x32 matrix boards, I could have two rows of text, and room for the audio spectrum.  This would increase cost, and the software would need some adjustments because I'm not sure the library currently supports multiples lines of scrolling text.
  • Improve WIFI connection
    • At the moment there is no retry for a network connection, if it fails the display will show 0.0.0.0 for the IP address.  This has only happened a few times but it could detect this, reset the chip and try again.  Also there are several arbitrary waits that I think could be reduced.  And at the moment it will attempt to reconnect to the network each power up, and this is not really needed because the chip remembers the last connection made.  This could also save several seconds on startup.





All Posts