What's new
Van's Air Force

Don't miss anything! Register now for full access to the definitive RV support community.

EFIS flight data interchange protocols

Preliminary CAN-FIX Specification

I've posted a preliminary specification for CAN-FIX at...

https://sourceforge.net/projects/fix-project/files/

It is by no means complete and I'm sure there are many typos, grammatical errors, spelling mistakes and general technical difficulties with it.

There are a lot of parameters that are missing units, ranges etc.

I'd appreciate any comments / help. The FixIDs.ods file is a LibreOffice Spreadsheet file that has all of the parameter definitions. If you have LibreOffice (and it's free so why don't you) feel free to help fill in some of the blanks. Be sure to turn on change tracking so I know whats new.

My new USB<->CAN interface just got delivered today so I hope to start playing around with some hardware tonight.
 
CAN-FIX Specification

It seems that I had a foundational misunderstanding of the CAN protocol and how it arbitrates messages. Thanks to some offline comments, I have now been set straight. That's why we call it 'development' right? :)

Basically, CAN arbitrates messages by requiring all senders to read the bit on the bus as they are sending. If the bit on the bus is different than the bit being sent then the sender is supposed to stop, because that means that somebody else is sending a higher priority message. The winning bit will always be 0 because of the electrical design. This is why a lower numbered ID will have a higher priority.

Well I thought that this arbitration continued throughout the message, not just with the ID field. I was wrong. If two nodes try to send different data with the same ID at the same time then an unrecoverable error will result. I was relying on my misunderstanding for most of my protocol design so obviously it won't work.

I put the node number first in the data field assuming that would allow two different nodes to send the same parameter simultaneously and then the node with the lower address would win and the other would retry. This won't work. That would be an error.

Oh well. Back to the drawing board, as they say. The major departures that I made from CANaerospace are based on this misunderstanding so I'm going back and looking at CANaero to see if there is a way for CAN-FIX to play nice with the existing standard. There are still some things that I don't like about CANaero but we may be able to reconcile them without having to start from scratch.

Stay tuned.
 
I don't envy you.
Trying to make any sort of standard using CAN is difficult and bound to be rejected.
AeroCAN is a prime example. There is nothing wrong with it but due to the way things have been setup it becomes cumbersome. It is very easy to fall into the same trap as you try and figure out how to use 8 bytes of payload without throwing away precious bandwidth.

We are moving to CAN in a big way ourselves currently and have faced exactly the same problems leading to propriety implementation. This is nothing new, look at any CAN implementation in a vehicle and the same thing happens for the same reasons. Even JS1939 is a nice document (for engine monitoring on CAN) but of little practical value.

CAN is good if you use it just the way you as implementer want it. It falls on its face if you try and create a universal way of using it as you simply don't have the bandwidth to move large amounts of data in a universal protocol using individual, known data items.

The only way you will have some sort of acceptance and a usable system is to force simplicity, fixed units and predicable, known data formats.
Don't forget the primary purpose of CAN - to move small chunks of data as safe as possible on a common link between multiple nodes and typically there are NOT that many nodes in the system. Your protocol needs to take heed of this. Clever use will see you using address bits as part of message identifiers and protocol overhead to preserve the actual data space for just that - data.

Rainier

It seems that I had a foundational misunderstanding of the CAN protocol and how it arbitrates messages. Thanks to some offline comments, I have now been set straight. That's why we call it 'development' right? :)

Basically, CAN arbitrates messages by requiring all senders to read the bit on the bus as they are sending. If the bit on the bus is different than the bit being sent then the sender is supposed to stop, because that means that somebody else is sending a higher priority message. The winning bit will always be 0 because of the electrical design. This is why a lower numbered ID will have a higher priority.

Well I thought that this arbitration continued throughout the message, not just with the ID field. I was wrong. If two nodes try to send different data with the same ID at the same time then an unrecoverable error will result. I was relying on my misunderstanding for most of my protocol design so obviously it won't work.

I put the node number first in the data field assuming that would allow two different nodes to send the same parameter simultaneously and then the node with the lower address would win and the other would retry. This won't work. That would be an error.

Oh well. Back to the drawing board, as they say. The major departures that I made from CANaerospace are based on this misunderstanding so I'm going back and looking at CANaero to see if there is a way for CAN-FIX to play nice with the existing standard. There are still some things that I don't like about CANaero but we may be able to reconcile them without having to start from scratch.

Stay tuned.
 
<<snip>>
The only way you will have some sort of acceptance and a usable system is to force simplicity, fixed units and predicable, known data formats.
Don't forget the primary purpose of CAN - to move small chunks of data as safe as possible on a common link between multiple nodes and typically there are NOT that many nodes in the system. Your protocol needs to take heed of this. Clever use will see you using address bits as part of message identifiers and protocol overhead to preserve the actual data space for just that - data.
Rainier

