Skip to content

Posts from the ‘Useful Tools’ Category

Let’s Talk About LabVIEW Units, Part 2

In Part 1, I talked about important things to know about LabVIEW Units. In this part, I will focus more on a few use cases where I find them valuable.

Depth of Field with LabVIEW Units

When I was first learning how to use LabVIEW Units, I wrote a photography “depth of field calculator” using LabVIEW Units. As many of my readers know, I’m an avid photographer. Check out bhpowell.com! In photography, the “depth of field” is a measure of how much of an image is in focus.

There are four variables that go into calculating depth of field.

  1. Lens focal length — this is almost always represented in millimeters, such as a 50mm lens.
  2. Aperture — a unitless measure of how big the lens opening is. It’s like our own eye’s iris, which closes down in bright light, and opens up in low light. Because of the way light travels through the lens, a narrower opening gives greater depth of field. Aperture is also called the “F Stop”, and the bigger the number, the smaller the opening. As we’ll see, it’s also a square relationship (based on area), so an f/4 opening lets in twice as much light as f/5.6, and four times as much as f/8.
  3. Focus distance — the further away your subject is, the more distance front to back is in focus. The depth of field is relative to this focus point, so with an extreme closeup, you may only have a few millimeters front to back in focus. Distance is measured in whatever is natural for the country we each live in. Feet in the USA, meters almost everywhere else.
  4. Circle of confusion — this interesting sounding term is a measure of how precise you want to be when you say something is “in focus”. Exact focus is an infinitely tiny point, so the “circle of confusion” is a measure of how much area of the sensor is considered to be the same point. It’s usually measured in fractions of a millimeter, and is usually related to the sensor or film size of the camera.

There’s an example that ships with LabVIEW that demonstrates this simple calculation. It produces three results:

Depth of Field front panel
Block diagram of the LabVIEW example

The near and far distance are the front and back distances considered in focus, so everything from 5 to 7.5 meters is in focus when I have a 50mm lens at f/2.8 focused at 6 meters. The example also lets me replace “m” with “ft” and the code stays the same:

Same example with “feet”

The hyperfocal distance is an intermediate computation, and basically answers the question, “at what distance do I need to focus if I want the far horizon to be in focus?” If I were to run the calculation with focus set to 29.8 meters, for example:

The far distance is computed as almost 75 kilometers away, which is effectively infinite. Oh, as an aside, if you use the “SI” numeric display format, it plays nicely with units.

In the example above, instead of showing “74.50k”, it moved the “k” to the unit and automatically became “74.50 km”.

This example lends itself to LabVIEW Units because the computation is a mix of lengths represented with different units–millimeters and meters or millimeters and feet. Having LabVIEW Units as part of the data type provides some guardrails for my programming. If I try to add or subtract aperture from length, the wires will break, letting me know I’ve done something wrong. If, after all my multiplies and divides, I don’t end up with length as a result, I know I’ve left out part of the computation.


Representing duration with LabVIEW Units

Here’s another simple example of where units are useful.

I have one application that acquires data at about 1 Hz, with a front panel graph that can display the last hour, last day, or last week of data. Originally, I encoded the duration as constant containing a number of seconds:

  • 3600 (one hour)
  • 86,400 (one day)
  • 604,800 (one week)

I added a comment next to each to explain what the values mean.

Then it occurred to me that I could put a unit on that value, and instead use:

  • 1h
  • 1d
  • 7d

This is more descriptive, but also more likely to be correct. (If I mistyped “604800” as “608400”, would I immediately recognize that I did it wrong?).


Converting complex formulas with LabVIEW Units

My third example is a customer application that is computing the time a vehicle will reach a particular travel point, based on the vehicle’s velocity and the distance between sensors monitoring its progress. As an added bonus, the system was designed with the metric system in mind (km/h for speed), but the distance displays are both metric (meters) and imperial (feet and inches).

Originally, the operator had to use a spreadsheet with undocumented formulas of velocity and distance, and then paste them into a LabVIEW front panel. The LabVIEW application then took those numbers to program counter/timer hardware.

