IEEE Floating Point ASCII

TPCTJ

Lifetime Supporting Member
Join Date
Jun 2012
Location
Minnesota
Posts
21
OK, so I have a ControlLogix L61 Processor and I am communicating with a Veeder-Root 350+. I have established the comm and am getting valid data. The problem I am having is the data I am receiving comes in as a string of 8 SINTs which when the “Style” of the data format for each SINT is changed to ASCII, is when I get the character I need. For example: From the first word to the last in DECIMAL – 52 , 49 , 70 , 70 , 68 , 49 , 54 , 48 these are 16 bit SINTs that translate in ASCII to – 4 , 1 , F , F , D , 1 , 6 , 0. Now, each one of these characters can be translated into 4 bit nibbles because in HEX they need only 4 bits…. With a piece of paper, I can take the 0100 0001 1111 1111 1101 0001 0110 0000 and make that the floating point number I need. It’s easier to see like this:

4 1 F F D 1 6 0
0100 0001 1111 1111 1101 0001 0110 0000

The formula to break this down is quite cumbersome and I am not sure if the PLC is up to the challenge. First, you take the very first bit, if it is 0 the number is positive 1 is negative. Then the next eight bits are called the exponent, subtract 127 from that number (131 in this case) and you take 2^(131-127) to get 16. The last 23 bits are called the mantissa. Take this number, 8,376,672 and divide it by 8,338,608 and add 1 to get 1.99857711. Multiply this by the 16 from earlier to get 31.98.

I am looking into some bit shifting and bit pulling instructions to maybe get what I need.

If you know of a better way to do this, I would greatly appreciate your help.
 
Let me see if I have this right...

1) You get 8 SINTS containing the ASCII representation of 32 bits of data in hex format. 8 chars 41FFD160.

2) You then convert each char to 4 bits of data. ASCII (hex) to integer. 0100 0001 1111 1111 1101 0001 0110 0000

So far, so good. The next step is where I think you are making it more complicated than it has to be. Try this...

3) Take the 8 nybbles of data from step 2 and copy them into a REAL data type bit for bit. You have all 32 bits of the floating point number, they just aren't in the right data type.

In step 2, when you convert each char to 4bits of data, you could use a BTD instruction to place each 4bit chunk into the correct order in a single 32-bit DINT. 0100 0001 1111 1111 1101 0001 0110 0000

Then simply COP the DINT to a REAL and you should get your floating point value without all the extra fuss.
 
Last edited:
1. For each received SINT:
  • Subtract 48
  • If the result is greater than 9 then subtract 7
2. This gets each SINT down to the 0-F range

3. Examine the leftmost (first received I guess) SINT only, if greater than 7 then set a 'negative flag' and subtract 8.

4. MOV the leftmost SINT referenced above into a DINT.

5. Do the following 7 times:
  • MUL the DINT by 16
  • Add in the next SINT
6. If the 'negative flag' is set then set the top bit (bit .31) of the DINT.

7. COPy the DINT into a REAL.
 
Mellis, this is what I was initially going to do but I found that the characters, F and D, do not have the right bit order to do that. For example, an ASCII 1 is 0011 0001. That would be OK to take the last 4 bits out. The F is 0100 0110 but if I want it to be four bits it needs to be 1111.
Am I overthinking this still? I am going to look into Bernie's suggestion too. It looks like that might be difficult though...
Thanks guys, I will keep ya updated.
 
Bernie,
I printed out your instructions and put it into my logic...I didn't get the expected result.
Maybe I am missing what you are calling a "Negative Flag"
I know that the number I am looking for will NEVER be negative. Of course, I hate to use NEVER, but I am monitoring a tank level in inches.
OH, I just saw that I forgot something in step 1...I only subtracted 48 from the first SINT....be back shortly...
 
You still have to convert the ASCII to 4bits of data for each character. That is step 2 in my post. I didn't elaborate on how to do that because you seemed to have a handle on that.

Bernie's technique (his step 1) will work fine.

An alternative method is to use 16 rungs with an EQU and MOV on each.
Basically a table lookup..
If ASCII code is 48, then result is 0
If ASCII code is 49, then result is 1
If ASCII code is 50, then result is 2
If ASCII code is 51, then result is 3
If ASCII code is 52, then result is 4
If ASCII code is 53, then result is 5
If ASCII code is 54, then result is 6
If ASCII code is 55, then result is 7
If ASCII code is 56, then result is 8
If ASCII code is 57, then result is 9
If ASCII code is 65, then result is 10
If ASCII code is 66, then result is 11
If ASCII code is 67, then result is 12
If ASCII code is 68, then result is 13
If ASCII code is 69, then result is 14
If ASCII code is 70, then result is 15

