Jump to content

How to get strings from a ring w/o UI thread swap?


Stobber

Recommended Posts

Hi all -

I'm drafting up a simple LV API for a serial-based pressure transducer. The driver interface lets me select the baud rate for communication from a list of values, and the value that I send to the transducer is an index into this list. (e.g. if I want to communicate at 9600 bps, I send the sensor '2', which corresponds to the rate of 9600. If I want 19200 bps, I send '3'.) After sending the desired rate to the device, I have to reconfigure my serial port before talking to it again. Unfortunately, I need the rate for the serial port configuration, not the index corresponding to that rate in the driver API.

To solve this problem, I did the usual maneuver of creating a ring typedef for the selectable rates in the driver, then grabbing the string off the typedef and converting it back to a number to be used as an argument to the Configure Serial Port VI. I don't like this on principle, because it depends on the format of the typedef strings never changing in the future -- if they stop being legally formatted decimal numbers, this code will break -- but it worked for my proof-of-concept. Here's the VI:

post-17939-0-29083100-1327255169_thumb.p

The string formatting dependency notwithstanding, this is also a bad idea for a hardware driver API because calling into the property node forces a thread swap to the UI execution system. This isn't a high-performance driver, but I still don't like the idea of waiting in the UI threadpool to execute a hardware call.

What's a better approach to this problem? The ring seems like it's definitely the right choice for the API interface, but I need its strings as numeric values alongside the list indices that are sent off to the device. I considered creating a second typedef that holds numeric values of both things in a lookup table, but then I'd have two diagram constants (or a typedef and a lookup VI) that would have to be kept in sync every time the software is updated. I'd prefer to encapsulate all this information in a single diagram element. An X-Control seems like overkill here, though.

Ideas?

Link to comment

Well. I think you are over-thinking it a bit. However. If you use a ring instead of an enum, you can assign abitrary numeric values to your strings (the baud rates) since a rings values doesn't have to be contiguous. You can then wire it straight into your "Config Serial Port" VI.

Edited by ShaunR
Link to comment

Well. In that case you have two options.

1. Use a look-up table (which you have already said you don't like)

2. Ascertain the baud characterisitc and calculate it.

Baud rate generators are a function of the processor clock. So if you find one here that closely matches your ring control, you should be able to work out a function for calculating it for that device [i.e that devices clock - most use 18.432 MHz if they have any sense, e.g. UBRR = (18432000 / (16 x Baud rate)) - 1].

Edited by ShaunR
Link to comment

I would just create a VI that returns the paired arrays of strings as a constant... use that all over the place, including to populate the ring in the one place that is actually a user interface.

> An X-Control seems like overkill here, though.

And an XControl is not a diagram element. I think that's pretty much the whole problem: you're using panel elements for diagram information.

Edited by Aristos Queue
Link to comment

I think that's pretty much the whole problem: you're using panel elements for diagram information.

In my defense, LV is structured in such a way that panel elements become diagram elements via the requirement that every subroutine have a panel. I want to design a good API that limits the potential for bad values passed in by the client, but I don't want to create a clunky coding scheme in order to do so. Using a ring is natural here.

I only verbalized the XControl possibility to hopefully spur conversation about alternative approaches.

I ended up just adding a utility VI to the API class that uses a case structure to translate ring values into the integer values that correspond with the ring strings. Future devs working on this class will have to know that it needs to be updated whenever the typedef is modified.

Link to comment

We recently discovered this VI among the utilities: vi.lib\Utility\VariantDataType\GetNumericInfo.vi that returns all the string values for an Enum. We have found it quite useful. (You can then index the array to get the specific string.) (I just tried it and it doesn't seem to work for a ring control. I always use Enums anyway.)

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

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