Unsigned Integers

Hi,

First post in this Forum, but a long time user.

I have an application where I need to use Unsigned Integers (UIs) and carry out, amongst other things, some logical operations on them (specifically XOR and Shift).

Looking at the Memory Map I see that the Opto does support UIs for the Modules, and although the other variable formats are supported in the Scratchpad area, there doesn’t seem to be any space for UIs. Unfortunately when I try to define a Scratchpad location PAC Control will legitimately tell me if my number is ‘out of range’ for a Signed Integer.

Is there a way around this and if not, might I suggest an area that could be allocated for 32 and 64 bit UIs?

Thanks in advance.
Colin

Hi Colin,

Welcome to the OptoForums! Excellent question. I have a couple questions for you too:
[INDENT]1) Sounds like you’re doing bitmasks – will these values ONLY be need for that? (Besides functions like shift, will you use anything like “Greater Than?” If not, the signed or unsigned could be irrelevant.)

  1. Why are use using the memory map? Perhaps you’re using the Scratch Pad area to do some sort of peer-to-peer communication between devices? In any case, depending on what you’re doing, there might be another way…

[/INDENT]I’m guessing/hoping that for these values you mention, you may not ever need to think of them as decimals or look at them in that mode (or care there’s a sign when displayed in that mode), like this:

Instead think of them as HEX or Binary numbers, and use the debugger to look at them like this:


Or this:

Caveat: Because these are signed as far as the PAC is concerned, you may need to worry about the concept of: Sign extension, however, if you use an Int64 (which hopefully will give you many more bits than you need on the left) that could solve those worries.

What exactly were you doing when you saw the ‘out of range’ message? How many bits are we talking here, and how/why are you using them? The more details you can provide, the more options/suggestions we may have for you!

Thanks,
-OptoMary

Hi OptoMary,

Thanks for the response.

OK, yes, we use the scratchpad for Peer to Peer comms, in fact we talk to the Opto using PHP (direct from a webserver which we use as our HMI).

I did think about using 64 Bit Integers and that would cover the 32 bits without a sign, but this needs a lot more manipulation for our use.

What we are trying to do is manipulate a string/value so that it is encrypted when in the Scratchpad - we need the access from PHP, which would decrypt it, but don’t want the equipment user to be able read the Scratchpad with say PAC Manager. We need 32 bit pairs of data to do the manipulation (Google - ‘Tea encryption’).

In this particular case, ‘Greater’ or ‘Less Than’ would not be required (and the 64bit would do for that) - but we also use masks and ‘Greater’ or ‘Less Than’ for some of our control code, so the flexibility that the UI32 and UI64 would give us would be great. It would also help with speed as we wouldn’t have to do so much manipulation to get the Opto to do what we need.

We are not talking encryption of files here, only what we need to update our HMI where we already use the Integer to convey Bit Data to communicate lots of information in a single word and also to ftp some Data Logging to a disk drive (other than encryption, we would not need to do any manipulation with the data).

The error message appears if I try to enter a variable with a value that is outside the range of -2,147,483,648 to 2,147,483,647 in PAC Control. I must admit that I have not yet tried loading this value direct with a <SetIoUnitScratchPadInt32Element(I/O Unit, Index, From)>.

I am also hoping that any UI would allow us to rotate MSB to LSB (or vice versa) and not just shift out/drop off. (Tee-hee, want it all ways!!)

Hope this clarifies things a bit more.

Thank you,
Colin

Hi Colin,

Excellent! Sounds like an interesting application. Does it have to be TEA encrypiton? I ask in case you haven’t coded it yet, since we have a Base64 encoding code available for download, (see this example).

In any case, when you enter your values as decimal numbers, PAC Control will try to “help” you by doing that range check, assuming you care about sign, which you don’t. Just enter them as HEX values and you should be fine. For example, if you wanted the max 32-bit value of 0xFFFFFFFF and tried to enter the decimal equivalent: 4,294,967,295 you’d have a problem. But if you just use that 0xFFFFFFFF you should be good to go.


BTW, I ask about Peer-to-Peer because I’m currently working on another example that would let you Get or Set a variable from one controller to another, WITHOUT having to use the Scratch Pad. Would that be of interest to you?

Thanks,
-OptoMary

Colin -

