SLC500 Converting integer to Ascii

ejessen

Guest
E
In order to communicate with some 3rd party hardware, I need to build a ASCII-string based on HEX values.

The basic problem is to have an calculated variable integer value of e.g. 255 and have the ST element to be added FF.

Entering HEX values manually into the ST-element is no problem and the communication works fine, but I can't find a way to build the string based on PLC commands. The ASCII conversion table describes how a value of e.g. 01h is entered as \01 or ^A (the latter to be displayed in the ST-element), but how can this be concatenated to the ST-element on basis of a calculated value in an N-file?
 
So, if your integer value is '255' you want to send the ASCII string 'FF' to the device, and if the integer value is '16' you want to send an ASCII '10', and so on, correct? I've got an idea, I just want to be sure we're talking about the same thing.
 
Wow, this is a challenge.

The SLC has a pair of nifty "Integer to String" (AIC) and "String to Integer" (ACI) commands. But these work off Base 10 numbers, and will convert the value 255 to the string "255", not "FF".

Hmm. We're probably going to need a for-next loop and sixteen compare instructions in a subroutine here.

[scratches head]
 
OK now, 'ejessen' mentioned 255 but is that the largest integer which will be present? In general lets say he wants to send the ASCII-hex representation of any possible integer. Let's also assume he wants these in in order from most significant nybble (that is the name for the 4 bits section of a byte if I'm not mistaken) to least significant.

So the outermost loop will have to pick off the 4 nybbles from the 16 bit word by ANDing and shifting. (AND F000h then shift right 12 bits, AND 0F00h then shift right 8 bits, AND 00F0h then shift right 4 bits, then finally AND 000Fh)

The inner code would take each isolated nybble and add 30h. If the result is greater than 39h then add another 07h. This will give the characters '0'(30h) through -'9'(39h) and 'A'(41h) through 'F'(46h) given the values 0-15.

These characters must then be added to the end (concatenated) of the string being built.

Not a simple task but fairly straightforward in execution.
 
Quote:
So the outermost loop will have to pick off the 4 nybbles from the 16 bit word by ANDing and shifting. (AND F000h then shift right 12 bits, AND 0F00h then shift right 8 bits, AND 00F0h then shift right 4 bits, then finally AND 000Fh)


I was thinking along those lines also, except I was going to divide by 16 to bring the next set of bits into position.

Quote:
The inner code would take each isolated nybble and add 30h. If the result is greater than 39h then add another 07h. This will give the characters '0'(30h) through -'9'(39h) and 'A'(41h) through 'F'(46h) given the values 0-15.

These characters must then be added to the end (concatenated) of the string being built.

Not a simple task but fairly straightforward in execution.


Since 'ejessen' seems a little unsure here I was going to suggest a lookup table. That is, take the result of the ANDing above and use it as the index into a table set up with the required ASCII characters for each hex value. It's a personal preference thing, I guess.

As an aside, it's not absolutely required to use the concatenation instruction - the individual string characters can also be addressed by the instruction:

MOV N7:0 ST10:0.DATA[N]

where N is a literal integer value designating the nth character of the string, zero being the first character, one being the second, etc. At least that is, with a PLC-5. The SLC's have the same basic string handling instructions so I presume this would work with them as well. When using this method I would always do a MOV of the required length into ST10:0.LEN
 
I got tripped up because you can't individually address a character in a STring element, you can only address two characters (a 16-bit subelement). The Logix family does this better, allowing you to manipulate 8-bit SINT bytes individually.

The sign bit on the most-significant-nibble also poses a problem, but I didn't want to deal with the control-file overhead of BSR instructions so I just worked around that by considering that one bit separately.

I got this working in a 16-rung subroutine by following Bernie's description of the program execution. (Thanks, that was really good !)
 
My subroutine looks OK for converting just one word from hex to ASCII, but if our original querent wants several words to be converted it makes sense to have a more loop-oriented approach.

What do you say, ejessen ?
 
Thank you all for your enlightning replies.

Unfortunately, I wasn't online when the major part of the discussion took place, but here are my comments:

The code of Ken Roach, based of the words of bernie_carlton, is really what I was looking for. I was not aware of the way of writing individual characters into the string element by using the MOV N7:0 ST10:0.DATA[N] as Doug-P suggested and it really seems to be the right way to go.

In order to send not ASCII characters but hex values, I need to add a back slash in front of every byte, but that is a simple task.

I will have to design a more loop oriented code as first of all, there are severel values to be transferred and second, a few of them are values of way more than 65535. So I'll also have to go into deciffering a few floating point registers into ascii characters (but then a do not enter the sign bit problem *SS*).

But I'm very pleased that you can do the conversion in only 16 rungs (and now it is explained for the studpid, i.e. me, it can well be compressed).
 
I'm now a registered member - it has been far more interesting replies than I have ever hoped for. And I'll check future discussions for the chance to give my comments to new interesting subjects.
 
I'll now go into the issue of retriewing a floating point value into hex values and then into ascii characters as above. For a start, I'll limit the floating point values to be integer values > 65535, not real numbers.

I've read some describtion of how the floating point reg's are build, so I think it isn't too difficult to extract the value. Do any of you have experience with that?
 
Hej !

With AB SLC500, converting between integers and floats is painless. Simply MOV the float value into an integer value. The processor will automatically extract the integer value with proper rounding.

You may have to put the limits to +/- 32676, as the standard interpretation of integers in the SLC500 is signed .
 
Using the MOV to convert from F-reg's to N-reg's is no problem as long as the value is less than +/- 32676. At greater values, e.g. greater than 65535, the PLC will fault.

As I need to convert values far greater than this limit, some other measures need to be taken.
 
Hej igen !

Hmmm... how do you move a number greater than 32676 from a float into two integers ? (which I think is what is needed for you to solve your problem).

In the SLC500 there is no move-the-float-value-into-two-integer-values instruction (in MicroLogix 1500 there is !).
Somehow you must use some math here, dividing by 10000 for example to access the higher values.
The problem is, that floating point values have a range of 1.1754944e-38 to 3.40282347e+38. In other words, the mantissa has a precision of 8 decimals. You cannot get more decimals than that anyhow.

I would like to ask you a question:
From where does the value originate ?
If it is from some math then I dont think there is a way without using floating point.
If it is from some kind of counting, then use cascaded integers in stead of a floating point. This would simplify everything considerably.
 
Appendix F of the Instruction Set Reference Manual (1747-rm001c-en-p) discibes how the floating point element is calculated. I haven't had the time yet to make any code for retriewing a number from such register, but it LOOKS straght foreward - thats why I ask for a comment from one that tried.

The nature of the task limits the RESULT value to a long integer (+/-2147483647), but it will be a calculated value from elsewhere in the program and may even contain decimals.
 

Similar Topics

Hello, did anybody know, if there exist an converting cable like the1492-CM1746-M01 (for an 1746-IB16 to an 5069-IB16), for an 1746-HSCE to an...
Replies
3
Views
381
Hi, is there anyone experienced in converting shift registry(SR) his command to SLC ladder logic have been trying for some time but not...
Replies
0
Views
1,502
hi, i balan here, i am amids of converting a program from ps3 to slc, however to start i have a manual on it but it is in dutch language and i am...
Replies
20
Views
4,764
hi any out there have any information on converting seimens s5 to allen bradley slc500 as i am looking at converting these programs in our...
Replies
3
Views
4,635
can the slc500 5/05 send a email and text over Ethernet ?
Replies
3
Views
178
Back
Top Bottom