I replaced the spreadsheet with a LabVIEW VI and used Units. Again, using Units provided guardrails as I translated the algorithm into LabVIEW. As an example, here’s one of the Excel formulas I needed to make sense of:

=((A$25-K$12)*40-(279-H$30))/10+K$15

Based on other documentation, I began to deduce that these specific Excel cell values represented time. From there, I could conjecture that “279” was also time (e.g., milliseconds), and I also conjectured that “40” and “10” were in kHz. (Or was 10 in micro- or nanoseconds? Or in ticks of an 80MHz clock?)

By assigning units to my LabVIEW translation, I’d get a broken wire whenever I didn’t have a unit right. Using units gave me confidence that I understood my code and could document it when I got done. I even went so far as to replace a formula node (a builtin feature that doesn’t work with Units) with add, subtract, and divide primitives (which do work with Units). I kept the formula as a comment, since its algebraic nature is easier to understand at a glance.


Key takeaways

When you next write a LabVIEW application that represents a physical unit, I recommend that you give units a try. A fair warning that there’s a bit of a slippery slope to using units. If you add units to one control, there’s a good chance that you’ll want to follow that wire and add units to subVIs and other controls and indicators, and you’ll soon find yourself committed to using units in the application. It’s a good feeling, though, when you’re done.

The other piece of advice, which I mentioned in the previous post, is to not force units into reuse libraries. Sure, use units in a reusable VI if it’s always working with length or another physical unit, but sometimes it’s easier to not have units (even polymorphic ones), and let the user use Convert Unit outside of your reuse library. In other words, it’s okay to define boundaries between components where you will add or remove units.

My point of writing these two blog posts is to encourage you to use Units where they work well, and discourage you from using them where they don’t. I could go on about ways I wished they worked better, but I still think they’re a great feature worthy of more attention.

Let’s Talk About LabVIEW Units, Part 1

First, let’s start with a poll…

What do you think of LabVIEW Units?

View Results

Loading ... Loading ...

I’m a fan of Units in LabVIEW, but I totally understand that I’m in the minority. I’m writing this blog post to perhaps persuade at least a few of you to give them a try.

What are they?

A “Unit” in LabVIEW is a label you can add to floating point numbers to tell it what physical quantity the number represents.

Show the unit label

For example, I can assign the unit “degC” to a front panel control, to denote that the value is Degrees Celsius. Similarly, “degF” is Degrees Fahrenheit. If I wire a control representing degC to an indicator representing degF, when the VI runs, it automatically converts the value for me. I don’t have to remember F = C * 9 / 5 + 32.

Temperature conversion

LabVIEW knows about lots of physical units, using the International System of Units (SI). It also knows about prefixes like “milli”, “centi”, “kilo”, etc. If you’d like to explore them, you can right click on a unit label, and select “Build Unit String”.

Help building unit strings

This brings up a dialog to help you create a valid unit string.

Build Unit String Dialog

Note that you can do arithmetic on units. For example, I can represent velocity as “m/s” (meters per second), or “mi/h” (miles per hour), or “cm/ms” (centimeters per millisecond).

Convert meters/second to miles/hour.

Similarly, I could have exponents on units, such as m/s^2 to represent acceleration in meters per seconds squared.

In the example above, I hardcoded the unit as m/s, but I could also have taken a control of unit “meters” and divided it by a control of unit “seconds”, and produced a result that was velocity:

Unit arithmetic

Many of the builtin LabVIEW functions understand units. The unit is part of the LabVIEW data type, which also means that LabVIEW will make sure that any arithmetic you do on units is valid. For example, I can’t add meters and seconds, because they are different base SI units (length vs. time).

Note that you can change the units on the front panel while a VI is running, as long as you enter a compatible unit. For example, in the VI above, I could change “m/s” to any velocity unit (such as “km/d” for kilometers per day) at runtime. Because the unit is part of the data type, you can’t change to an incompatible unit (e.g., change velocity to length) unless the VI is editable.

We’ve seen one rough edge to units so far: almost nobody writes “miles per hour” as “mi/h”. It’s more accepted in the USA to write “mph”. Or what if I wanted to be more verbose, and say “miles/hour”? Well, too bad. The LabVIEW Unit system doesn’t support that. There’s a long list of feature requests for making LabVIEW Units better and more customizable.