Since there are only 16 things to lookup, I'd probably do it this way.

Either way you go, a nice rung comment explaining what is going on is required.
 
If the result will NEVER be negative then you can eliminate my steps 3 and 6. And, as I mentioned, the BTD method won't care if it's negative or not.

Come to think of it, couldn't the BTDs be done into a REAL eliminating the final DINT -> REAL COPy?
Edit - apparently not, preparing an AOI
 
Last edited:
:pBIRNIE!!!,,,,MELLIS!!!!,
I GOT IT!!! I seen that I also missed the parts of step one AGAIN. I forgot to compare the result of subtracting 48 to 9 and if greater subtract another 7 to ALL of the SINTs.

Once I did that for the F and D characters......WHALA! I have the EXACT number I need.

Man, thank you BOTH for your help this morning. I really do APPRECIATE it. I have been trying to get this figured out for a while now.

I hope you two have a great rest of the week and a WONDERFUL Labor Day Weekend!

Sincerely,
T.J.:site:
 
Bernie,
I looked at your website...are you former Navy? I was an AT2, not retired but got honorably discharged in '07.
Anywho, I imported that AOI because 1. it is much cleaner than the logic I made. 2. I have multiple tanks to do this logic with and I think this is going to be a quicker way to get that done.

I don't know how how to execute this AOI with the tags and such. Do I have to move the data I want (GSC.Data.Port1.ReadString[X]) into the SINT_ARRAY[X]?
I'm thinking I might have to have a separate AOI for each tank, is that correct?

Please forgive me for not being as fluent with the RS5K instructions.

Thank you,

T.J.
 
Once you import the AOI then you can, at each appropriate point create one copy of it. You will give it a name, after ASCII_SINT_TO_REAL, to represent this particular instance, like 'Tank_1_STR'. Then do a 'new' to actually create the instance. Fill in the tag name of the 8 position SINT array which holds the ASCII data. You can create a new one right here if it doesn't already exist. Finally (in the new version I mention below) you fill in the tag of the target REAL (or create it.)

The logic will turn on this instruction whenever you want a conversion (or constantly if you want).


By the way, I changed the AOI to provide the space to fill in the REAL output tag you are sending the result to.

(Former Air Force by the way, taught Electronics for 4 years at Lowry Air Force Base just outside of Denver)
 
Last edited:
To give a little more information, the SINT arrays wil exist outside of the AOI as will the REAL result. The AOI has a couple internal variables (a SINT and a DINT) but you don't have to worry about those, they are created as the instance of the AOI is created.

If you aren't certain about AOIs they are like any instruction which was provided with the software. They are also like the definitions of data types. For example, a DINT is defined as a 32 bit number but one doesn't EXIST until you create a tag of that type. The AOI is defined but doesn't actually exist until you place one and give it a unique name (using the 'new'). The AOI you place in the logic and give a name is an 'instance' of the defined AOI. And you can create as many as you need.
 
Got it. Thanks again.
Only thing is...I already have all of the old versions of the AOI in my logic...Do you know if it would work to import the new version and drag it on top of what I have in place? Looks like the name is the same so I wonder if I just overwrote the existing AOI would it replace the logic instructions with the new version and leave the tagnames alone?

After I asked about the Navy thing I saw your profile and read you are former Air Force. Although we like to go back and forth about who's better (at least I like to joke with my flyboy buddies).....I do most of my work on Air Force fueling systems and know a lot of Air Force GIs. I know better now when I say "Chair Force" lol. :ROFLMAO:

Take care my friend. You have been an unbelievable help to me today!
 

Similar Topics

does anyone have an example on how to convert a double precision (64bit) floating point number to single precision in a SLC500. i am polling an...
Replies
3
Views
7,696
I am transferring data ASCII Modbus though an Allen Bradley Point I/O Rs232 module. I can query the data and load my data tables with the...
Replies
6
Views
6,593
Looking for some explanation/history between North American electrical symbols standards (how they relate, what are the latest, what is the...
Replies
3
Views
1,701
Hello! Long time lurker and gatherer of information - love this forum. I am trying to find some sort of tag naming standard if it exists...
Replies
18
Views
8,406
Back
Top Bottom