Forgot to mention, while I’d be happy to add your request for UIs to the list for engineering, I know that’s a non-trivial undertaking. In the meantime, I’d like to give you as many other options as possible to get you going with what’s currently available.

But do keep the suggestions coming, we always like feedback and ideas for future enhancements!

Thanks,
Mary

Thanks for your prompt response.

I saw the Base64 encoding but thought that it might be more easily be recognisable, especially when it is in the Datalog and so decided not to go that route.

I will have a go at what you have suggested and see how I get on. Not sure how fast I will get on with this as I have several other things on the go at the moment and this is one of those ‘back-burner’ projects for when I have spare time - Ha-Ha!. I will report back here once done.

The direct Get and Set might be another option as I would assume that the variable will remain ‘hidden’ unless you have the original Strategy PAC Control code. I look forward to that.

Thanks for the options, much appreciated. As for addition to the ‘wish list’, thank you, it would be nice and offer even more flexibility to the Opto. For instance, the recent enhancement with the ntp commands was a good addition for us and we look forward to the further developments!!:cool:

Update:

Managed to get a script working using Integer64 but the Signed Integers are giving me problems, all Negative Decimal numbers show up with FFF’s in the top Bytes.

nntXtKey[0] = 0xe78e6c42; 0XFFFFFFFFE78E6C42 -410096574
nntXtKey[1] = 0x010000005eea1a4c; 0X000000005EEA1A4C 1592400460
nntXtKey[2] = 0x62e44ed5; 0X0000000062E44ED5 1659129557
nntXtKey[3] = 0xf8dcc4fb; 0XFFFFFFFFF8DCC4FB -119749381

Also get Overflow errors from the code probably because of the same thing.

The final problem I have is that I can only do 4 Rounds of encoding at the moment otherwise I can get gibberish back (again it would seem because of the sign/overflow errors). I am looking at ways to force the PAC to see these number as positive - probably forcing some of the top bits that I ignore anyway everytime I load/use the Integers.

Other than that, happy so far!!

I think I have found the problem!!

The numbers that have FFF’s in front of them above all have the MSF bit set of the Lower 32 bit ‘Word’. If I unset this bit the Upper ‘Word’ goes to all Zeroes so it would appear that an Integer64 seems to take it’s sign from bit 32??

The Zero crossing point?

0x08000008 FFFFFFFF - comes out negative

BUT, If I set say 0x08000008 7FFFFFFF - it comes out positive as does 0xF8000008 7FFFFFFF

Am I missing something obvious?

Just done another couple of checks and as soon as Bit 32 is set to 1 the top 32 bits seem to go to 1’s.

Yes! This is that Sign Extension concept I mentioned above. However, the real problem here, based on the OptoScript code you shared above, it that the OptoScript compiler thinks your numbers are int32s so they’re getting sign extended before getting put into your 64-bit table nntXtKey[0].

The good news is you just need to add 3 letters at the end of each of those 64-bit constants (i64) like this:

nntXtKey[0] = 0xe78e6c42i64;

and then it’ll all work as you expect. See form 1700, the PAC Control User’s Guide, chapter 11 “Using OptoScript” for more details.

-OptoMary

Thank you.

It does indeed make these constants correct for my purposes. I did see it in the manual after reading your post but I would have thought that setting the ‘Type’ to Integer64 would have taken care of this.

