Host Engineering Forum
General Category => Do-more CPUs and Do-more Designer Software => Topic started by: Friendlyperson on May 20, 2013, 06:58:07 PM
-
I need to choose a PLC that can do the following:
The PLC would send a SOH (which is a Ctr+A or ASCII 01) and i201 to the serial port
Then the connected device will respond with a string like this:
130430173001100000745FC000045FA780044F20000429053B43FF3B32C42927001423C866B&&EEB3
From the device's manual, this is the Format:
<SOH>i201TTYYMMDDHHmmTTpssssNNFFFFFFFF... TTpssssNNFFFFFFFF&&CCCC<ETX>
1. YYMMDDHHmm - Current Date and Time
2. TT - Tank Number (Decimal, 00=all)
3. p - Product Code (one ASCII character [20h-7Eh])
4. ssss - Tank Status Bits:
Bit 1 - (LSB) Delivery in Progress
Bit 2 - Leak Test in Progress
Bit 3 - Invalid Fuel Height Alarm (MAG Probes Only)
Bit 4-16 - Unused
5. NN - Number of eight character Data Fields to follow (Hex)
6. FFFFFFFF - ASCII Hex IEEE floats:
1. Volume
2. TC Volume
3. Ullage
4. Height
5. Water
6. Temperature
7. Water Volume
7. && - Data Termination Flag
8. CCCC - Message Checksum
I am looking to be able to extract the TC Volume value and have the PLC respond to changes by closing a contact. I understand that some PLCs can do anything that can be done with a spreadsheet program. However, I have not been able to figure out how to extract the value of the TC Volume using a spreadsheet.
Finding the HEX number for the TC Volume is the simple part (I hope). The hard part will be decoding the value of the TC Volume.
The manual for the device says:
6.3 ASCII FLOATING POINT FORMAT
6.3.1 NOTES
6.3.1.1 HHHHHHHH (H = 0-9 or A-F) indicates the 8 "nibble" ASCII-Hexadecimal representation
of a 4-Byte Floating Point number. Many data parameters are transmitted in this format.
6.3.1.2 The 32-bits are arranged as follows:
Byte1 = SEEE EEEE
Byte2 = EMMM MMMM
Byte3 = MMMM MMMM
Byte4 = MMMM MMMM
Nibbles are the groups of four letters
S is the sign bit (0 if positive, 1 if negative).
EEE EEEE E represents the 2's exponent. It is a 2's complement value biased by 127 (7F
Hex). The exponent can be determined by subtracting 127 from the value of the E field and
raising 2 to the resulting power.
MMM MMMM MMMM MMMM MMMM MMMM represents the 23-bit mantissa. Since
the mantissa describes a value which is greater than or equal to 1.0 and less than 2.0, the 24th
bit is always assumed to be equal to 1 and is not transmitted or stored. The value of the
mantissa can be determined by dividing the value of the M field by 8,388,608 (2 23 ) and
adding 1.0.
6.3.1.3 The complete value of the floating point number can then be determined by multiplying the
exponent by the mantissa and attaching the appropriate positive or negative sign.
6.3.1.4 By convention, 00 00 00 00 represents the value 0.0 even though it actually converts to
5.8775 x 10 -39 .
6.3.1.5 The eight "nibbles" are transmitted in sequence from 1 through 8 as shown in section 6.3.1.2.
Part No. 576013-635, Revision Y 6
6.3.2 EXAMPLES
6.3.2.1 3F800000 hex = 0011 1111 1000 0000 0000 0000 0000 0000 bin
S = 0 = + (positive)
E = 011 1111 1 bin = 7F hex = 127 dec
M = 000 0000 0000 0000 0000 0000 bin = 0 hex = 0 dec
Exponent = 2 (127-127) = 1.0
Mantissa = 1.0 + (0/8,388,608) = 1.0
Decimal Value = +1.0 x 1.0 = 1.0
6.3.2.2 B8D1B717 hex = 1011 1000 1101 0001 1011 0111 0001 0111 bin
S = 1 = - (negative)
E = 011 1000 1 bin = 71 hex = 113 dec
M = 101 0001 1011 0111 0001 0111 bin = 51 B7 17 hex = 5,355,287 dec
Exponent = 2 (113-127) = 0.0000610352
Mantissa = 1.0 + (5,355,287/8,388,608) = 1.63840
Decimal Value = -0.0000610352 x 1.63840 = -0.0001
6.3.2.3 C2C7FAE1 hex = 1100 0010 1100 0111 1111 1010 1110 0001 bin
S = 1 = - (negative)
E = 100 0010 1 bin = 85 hex = 133 dec
M = 100 0111 1111 1010 1110 0001 bin = 47 FA E1 hex = 4,717,281 dec
Exponent = 2 (133-127) = 64
Mantissa = 1.0 + (4,717,281/8,388,608) = 1.56234
Decimal Value = -64 x 1.56234 = -99.99
6.3.2.4 461C4000 hex = 0100 0110 0001 1100 0100 0000 0000 0000 bin
S = 0 = + (positive)
E = 100 0110 0 bin = 8C hex = 140 dec
M = 001 1100 0100 0000 0000 0000 bin = 1C 40 00 hex = 1,851,392 dec
Exponent = 2 (140-127) = 8,192
Mantissa = 1.0 + (1,851,392/8,388,608) = 1.22070
Decimal Value = +8,192 x 1.22070 = 10,000
So, I have created a spreadsheet which almost is able to extract the value of the TC Level. However, almost is the operative word. A zipped version of my Microsoft Excel 2007 xlsx file is attached.
Thank you for reading this far. Happy summer! Oh, I downloaded and ran the Do-more controller software. It is over my head at this time. I have successfully created a simple smart relay system using the Click PLC for another project.
Special thanks to Travis E., Billy S., Paul R., and the folks at Automation Direct who have been so helpful over the phone.
-
It's much, much easier than that...no spreadsheet required. You would use a STREAMIN to read data from the port to a string element. Use STRSUB to access the desired characters and copy to a second string. Use STR2INT to convert the ASCII hex val in the second string into an integer. Then cast the integer to real using the :R cast operator. Since the value is IEEE float, it should work fine without conversion.
Possible sticking point is byte order, but we have many ways to handle that. In Do-more, you won't break a sweat on this one.
-
BobO!!
Thanks for the assurance.
Since all of this is sooo much over my head, who can I hire to write the program?
Which Do-More should I choose?
(All we need is a way to close one contact when the value of the TC Volume drops when another contact is open. We don't want to respond to an increase.)
-
Since all of this is sooo much over my head, who can I hire to write the program?
We don't do apps and I'm not sure who I would send you to...but...the code to talk to the device would be pretty simple and we would be happy to roll out some sample code that would get you most of the way there.
Which Do-More should I choose?
The most expensive one of course!! ;)
I personally always use the H2-DM1E because the Ethernet port is much faster for programming, but, if all you need is the serial port to access your device, the H2-DM1 would be fine...you would have to program it with the USB port, since the serial port will be unavailable.
-
BobO,
The STRSUB command is clear enough. I was able to extract part of the 82 characters into SS1. Now, I need to evaluate the number. Does the PLC need to have the HEX in another format or, can the HEX be evaluated directly? I want to know when the volume decreases and activate the relay when it does decrease.
-
Take a look at STR2INT.
-
BobO,
I take it that the system must have an integer to evaluate.
Now, I need to figure out what I'm doing wrong with the memory location. The text portion of the 82 is in SS1, but the STR2INT does not show SS1 in the Valid Ranges window. I'm also seeing a "Coil parameter is invalid: Element is an excluded size" message.
Where is the tutorial...?
-
Not in front of a PC where I can enter this and do screen caps, so bear with me...
I am assuming that you have already extracted the 8 digit hex representation of an IEEE float. So in SS1, you should have 8 characters...no more, no less. If you do not have 8 characters in SS1, we're gonna need to back up and get that part right.
The 8 characters in SS1 are the text representation of a 32 bit hex integer containing the raw data of a 32 bit float. So we first need to convert the text of the 32 bit hex number into an actual 32 bit hex number. To do that we are using the STR2INT instruction, which is designed to convert string representations of integers into the integers themselves. STR2INT takes a string input and outputs an integer. So plug SS1 into the input field, stick a valid 32 bit integer into the output field...say D0, and select hex as the format.
Assuming that you started with "1234ABCD" as the value in SS1, after the conversion you should have 0x1234ABCD (in hex) in D0. Since D0 is an integer...which is necessary since the raw data was stored as integer text...we need to reinterpret the value in D0 as a float. To do this you will use a format cast. To get Do-more to interpret the the data in D0 as a float instead of an integer, append ":R" to D0. The best place to test it is a data view...just enter "D0:R" to see the float result.
It really should be that simple: 8 characters in SS1, gets converted to an integer in D0 through STR2INT, then use ":R" to get Do-more to reinterpret the value as a float.
I'll pop in the office tomorrow and do a quick sample and post it.
-
Ok...here is a sample program that does what I think you need to be doing...which I think is just a STR2INT instruction, although it might require a SWAPB if the order of the bytes in your data are different. Let's assume not for now. This sample has just 3 instructions, and the first 2 are just to create the data that you should be getting from your comm stream.
* In the MOVE I am plugging 3.14159 into D0:R, which means D0 (which is an int) reinterpreted as a float. This is necessary because otherwise it would store an integer 3 there, rather than a float 3.14159.
Line 1 of the data view shows D0:R, and you see 3.14159...the desired float value.
Line 2 shows D0 as its native integer (shown in hex) and contains the raw hex data of the float value 3.14159.
* In the STRPRINT, I am printing the hex value of the float 3.14159 into SS0. This should be exactly the same kind of value you are getting from your device.
Line 3 of the data view show SS0 after the hex value in D0 is printed to it. Your data should look very similar to this.
* In the STR2INT, I am converting SS0, containing the string representation of the raw hex into an integer containing the same hex value and storing it in D1.
Line 4 of the data view shows D1 as a hex integer showing the same value that was originally in D0.
Line 5 shows D1 reinterpreted as a float. D0 and and D1 both match in both formats.
That should be re-creating the full path back to the original sensor.
The only caveat here is possible byte order. If for some reason the data doesn't look right, you may need to swap the bytes after the STR2INT. Use SWAPB to do that.