Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/01/2010 in Posts

  1. Turning our lovely logo on its side makes it look like either a tube of toothpaste or a dead fish.
    2 points
  2. Within the context of a large test application, I recently wrote a set of utilities for defining CAN tags using the Channel API. In a nutshell, it allows for CAN channels and the associated messages to be defined from a configuration spreadsheet without the use of MAX. It handles scaling, limits, encoding, all the bits and bytes stuff, and is very easy and intuitive to use. It's all very cool, and most of it functioned perfectly right from the start without any hassles at all. I had successfully defined several little-endian, unsigned channels, of various widths, and everything worked great. Then I tried to define a channel to read a single-precision floating point value using big-endian (Motorola) format. LabVIEW kept throwing cryptic "an input parameter is invalid (but I won't tell you which one)" errors that didn't seem to make any sense at all. I chatted about the situation with friends and colleagues at Bloomy Controls and VI Engineering, and no one seemed to have a clue why I has encountering difficulty. We were collectively beginning to think that the CAN Channel API somehow couldn't deal with a Float32. We needed to read a channel that started at bit 8 and was 32 bits in length, in big endian format, and format that into a float, and LabVIEW simply wouldn't accommodate us. Since I knew that I could successfully read U16's, I formulated a fallback position that I would read the requisite 32 bits as two channels, and reconstruct the Float32 programmatically. Ugly, but workable. While I coded that, one of my co-workers at UTC Power hooked up a CANalyzer to watch the bus traffic. The CANalyzer showed the bytes coming through the way they were expected to, but my two U16's showed bytes shifted in strange ways, crossing word boundaries, and things didn't make sense. And then there was a flash of insight provided by the CANalyzer: when you changed the channel configuration from Intel to Motorola and back again, it automatically changed the location of the start bit. A 32-bit channel that starts at bit 8 for Intel (little endian) format becomes a 32-bit channel that starts at bit 32 for Motorola. I edited my channel configuration spreadsheet accordingly, and suddenly, magically, LabVIEW knew what to do. No channel configuration errors, and the data came through correctly. WTF? We scratched our heads for a minute, and the lights came on in our collective brains. The start of a CAN channel appeared to be specified by the least-significant bit of the least-significant byte. For a little-endian message beginning at bit 8 and spanning 32 bits, it's WYSIWYG. But a big-endian Float32 has its words, and the bytes within those words, swapped. So for a 32-bit message that resides from bit 8 to bit 40, the message "starts" at bit 32. It all makes perfect sense, in a totally frustrating and absolutely retarded way. There are two really amazing things about this story. First, this bizarre idiosyncrasy was consistent across two completely separate and apparently unrelated software platforms: the LabVIEW CAN API, and a commercial CAN diagnostic tool. In other words, this isn't a bug, it's a feature, based upon a standard. Second, neither environment contained any hint of this requirement in its documentation. The moral of the story: if you're using CAN and dealing with Floats and big-endians, watch out. Reality is not what it may seem to be. You're welcome
    1 point
  3. My $0.02... FGs / AEs / LCODs have proven themseleves as excellent constructs for many years (config file library comes to mind). Yes, they can be abused (I can abuse anything). Yes, they can get out of hand with quick fixes (the quick fix is to blame not the AE construct). Just because we have another tool (e.g. LVOOP) in our bag doesn't mean we need to throw out the old ones... maybe we just need to protect them better as suggested above. BTW... aren't you the one who said "...[don't] throw the baby out with the bath water" awhile back? ~Dan
    1 point
  4. As always, there is a middle ground (IMHO): Create a lvlib, make the AE VI private and create public "Accessor" VIs for each of the actions. This has the advantage of keeping the "simple" AE paradigm whist restricting uses of the internal VIs. In addition, the accessor VIs can have the proper connections for the action involved (named, typed, and with appropriate required statuses), making them a little easier to use (and to avoid having to remember what inputs are needed for what actions). Note: I personally am not such a huge fan of action engines everywhere for the simple reason that they are global structures which means that you cannot easily modify your system to deal with a second "thing", and your "thing" can be used absolutely anywhere, not just in the part of your program that does use it.
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.