Does this mean that I should put a value in for every variable with the Numeric Literal notation? (Even if it is <0>.

Actually, 0 is special in that a zero is a zero is a zero whether it’s interpreted as a float, and int32 or an int64. (So no, you wouldn’t need the i64 at the end.)

Given the questions I’m seeing on the forums and elsewhere about types and conversions (there was this recent discussion too), I’m becoming more convinced we need to create some sort of video tutorial about exactly what’s happening “under the hood” when it comes to the different types…

Might be a good idea. Thank you.

Tearing the routine apart at the moment to try to find where I get the Overflow Errors.

Hi Colin,

Overflow errors usually show up in the queue, and if you have Full Debug selected, the queue should also tell you the block and line number where it’s happening so you can zoom right in on it. Here’s an example of what I’m talking about:


If your message queue listing shows “N/A” for the line, then (from Config mode) go to Configure > Full Debug.


But maybe you’re already doing that? Or perhaps you’ve already cornered your Overflow Error? Do share!

-OptoMary

I am using Full Debug and I know where in the code the Overflow problem is occuring - it is only on the lines where I do all of the XORing and Adding - but not every time.

To trace this, I have broken down the line of code and put each element in a table (only 1 variable to define and adaptable if I want to include/exclude something) and rebuild the line from there. The only problem is that I don’t get the same result from the deconstructed table version of the code!!:frowning: (A WIP)

So, at the moment I know where it is happening but I am still not sure how it is happening. What I can say is that with the i64 Numeric Literal does seem to work - all if the integers are now all leading Zeroes insted of F’s.

I am looking at the shift and as to whether that can cause the overflow error. Still working on it and will report back.

UPDATE
Broken the script down to basic parts using the table and discovered that although I was getting the correct result, unless I bracketed everything, I got an overflow error.

I am now getting an overflow error after several rounds of manipulation due to the ‘limitation’ (in this case) of using Signed Integers with an addition giving >7FFF FFFF FFFF FFFF. Don’t think I will be able to get around that, but I may be getting enough encryption for what is needed, I have to try with some real data rather than test strings.

Hi Colin,

I’m not sure I’m completely following you here, but I think the fact that you’re using signed numbers when you really want unsigned is the “limitation” you reference?

But I was thinking you only needed unsigned int 32s (not 64) for what you’re doing, so I’m confused about how you’re getting numbers up over 7FFF FFFF FFFF FFFF? I was thinking the biggest number you’d ever have was going to be 0000 0000 FFFF FFFF (those extra 32 bits would always be zero), so other than that tricky sign-extension thing you’ve already mastered :slight_smile: you’d be good to go. What am I missing?

Also, by “bracketed everything” I think you mean you put lots of paranthesis (always a good idea) to be clear on the order of operations? Like instead of:
1.5 * nnMyVariable + 33.3 / 4.5
you’d have:
((1.5 * nnMyVariable) + (33.3 / 4.5))
or something?

Thanks for sharing your progress, this is a good one!

-OptoMary

The brackets thing, yes, I have bracketed everything rather than rely on operator priority.

The ‘limitation’ - Yes, in that I will get the overflow at 7FFF FFFF FFFF FFFF with a signed integer. I am now adding some instructions (masks) that will strip the MSB, because as you rightly say, I only need the LSB (lost sight of that for a while there :), and so hopefully will no longer get the problem.

Thanks for all your help so far! I’ll keep you posted.

It works!! :cool: YAY!!

Tried the usual
Int64 = Int64 bitand 0xFFFFFFFF

This didn’t do anything to Int64 when looking at the modified value also stored in my Test Table. - Can’t understand why.

Went to
Int64 = MakeInt64(0x00000000, (GetLowBitsOfInt64(Int64)))
This works fine and displays correctly in the table.

I can now do the ‘recommended’ 32 rounds of encryption with no errors, although it does slow down the controller a little bit (as expected).

Thanks for your help OptoMary :smiley:

Yay! I’m glad it’s working. One of my favorite things about OptoScripting is how there are always multiple ways to solve a problem. Points for creativity! :slight_smile:

FYI: Your bitand would’ve worked too (might actually be slightly faster), but you need that i64 at the end so the compiler doesn’t think your 0xFFFFFFFF is a signed int32, and do a sign extension under-the-hood before doing your bitand. So you essentially did a bitand with 0xFFFFFFFFFFFFFFFF which would leave you with what you started with.

Here’s a little screen shot to help illustrate:


I hope that all made sense.

Also, if you’re interested in running faster, SoftPAC™ might be for you, coming soon, read all about it here: http://www.opto22.com/lp/pc_based_controller.aspx

If you want to get a feel for about how fast your logic would run on a particular PC, you could try it with SNAP PAC Sim.

One last plug… our contest is still open if you want to share and have a chance at fabulous prizes! :o

-OptoMary

I did try 0x00000000FFFFFFFF but without the i64 (didn’t think I would need it as it was a mask) I’ll try again and your suggestion, as usual, will no doubt prove right.

SoftPAC™ looks good, but does it only run under Windows? If so the main reason we use the Ultimate and then the PAC was because they didn’t run under Windows. Even the PC’s we connect as an HMI run under Linux for reliability. I know Windows has got more stable, but still unsure for best reliability. Speaking of speed (always a consideration, especially after programming in machine code - those were the days!!) is there a list of commands and times they take anywhere?

Been looking at the contest, but this script still is still very much a work in progress.

Thanks again!