Agreed. One of the problems that I have with CANaerospace is that it allows too many different data types for the same information. I'd rather just specify the data type, because it makes it easier to implement. The easier it is to implement the more widespread it's acceptance. I think that the vast majority of the data that needs to be transmitted in an aircraft are small chunks of easily pre-defined data so CAN should be perfect. We get into trouble when we start asking ourselves, about how many engines we should support or how to handle scaling, ranges and data types. It will be impossible to make everyone happy, but I hope that we can figure out a way to make it easy to implement yet extensible enough cover the unforeseen.

In any case I'm learning a LOT! Which was most of the motivation for me anyway. :)
 
Yes, that is exactly correct. You are on the right track.

No point in having multiple formats for the same data - just screws around everybody and creates major additional overhead for any application just to find out what it is looking at (never mind the potential bugs that this could add).

For example, consider altitude. Decide on a format (most likely binary), units (choose the smallest practical, like 1 foot) and number of bytes (perhaps a two byte value with an offset so you can cater for negative values). Assume a 2000 ft offset (so the value 2000 is zero ft altitude) - that leaves you some 63000 ft of range. Probably good enough. You could of course scale. Say anything above the value 50000 is in 10 ft increments. This means you have the entire practical range of a pressure altimeter covered with just two bytes. No options, no discussion, no uncertainty - everybody that wants to use the value knows exactly what to expect the moment the first message containing this value has been received.
You don't need to cater for anything larger here - for space flight we need more altitude but that is not based on a pressure altitude so would be a different variable anyway.

Dictate your protocol, don't try and cater for every variant of data formats, don't accomodate. You are the boss. Just do one very important little thing - don't hog the bus - allow for packets to exist that have been defined by somebody else to do something that just is not catered for or too special in nature. Try and define something that can coexist and leaves enough headroom for a vendor to use the bus for his particular needs as well.

There are perhaps only a couple of dozen real interesting data items that would be nice to have. Have a look at www.MGLAvionics.co.za/Docs.MGL EFIS data feed.pdf for some inspiration. This one is targeted at RS232 but it might give you some ideas.

Rainier

Agreed. One of the problems that I have with CANaerospace is that it allows too many different data types for the same information. I'd rather just specify the data type, because it makes it easier to implement. The easier it is to implement the more widespread it's acceptance. I think that the vast majority of the data that needs to be transmitted in an aircraft are small chunks of easily pre-defined data so CAN should be perfect. We get into trouble when we start asking ourselves, about how many engines we should support or how to handle scaling, ranges and data types. It will be impossible to make everyone happy, but I hope that we can figure out a way to make it easy to implement yet extensible enough cover the unforeseen.

In any case I'm learning a LOT! Which was most of the motivation for me anyway. :)
 
CAN, think differently

The problem with CAN is a problem of perception. Most of us software guys work with Ethernet much more that anything else. If you approach CAN and try to impress Ethernet mentality you will fail. It just isn't built to function that way. The concepts of broadcast and point to point communications are almost opposite in their implementations. As Rainier points out, CAN was built to move small data chunks quickly to many receivers not large chunks (like video) between two specific devices.
The best example I can think of is airspeed. If the RS-232FIX protocol places airspeed on the CAN bus, all my trim servos and my flap controller receive the message at the same time. Minimum bus usage with maximum return as thee devices receive the same information. Devices not keyed to receive airspeed ignore the message in hardware so their performance is not impacted.


I still believe CANaero is a good basis for a system. What I proposed was to define a new dictionary (This is supported in CANaero) and use a subset of CANaero functions. This would simplify the initial protocol and programing requirements and yet still be compatible and able to share the bus with more complex devices that are CANaero 1.7 compliant. Limiting or simply defining what datatype(s) are acceptable in a new 'FIX' ID dictionary would be acceptable, compatible and simple to define.


One other thing about CANaero that we should keep. It reserves space for 3rd party devices. This allows manufactures who want to stay proprietary a range of Ids so they can share the common bus
 
I'm starting to be convinced. I still think that there is some room for improvement but we can overcome most of the shortcomings in CANaero with some specifications within the node service codes and user defined data areas. I'll spend some time with the CANaero spec this weekend and see if I can't figure out a way to fit all this in a way that makes sense.

I'd also like to figure out a way to standardize firmware updating and configuration so that the user only has to have one program to update and configure any node on the network.

Has anybody had a chance to scrutinize the list of data points from my spec? The protocol won't work but we still need to come up with a good list of data points, with data types, ranges, units etc. I know that Vern is dealing with these issues with the manufacturers. The more commonality we keep here the better off we'll be.
 
I'd also like to figure out a way to standardize firmware updating and configuration so that the user only has to have one program to update and configure any node on the network.

No, don't.
That should be left to the vendor and should use vendor defined methods.
There are too many possible architectures and ways to update firmware and it tends to be specific to an item.

Rainier
 
Looks like Dynon has done a great job with this look at what they are planning for the Skyview. They are adding a bunch more data to their format than what is possible with the Legendary system. They also appear to be getting rid of the weird way they swapped data sources for a few of the characters. This coupled with the fact that they are gonna allow the end user to modify the streaming baud rate really makes their format cool!