By the way, most of the decision makers about NXG saw no value in LabVIEW Units (because they didn’t use LabVIEW for much real-world work), so I think the plan was that NXG would never support Units. That made me sad. But fortunately, that resolved itself when NXG was retired.

How do Units work?

Under the hood, the system uses the base SI units. There are seven base SI units:

Read more

MQTT in LabVIEW

I’ve been experimenting lately with MQTT in LabVIEW. MQTT is an open standard for message-based communications using a publisher/subscriber paradigm. It’s commonly used in the Internet of Things (IoT) world.

I’m working on updating an old LabVIEW application that makes heavy use of DataSocket, an NI-proprietary data communications mechanism. DataSocket has been deprecated, so my customer was interested in updating the communications scheme.

My friend Jörg Hampel of Hampel Software Engineering recommended I look into François Normandin’s LabVIEW Open Source MQTT client and broker. I started by watching François’ YouTube video, which gives a good introduction:

In parallel, I downloaded and installed the software with VIPM so I could follow along with the video. (Just search for MQTT in VIPM.)

Read more

Best Practices for Using LabVIEW with LXI

I’ve been designing a test system for a customer, and it’s going to be a mix of PXI and LXI instrumentation. Most NI customers understand PXI, but aren’t very familiar with LXI, which is the standard for Ethernet-based instrumentation. Up until about five years ago, I was a member of the LXI Consortium, and closely followed all of its technical developments. For my new project, I’ve been searching the internet so I can catch up and learn about the latest with LXI. While doing so, I realize there’s not a lot out there that discusses how to get started with LXI and LabVIEW (and NI MAX and NI VISA).

Around the same time, a customer asked me to teach the National Instruments “LabVIEW Instrument Control” course, which hasn’t been updated in about ten years. It also doesn’t cover much in the way of Ethernet or USB instrumentation.

So, I felt like I should do something about this dearth of content. I thought a video or two might be the best way to explain how to get started. I asked my friends at the LXI Consortium if anyone could loan me an LXI device, and Keithley Instruments graciously sent me a very nice DMM.

With that DMM on my bench, I created a couple of short videos (attached below). Part one is a good starting point if you’ve never used LXI with LabVIEW before. Part two begins to cover some of the issues if you want to use LXI in a production environment where the system needs to be more robust and maintainable.

For those wanting to learn even more, I’m developing additional custom training to help people who are building LabVIEW-based test systems that include more modern buses like USB and Ethernet. Contact us if you are interested in this custom training.

I’d love to hear your feedback on these videos. Please comment below!

OAuth2 and LabVIEW — Part Four, Reusability

It’s only when you try to reuse your code that you really understand how reusable it is.

– Mr. Obvious

After finishing part three of this series of posts on OAuth2, I went back to my original goal of writing code to interact with my Wireless Sensor Tags for measuring temperature and humidity. The further I went down that path, the more I wanted to change the existing example code.

Since this is a blog post that is partly about how the example evolved, I wanted to write a part four to describe my thought process. The code has been updated in the repository: https://gitlab.com/bhpowell/oauth2-labview-tutorial


Overall file organization

My first step in adding support for the Wireless Tag web service was to duplicate Main.vi. I called the new copy “Wireless Tag.vi”, and began changing out the endpoints, IDs, secrets, and such. To reduce confusion about two top-level VIs, I renamed Main.vi to “Example Get Google Photo.vi”. Not necessarily a great name, but more descriptive than “Main”.

As I began changing out “google.com” and “googleapis.com” endpoints for “my.wirelesstag.net” endpoints, I realized I’d saved several of the subVIs with default values for those endpoints. So, even though I found all of the URLs on the top-level diagram that needed to be updated, when I ran the VI, it was still access Google APIs because of the default values.

Here’s an example for the VI that exchanges the code for the token. First, the original way I used the subVI:

Read more

OAuth2 and LabVIEW — Part Three, Improving the Example

This is part three of a three four nine part blog post where I describe how to use OAuth2 with LabVIEW. See also:

