Sign in to follow this  
Followers 0
ReBroker

shift register recomendations

2 posts in this topic

Hi all, I am modifying some code at work and have been pondering 1 of 2 ways to go about accomplishing my goal. Sorry i can not post the code but will describe what going on to the best of my ability. We use a bit shift register to track cartons thru a machine, at start up we use a "bitwise comparative or" to load known bad catons (due to stop/start) into the register for rejection purposes. We have identifyed another area of cartons that are bad durring stop/start and want to reject them also. I plan to set-up another "bitwise comparative or" and load this in the same shift register at thier respective place for reject. Is this a better idea then setting up a whole new shift register for tracking and reject? Slc 500 plc. Please let me know your thoughts

Share this post


Link to post
Share on other sites
It is not entirely obvious what exactly you are describing. It sounds like you have a certain number of fixed stations and you are representing the presence/absence of a carton at a station based on the presence/absence of a corresponding bit, and you want to now have 3 states: "no carton", "carton, good", and "carton, reject". You haven't specified whether you may in the future want to expand this to say "carton, filled", "carton filled with X items", etc. You are representing them with a bit queue. With you 3 states, you can represent this easily in 2 bits. If you have 8 or fewer stations, you could store the state for each station in 2 consecutive bits in the same word and use 2 shifts for each index move instead of just one. Or you could use 2 words and represent up to 16 stations and use 2 shifts, one for each word. The latter is what you are describing. If you expand further in the future (to the point where single bits become unwieldy), then you may want to consider whole words to represent things. The easiest way to do this is with a FIFO (first in, first out) queue. PLC-5 and SLC have instructions for doing so (FFL, FFU), but it is somewhat inflexible...it can only operate on words. You can also implement this somewhat more directly without the overhead of the "R" register and such with a simple COP instruction if you are doing the shift with whole words but with one caveat: everything must be "backwards" in memory, and you can index everything in one direction only. In other words, the highest numbered word is the "start" of the queue, and the lowest numbered word (usually 0) is at the "end" of the queue. Use COP <second-to-last station> <last station> <number of words> to do this. So for instance if each station is represented by 1 word and there are 20 stations, you'd use COP 1 0 20. If you try to use COP in the reverse direction, it won't work because COPy always starts with the first location in memory...draw it out on paper and you'll see why. This method will work with any data type, not just integers. And it can work with multi-word stations as well just by adjusting the starting locations in the COPy instruction. Both of the last 2 methods (built-in FIFO and COP instruction) physically COPY memory for each register shift. If you have a large number of stations, this can begin to consume a lot of cycles in the ladder. At that point, a better method is a ring or circular buffer. Check out wikipedia's article on circular buffers if you want a graphical description of this technique. In this case, you have a pointer to the head and tail of the buffer. Every time you add an item, you increment the head location. Every time you remove an item, you increment the tail. Make sure that the tail does not overtake the head (buffer underflow) and vice versa (buffer overflow). Whenever the index for the head or tail over-runs the "end" of the physical memory, reset it back to the start of physical memory. This ring buffer technique requires a lot more math to figure out where you are at especially if you are accessing the buffer anywhere except at the ends but requires no physical copying operations because it just moves pointers around the ring. Finally, sometimes I find that I have a variable or a large amount of items between stations and it becomes really tedious to try to force the item list into fixed-size queues. In this case, I'll estimate the maximum number of items between stations (to determine memory footprint) and use a ring buffer or other type of FIFO queue between stations. The idea here is that you really don't care too much what the content of the buffer is...only that it keeps everything in order as it passes from station A to station B.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0