Too bad they wouldn't make the old and new series inter-operable. Maybe once all the formats are published, some enterprising person will create a data exchanger unit that allows you to link any vendor's product to any other.

Update: Ok, now I've read the whole thread. My programming days are over pretty much except SQL, but perhaps I can contribute to documentation. Doesn't look like this project needs a PM as there may be too many cooks already; besides lots of smart people committed to a goal don't need overhead.
 
Last edited:
I don't think Dynon plans to open up the DSAB side of things. If they would though, I would be all over making a bridge module....
 
No, don't.
That should be left to the vendor and should use vendor defined methods.
There are too many possible architectures and ways to update firmware and it tends to be specific to an item.

Rainier
Rainier, defining a channel or some basic id to create an update channel is no more restrictive than demanding an RS-232 connection to update software. I think the general idea is to simply define the transfer layer over the CAN bus while the vendor implements both the download and/or updates as needed in their system. By defining a 'virtual' RS-232 channel the system will be more predictable when shared between vendors. For those who must go it alone, there is always the 3rd party reserved ID's for those who need them.
 
Don't bother with this.
All that will happen is restrictions.
Use the CAN for what it is intended. Keep it simple.

Some of the more fancy CAN based microcontrollers define a CAN boot loader as part of their built in firmware. Often that is a convenient way to update or load code (simply because that is the intention).
There is no common protocol for this at all. Every vendor implements his own method.

It is very typical for an effort like this to be derailed by feature creep and this is starting to show. Keep it simple and to the point to cater for 95% of the needs. Trying to fill the remaining 5% is going to blow the lid off.

The original idea (and the one behind this entire thread) is to have a common format (or a few) to exchange common data between EFIS systems and simple third part hardware. There are only a few dozen data items that are needed for that. Really, that is all.
Cater for the basic needs while allowing unavoidable vendor specific use of the bus. This is all that is needed.

Don't fix something that ain't broken.

Rainier

Rainier, defining a channel or some basic id to create an update channel is no more restrictive than demanding an RS-232 connection to update software. I think the general idea is to simply define the transfer layer over the CAN bus while the vendor implements both the download and/or updates as needed in their system. By defining a 'virtual' RS-232 channel the system will be more predictable when shared between vendors. For those who must go it alone, there is always the 3rd party reserved ID's for those who need them.
 
Don't bother with this.
All that will happen is restrictions.
Use the CAN for what it is intended. Keep it simple.
Can't get much simpler than only suggesting ID's to be use for off-line updates.

Some of the more fancy CAN based microcontrollers define a CAN boot loader as part of their built in firmware. Often that is a convenient way to update or load code (simply because that is the intention).
There is no common protocol for this at all. Every vendor implements his own method.
Then this is by default non-standard and other devices left with power on in the system may suffer. What if another vendor used the same development downloader or bootloader and your code got pushed into their hardware? Guards would need to be in place for this. The development downloaders that I have seen were never intended for production use.

It is very typical for an effort like this to be derailed by feature creep and this is starting to show. Keep it simple and to the point to cater for 95% of the needs. Trying to fill the remaining 5% is going to blow the lid off.

The original idea (and the one behind this entire thread) is to have a common format (or a few) to exchange common data between EFIS systems and simple third part hardware. There are only a few dozen data items that are needed for that. Really, that is all.
Cater for the basic needs while allowing unavoidable vendor specific use of the bus. This is all that is needed.

Don't fix something that ain't broken.

Rainier
I agree but this is basic stuff here. Defining a 'suggested' download channel and offering a third party set of ID's is far from useless. For a common protocol to work vendors can not be stepping on each other. I see nothing wrong posting a suggested use for two or thee ID's for off-line updates and reserving a block of ID's for vendors to do proprietary work. Would you rather see a document that only specifiers what to avoid? If you did that the system would be frozen and never be expandable.
I feel your view is somewhat narrow (admittedly mine is). I am not looking at this from the view of a few FIX commands and a single vendors EFIS. That is not open. I am looking at this as a way for two or three devices to become a cohesive flight system even if I choose equipment from two or three vendors.
 
Another approach?

Rainier, may I suggest a second tack. As updating software should never be done 'in-flight'. Suggest a block of ID for maintenance that must be avoided during flight operations
 
Posted Version 0.2 of CAN-FIX

I just posted the second preliminary release of CAN-FIX. You can get it at...

https://sourceforge.net/projects/fix-project/files/

I gave up on the CANAerospace compatibility. It got to be more tedious than I first thought that it would be. The original goal here was to have a community maintained spec that is simple and easy to implement.

I went through Vern's FIX protocol and attempted to make CAN-FIX as compatible with that as possible. There still may be some issues. There are a million details in the parameters. More eyeballs will help.

I don't consider this to be finished. I suspect that there are many places were I could spend some time clarifying things and I know that there are ranges, units and data types that still need some tweaking in the parameter definitions.

Perhaps this time it might actually work. :)

The spreadsheet that I am using to keep track of the parameter list is there for download as well. It's a little easier to sort through.

Feedback is not only welcome, but requested.
 
Back
Top