In part one, we created a web service that the authentication process is going to use to call us back with an authentication code. In part two, we wrote code to go through the authentication process and call an example Google web service. Here in part three, we’re going to start writing some tests, replace the JSON parser, and think about what we else we could do to improve the example.


Improvements for Testing

I’m usually not a Test-Driven Development (TDD) kind of guy.  That’s where you write unit tests first, show that they fail, and then write the code that passes the tests.  I’ll sometimes use TDD when I clearly know what the right answer for a function ought to be.  For example, I once used TDD for figuring out a SQL query to a database—I could look at the database and deduce what I wanted the query to return, so I wrote a test for that.  Then I iterated until I got a SQL query that returned the right answer, and then iterated until it was efficient.

In our OAuth2 case, I decided from the start not to use TDD.  I wasn’t as confident that I knew the “right answer” to each step.  But I still kept testability in mind as I went along, and I wasn’t afraid to go back and write tests (and refactor for testability) after the first pass of the app was “done”.

It’s worth talking about the structure of the C# example that I started from.  It was badly structured for testability.  Here’s a high-level pseudo-code overview of this structure:

Read more

OAuth2 and LabVIEW — Part Two, The Authentication Process

This is part two of a three four nine part blog post where I describe how to use OAuth2 with LabVIEW. See also:

In part one, we created a web service that the authentication process uses to call us back with an authentication code. Here in part two, we’ll write code to actually go through the authentication process and call an example Google web service.


Calling the Authentication Server

Okay, with the callback ready, we can now call the authentication server and request a code.  Fortunately, Google has conveniently set up example servers and client codes to make testing with their endpoints easy.  That’s what we’ll use for this example.

We will call https://accounts.google.com/o/OAuth2/v2/auth as our authorization endpoint.  It takes several parameters that are part of the OAuth2 standard which we’ll pass with the URL:

  • response_type=”code”
  • scope=”openid profile”
  • redirect_uri=<our redirect endpoint>
  • client_id=<client id registered in advance>
  • state=<state>
  • code_challenge=<code challenge that’s part of the PKCE extension hashed with SHA256>
  • code_challenge_method=”S256″

The “redirect_uri” is what we created in part one of this blog post. The “client_id” for our example belongs to an “AppAuth Example” which Google created for testing. The “state” is a random string used to discriminate between calls. “code_challenge” and “code_challenge_method” are part of the PKCE extension.

We’re also going to need some helper VIs…

Read more

OAuth2 and LabVIEW — The Evolution of an Example

This is part one of a three four nine part blog post where I describe how to use OAuth2 (and PKCE) with LabVIEW. OAuth2 is used to authenticate with web services such as Google, Twitter, Facebook, and almost every major cloud-based service today.

See also:

Introduction

I own a slightly faulty beverage refrigerator. What makes it slightly faulty is that it sometimes wants to be a beverage freezer—it starts cooling, and doesn’t stop. It only does this rarely, and is otherwise a nice enough refrigerator that fits conveniently in a spot in our laundry room, so I’m hesitant to replace it. Instead, being the engineer I am, I decided to address the issue with more technology!

I purchased a Wireless Sensor Tag and a Wemo Mini Smart Plug to solve the problem.  The Wemo Wifi plug controls power to the refrigerator.  The Wireless Tag monitors temperature and humidity in the fridge. I use an IFTTT recipe to turn on the power when the temperature is too high, and turn off the power when the temperature is too low.  I ask it to keep the temperature within a four Fahrenheit degree temperature range.  On average, it is on for one hour, off for four hours, and then repeats.

It works surprisingly well. I set the Wireless Tag to send its data to the cloud every five minutes. I can view temperature and humidity graphs over the last several months and know it’s working. IFTTT is imperfect as a control system, but has worked out more reliably than expected. It’s only missed the too-high/too-low alarm twice in the few months since I’ve had this setup, and I work around this by having the alarm continue to trigger every fifteen minutes until the temperature is back in range.

All in, I’ve spent about $90 to avoid buying a new, inexpensive refrigerator—but it was way more fun to do it this way!

I can’t help but wonder about using LabVIEW to replace IFTTT as the controller, or to use LabVIEW to analyze my months of temperature and humidity data—and that’s where this journey begins…

Read more