Numeric value formatting

Ok, I feel like this should be simple, but am not finding the solution. I have several numeric values that are greater than a thousand and I do not want a comma displayed in the value. Is it possible to control that in PAC Display? Thanks in advance :slight_smile:

Check under the menu Config for Runtime Options.
There is a check box there for ‘Format Value Data with Commas’.

For more information, check out page 287 in the PAC Display Users Guide Doc 1702 (click help in Config mode).

So all or nothing? No options at the field/value level? I think I have more fields that benefit from the comma than those that do not. I will review. Thanks Ben.

Yeah, all or nothing. The only thing you can change on a per value display is the number of decimals.

Perhaps you might like to manipulate the values in PACControl, using the instructions:

[B]FloatToString[/B](Convert, Length, Decimals, Put Result in)
[B]NumberToString[/B](Convert, Put Result in)

to move the numerical values into strings and then strip the offending commas and decimal points with some extra string handling commands such as.

[B]FindCharacterInString[/B](Find, Start at Index, Of String)
[B]SetNthCharacter[/B](To, In String, At Index)

Not the easiest way of handling this in the world, but a single subroutine would serve for all similar cases in the project.

If you update this routine as fast as you are reading the values, then no-one will know that the values have been converted into text fields.

I like it! That will totally work. Thank you :slight_smile:

Thanks, gmitchell, good points! There’s also the new-ish [B]TrimString[/B] command, which could be handy too.

On a related note, a customer just asked about formatting a float into scientific notation in PAC Display.

I told him about using [B]NumberToString[/B] in his logic, then displaying the resulting string, as we discussed above.

He specifically asked for the format 1.23E-08 but [B]NumberToString [/B]gives you: 1.234567e-08. (With a four more places after the decimal point, and a capital E – which might be okay, I’ve not yet heard back from him.)

In the meantime, for grins and giggles, I pondered how to adjust for that w/a couple of OptoScript lines ALMOST work perfectly:

NumberToString(fGauge, sGauge);

// drop the 4 extra characters and convert the lower-case e to upper case E
// "1.333000e+03"
GetSubstring(sGauge, 0, 4, sSignificand);
GetSubstring(sGauge, 9, 3, sExponent);

// put the piece together and replace that e with an E
sGaugeHMI = sSignificand + "E" + sExponent;

I say [I]almost [/I]because… and I could be thinking too hard about this but… do you see why it might work for 1.33E+03 but not 0.6666666 ?

That method effectively truncates at the least significant digit. Which might also be okay for him, given the specific numbers he sent me.

But just in case, I came up with a few more lines of OptoScript, but it’s getting kind of ugly. Wondering if anyone else out there in OptoLand as a more elegant way of formatting a float value to a specific number of significant digits in that significand/mantissa for scientific notation?

Here’s the longer version which does a Round at the 1/100ths place:

NumberToString(fGauge, sGauge);

// That gives us a string in this format: "1.333000e+03" 
// but we only want 2 sig digits, so let's convert the e to a space so we use the StringToFloat and Round comamnds
sGauge[8] = ' '; // SetNthCharacter works too

fGaugeX100 = StringToFloat(sGauge) * 100; // now we should have a value like 133.3
fGaugeX100 = Round( fGaugeX100 );

NumberToString(fGaugeX100, sGaugeX100); 

// drop the 4 extra characters and convert the lower-case e to upper case E
// "1.333000e+03"
GetSubstring(sGaugeX100, 0, 4, sSignificand);
GetSubstring(sGauge, 9, 3, sExponent);

// put the piece together and replace that e with an E
sGaugeHMI = sSignificand + "E" + sExponent;

Clear as mud? Other ideas/suggestions?

Would suggesting Opto22 makes a printf like command with full format specifiers be out of the question? :slight_smile:

Nope, good idea! That thought had occurred to me too, especially since you know there’s a printf under the hood there if you go deep enough…

Anyway, I will add a “feature request” ticket!

Is there really a printf() like function built-in / hidden in Control’s script editor…?

I think she meant that the PACs “OS” has a printf library function available to it, it just isn’t exposed to any Optoscript command. Is the OS written in C? Where does Forth come in?

I worked on a little subroutine for this the past few nights - put it in the Code Samples section.[URL=“”]

Thanks, philip, for sharing your excellent example/sub!

And yes, that’s what I meant. The [I]part [/I]of what’s needed for such a feature was built into the [I]firmware only[/I] at the same time as we added the new-ish “Trim” PAC Control command. The missing PAC Control piece is on the wish list but that’s a long list.

The firmware itself is written in mostly C/C++ (some of it by me, even!) and a big chunk of that (what we call the “control engine”, vs. the MMP part) is essentially a Forth interpreter. So when you compile your Strategy, PAC Control creates Forth code which gets downloaded interpreted by that control engine. Usually the Forth is not something users would have to worry about since the idea of our flowchart-based approach is you don’t have to be a programmer and worry about all that icky syntax and what-not!

Since you’ve already asked about how the watch works, and I can tell you WAY more than you need/want to know… some OptoFans may end up touching the Forth stuff a little if:

  1. you use the “initialize on download” option for variables; you’ll see a tiny bit of Forth in the PAC User’s guide, under “Setting Initial Values”
  2. you use this [B][U]peer-to-peer[/U][/B] example, where I include some subroutines that talk directly to that Forth interpreter. But that’s like “void the warranty” stuff that can really cause trouble so we don’t normally recommend…