Ron Beaufort
Lifetime Supporting Member
this is a request posted on another forum ...
since this topics of "using ASCII input data ... converting strings into numeric values ... and parsing parameters into separate memory locations" comes up relatively often, I've decided to answer the question here at Phil's more "user friendly" PLCs.net ... here is a link to the original posting just in case anyone is interested:
link to original post on the other forum
greetings, umesh9554,
first of all, thanks for a very specific statement of your program’s requirements ... unfortunately most people don’t go to the trouble of providing a detailed example of the data format ...
I do have one question though ... are your data values always “zero filled”? ... let me explain by using the first parameter as an example ... you gave this parameter as the five characters “##.##” ... based on this I would expect the value “12.34” to be transmitted as “12.34” ... that’s simple enough ... but consider the value “1.2” for the first parameter ... question: will that be transmitted as the full five characters “01.20” ... or as just three characters “1.2” ... let’s hope that it will be the former ... because if the number of characters varies, then the program I’ve written will require some SUBSTANTIAL modifications ... it CAN be done so let me know if this added functionality is required ...
basically my program consists of a subroutine which uses an ABL (ASCII Test For Line) instruction to continuously monitor the PLC’s serial port for a new data string ... whenever new data is received, an ARL (ASCII Read Line) instruction gets the data and stores it in a string location ... next AEX (String Extract) instructions are used to retrieve the “whole number” and the “fractional portion” for the parameter ... at this point, the data is still in a “string” format ... if you’re not exactly sure what that means, just think of it as “text only” data ... specifically, it may “look like” a number but it has no “real” numerical value ... and so ACI (String to Integer) instructions are used to convert from the “string” type data into true numerical values ... these values are temporarily stored in integer locations ... next, a MUL (Multiply) instruction is used to convert the integer value representing the “fractional portion” of the parameter into its actual “decimal” equivalent value ... example: the integer value “34” is multiplied by “0.01” and becomes “0.34” ... writing this “decimal” value directly into a floating point location (one reserved for this specific parameter) has the effect of overwriting any existing value from the last data string ... now we use an ADD (Addition) instruction to add in the “whole number” portion of the parameter ... and the first parameter is done ... and then we move on to the next parameter following the same type of conversion methods ...
you’ll notice that some of the parameters don’t even have a “fractional portion” so the conversion process is slightly easier in those cases ... once the “whole number” is converted from a string into an integer value, then only a simple MOV (Move) instruction is required to finish up by storing the number in a floating point location ...
I’ve kept the layout of the program rungs extremely simple on purpose ... this will make it a lot easier for you to accommodate any future modifications to the format of your data string ... the whole conversion routine could be made more “elegant” by using a recursive loop construction and by using indirect addressing to move from one parameter to the next ... I’m just guessing but probably ten rungs or so would handle the whole operation ... BUT ... I would NOT recommend that approach ... you might save several rungs, but the complexity of the program would be increased many times over ... someday someone else will have to work with this program ... there’s no valid reason to make it any more complicated than it really needs to be ... rungs are cheap ... time is expensive ...
finally, as for the cable connections that you’ll require ... a simple “null modem” cable is all that I used when I tested this out ... you’ll need a DB25 male connector for the PLC end ... and a DB9 female connector for the computer end ... if you turn the channel’s “hardware handshaking” off, then you’ll only need three wires connected ...
from pin 2 on the DB25 male – wire to pin 2 on the DB9 female ...
from pin 3 on the DB25 male – wire to pin 3 on the DB9 female ...
from pin 7 on the DB25 male – wire to pin 5 on the DB9 female ...
and incidentally, I used HyperTerminal to send the data from the PC to the PLC while testing my program’s operation ...
here is a screen shot of the program's handling of some random data which fits your specified format ...
[attachment]
in case you haven’t thought about it yet ... you’ll have to set up your PLC’s Channel 0 for the “User Mode” to get the ASCII input to work ... so if you’re using Channel 0 as your only programming port, look out for serious complications down the road ... the best way to proceed is to use the PLC’s DH+ (Data Highway Plus) connection for programming and reserve Channel 0 for the serial communications ...
continued in next post ...
I am using PLC5/20 processor and want to communicate with third party embedded PC on COM port in ASCII Format. Actually, PC is monitoring the machine and sending parameters in ASCII format through COM port and I have to retrieve those parameters in PLC. Embedded PC is set to send data on COM port with settings :9600, 8, None, 1 and sending string of parameters in following format
##.##_###_###.##_#.##_##.##_##.#_##_###_##.##_#.##_##.#_##_##_#
All # are numerical values and _ is the space between two parameters. I am not sure how to configure the PLC5 for receiving these parameters and the cable connections. Please help me if somebody is aware of the solution. Thanks umesh9554
since this topics of "using ASCII input data ... converting strings into numeric values ... and parsing parameters into separate memory locations" comes up relatively often, I've decided to answer the question here at Phil's more "user friendly" PLCs.net ... here is a link to the original posting just in case anyone is interested:
link to original post on the other forum
greetings, umesh9554,
first of all, thanks for a very specific statement of your program’s requirements ... unfortunately most people don’t go to the trouble of providing a detailed example of the data format ...
I do have one question though ... are your data values always “zero filled”? ... let me explain by using the first parameter as an example ... you gave this parameter as the five characters “##.##” ... based on this I would expect the value “12.34” to be transmitted as “12.34” ... that’s simple enough ... but consider the value “1.2” for the first parameter ... question: will that be transmitted as the full five characters “01.20” ... or as just three characters “1.2” ... let’s hope that it will be the former ... because if the number of characters varies, then the program I’ve written will require some SUBSTANTIAL modifications ... it CAN be done so let me know if this added functionality is required ...
basically my program consists of a subroutine which uses an ABL (ASCII Test For Line) instruction to continuously monitor the PLC’s serial port for a new data string ... whenever new data is received, an ARL (ASCII Read Line) instruction gets the data and stores it in a string location ... next AEX (String Extract) instructions are used to retrieve the “whole number” and the “fractional portion” for the parameter ... at this point, the data is still in a “string” format ... if you’re not exactly sure what that means, just think of it as “text only” data ... specifically, it may “look like” a number but it has no “real” numerical value ... and so ACI (String to Integer) instructions are used to convert from the “string” type data into true numerical values ... these values are temporarily stored in integer locations ... next, a MUL (Multiply) instruction is used to convert the integer value representing the “fractional portion” of the parameter into its actual “decimal” equivalent value ... example: the integer value “34” is multiplied by “0.01” and becomes “0.34” ... writing this “decimal” value directly into a floating point location (one reserved for this specific parameter) has the effect of overwriting any existing value from the last data string ... now we use an ADD (Addition) instruction to add in the “whole number” portion of the parameter ... and the first parameter is done ... and then we move on to the next parameter following the same type of conversion methods ...
you’ll notice that some of the parameters don’t even have a “fractional portion” so the conversion process is slightly easier in those cases ... once the “whole number” is converted from a string into an integer value, then only a simple MOV (Move) instruction is required to finish up by storing the number in a floating point location ...
I’ve kept the layout of the program rungs extremely simple on purpose ... this will make it a lot easier for you to accommodate any future modifications to the format of your data string ... the whole conversion routine could be made more “elegant” by using a recursive loop construction and by using indirect addressing to move from one parameter to the next ... I’m just guessing but probably ten rungs or so would handle the whole operation ... BUT ... I would NOT recommend that approach ... you might save several rungs, but the complexity of the program would be increased many times over ... someday someone else will have to work with this program ... there’s no valid reason to make it any more complicated than it really needs to be ... rungs are cheap ... time is expensive ...
finally, as for the cable connections that you’ll require ... a simple “null modem” cable is all that I used when I tested this out ... you’ll need a DB25 male connector for the PLC end ... and a DB9 female connector for the computer end ... if you turn the channel’s “hardware handshaking” off, then you’ll only need three wires connected ...
from pin 2 on the DB25 male – wire to pin 2 on the DB9 female ...
from pin 3 on the DB25 male – wire to pin 3 on the DB9 female ...
from pin 7 on the DB25 male – wire to pin 5 on the DB9 female ...
and incidentally, I used HyperTerminal to send the data from the PC to the PLC while testing my program’s operation ...
here is a screen shot of the program's handling of some random data which fits your specified format ...
[attachment]
in case you haven’t thought about it yet ... you’ll have to set up your PLC’s Channel 0 for the “User Mode” to get the ASCII input to work ... so if you’re using Channel 0 as your only programming port, look out for serious complications down the road ... the best way to proceed is to use the PLC’s DH+ (Data Highway Plus) connection for programming and reserve Channel 0 for the serial communications ...
continued in next post ...