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
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
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
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?
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=âhttp://www.opto22.com/community/showthread.php?t=1372&p=4456â]
http://www.opto22.com/community/showthread.php?t=1372&p=4456
Thanks, philip, for sharing your excellent example/sub!
And yes, thatâs what I meant. The part of whatâs needed for such a feature was built into the firmware only 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:
I had a customer that wanted Exponents values to show on display when below zero
I created code below and it works in groov to display the Exponent Value but will only execute if value changes
I commented the code
Enjoy
if (floatx <0 ) then // show exponent only if less than Zero
if (floatLast <> Floatx) then // do the conversion if the value has changed
floatlast = floatx;
FloatToString(floatx, 12, 9, exp); // make a 12 char string with 9 decimal places
//first character [0] will be negative sign "-" ascii 45
//next character [1] will be zero ascii 48
//next character [2] will be decimal point "." ascii 46
//next character [3] may be a leading zero or ascii 48 start looking in 3
expVal = 1; //set start of exponent count
CNT = 3; // set Counter to start Looking
NonZero = 0; // flag for non zero char found
While (nonzero == 0 or CNT > 11)
asciiVal = GetNthCharacter(exp, CNT); // get next char
if (asciiVal == 48) then // first val is 0
incrementvariable(ExpVal);
incrementvariable(CNT); // chk for next
else
NonZero = 1; // when first non zero found set flag
GetSubstring (exp, CNT, CNT + 1, FirstNon0); //get the first Whole exponent value
endif
wend
//non zero found
asciiVal = GetNthCharacter(exp, 11);
if (asciiVal == 48) then // if last value is 0 then Ignore
remVal = 11 - 1; //reduce the remainder of characters by 1
endif
asciiVal = GetNthCharacter(exp, 10);
if (asciiVal == 48) then // if second last value is 0 then Ignore
remVal = Remval - 1; // reduce remainder value by 1
endif
remainderChar = RemVal - CNT; // calculate the remainder of string characters
GetSubstring (exp, CNT +1, remainderChar, FirstE); // get the exponent value after decimal
NumberToString(expVal, ExpValS); //create the exponent string
FirstE = "-" + FirstNon0 + "." + FirstE + "e" + expVals; //format the string
DegK = Floatx + KelvinConvert;
endif
endif