Read byte to ascii characters

I have a machine that is storing the part number in the plc from address DBB10 to DBB59. Each character is stored as a byte. I want to be able to convert to character and combine to create a single tag called Partno.
How could this be done?

To start with, you might wish to check out the following URL:


You might say that life ( in Hexadecimal ) starts at 41 (Capital A) or at 61 ( Again Hexadecimal ) lower case a. It would take a third significant number if you stored it in Decimal ( 0-127) which can be translated back to a letter at a time with a Basic Interpreter command CHR$(decimal number). With that in mind, you would then need to decide how to read the PLC ( preferably into the Gateway default Database ) then how to create and update your Tag “Partno” in a way that makes sense for the number of part numbers you expect to read at a given time. If you expect to have a great number of part numbers and descriptions to go with them, you may want to consider an external database. Now would be a great time to get a ‘lite’ version of a Database program ( they are commonly called SQLs for Structured Query Language ). Discrimination between home and commercial use appears to now be an issue for anything connected to Java and/or Oracle ( line of products )- others may follow.
As to Tag creation from a Database, the modules in Ignition can tell you better for your specific Ignition versions- yet the general Database information may not apply to newer versions(yet).

It would seem to me that the Siemens Driver should be able to take care of this directly. I am assuming Siemens, although you didn’t specify in your post, or what version of Ignition you are using.

Something like DBSTRING10.40 would be a string starting at DB10 and is 40 characters in length.

https://docs.inductiveautomation.com/display/DOC79/Siemens

This will only work if it's actually being stored as a String in the PLC. The S7 strings aren't just an arbitrary sequence of bytes, they are prefixed by 2 bytes indicating max and current length.

2 Likes

Gotcha. One more reason to dislike Siemens… lol

Then something like this may put you in the right direction:

# generate tag list
tagPath = '[default]path/to/the/tags/'
tagList = []

for i in range(10,60):
  tagList.append(tagPath+'DBB'+str(i))

# read tags in list
tagValues = system.tag.readAll(tagList)

stringOut = ''
for tag in tagValues:
  if tag.value == 0:
    break
  stringOut += chr(tag.value)
  
print stringOut

I am using Ingnition319 version 7.9.4. The bender is a Siemens PLC stored as a decimal. From address DB400.DBB10 to DB400.DBB59 (50 bytes) each byte is an ascii character right aligned.
Our part numbers are typically 11 characters in length so I created 15 OPC tags to each which I think is not the right way to do it. I can see the values right aligned (0,0,0,0,49,54,50,50,55,51,95,67,69,76,76)
Converted would be (162273_CELL). I was thinking I could convert to the character and then build a string with the tags in an expression but that doesn’t work.
FYI I am only about 1 week understanding of ignition.
Am I doing it in the right manner or should I use a script or some other way.Capture

Where would I do this? Scripts? how would I store the value together with the other tags I want to capture?

Okay, the questions are getting a further afield. let’s take care of the first bit.

I set up a similar folder and tag structure on my server. I also made one more tag in the same folder just called PartNo.

I would put this in a gateway timer script at whatever rate you want to run it.

# generate tag list
tagPath = '[default]Test/PartNumber'
tagList = []

for i in range(1,16):
  tagList.append(tagPath+'/PartNo_Char'+str(i))

# read all the tags
tagValues = system.tag.readAll(tagList)

stringIn=''

# read one character at a time until we get to a non-printable character
for tag in tagValues:
  if  32 < tag.value < 127:
    stringIn += chr(tag.value)
  else:
    break
    
# reverse the string
stringOut = stringIn[::-1]
 
# write to the tag   
system.tag.write(tagPath+'/PartNo', stringOut)

If I’m reading the rest of your post correctly, you would be looking at transaction groups.

If you are not already aware, we do have Inductive University available to us that has a lot of good information and videos.

https://www.inductiveuniversity.com

1 Like

A more ‘pythonic’ way, along with reading the tags in reverse order.

# generate tag list
tagPath = '[default]Test/PartNumber'
tagList = []

for i in range(15,0,-1):
  tagList.append(tagPath+'/PartNo_Char'+str(i))

# read all the tags
tagValues = system.tag.readAll(tagList)

stringOut = ''.join(chr(tag.value) for tag in tagValues if 32 <= tag.value < 127)

system.tag.write(tagPath+'/PartNo', stringOut)
1 Like

We should add chr and ord expression functions… :thinking:

7 Likes

So what result should I see with the script you sent? I have been going through the courses. they are vary helpful but I don’t know where to search for what I would like to so I just need to get through the course.
I appreciate the help.

Though I haven’t tested, the script @JordanCClark supplied ought to read your PartNumber tags and turn them into the single string you are looking for. Add a memory string tag in your PartNumber folder named “PartNo”, put the script in a gateway time script (see here), try it out, and let us know how it goes.

1 Like

Thanks guys! That did the trick I missed changing the path from test/partnumber to my folder structure.

3 Likes

I am having a different issue. one of my triggers for one of my machines is duplicating the entry every part. I have check the setup at it is set to trigger on the part number tag changing the same way I do on the other equipment which does not give me a duplicate. What could cause this to happen?

And two years later we did. You'll find char() and ordinal() expression functions in the nightlies now and in 8.1.8 when it comes out.

3 Likes