Sign in to follow this  
Followers 0
Jeremiah

ADD Function

26 posts in this topic

Here is my issue. We are installing a table spray system in our plant. We have 8 tables and I need to know how many tables are on at any time. Each valve is controlled by a seperate timer and what I have tried doing is using the EN bit of each timer to add a 1 to an integer location and the DN bit of the same timer to subtract a 1 from the integer location. How do I get the ADD funtion to ONLY add a 1 each time. Once the EN comes on its seems to just add a 1 each scan until I am beyond 32767 and the processor faults. I think a ONS is what I need to use but can't seem to get it to work. How would you use a ONS to accomplish this or is there some other way? I appreciate your time and thanks for your help in advance. JS

Share this post


Link to post
Share on other sites
See picture below. Note: Make sure each one-shot instructions has a different address.

Share this post


Link to post
Share on other sites
Thanks Mickey. Your note is what saved me. All my one shots had the same address. Ooops. On another note, any suggestions on logic to prevent more than 4 tables to spray at the same time. We have 8 tables that will spray when needed but we don't want any more than 4 to be spraying at the same time. Thanks a lot Mickey I appreciate your help.

Share this post


Link to post
Share on other sites
Don't get tricky. Duh, set N7:0 to 0 at the before ADDs and forget the ONS. That way you always have the current count after the last ADD

Share this post


Link to post
Share on other sites
Not quite sure I understand Peter. How would N7:0 be anything other than 0? JS

Share this post


Link to post
Share on other sites
What Peter is saying is if you place a rung with CLR N7:0 before your ADD and SUB Rungs N7:0 will always have an accurate count with no one shots needed. My sample mnemonic code follows: Note in my code N7:1 always has the current spraying count. SOR CLR N7:0 EOR SOR XIC T4:1/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:2/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:3/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:4/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:5/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:6/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:7/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:8/EN ADD N7:0 1 N7:0 EOR SOR XIC T4:1/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:2/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:3/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:4/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:5/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:6/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:7/DN SUB N7:0 1 N7:0 EOR SOR XIC T4:8/DN SUB N7:0 1 N7:0 EOR SOR MOV N7:0 N7:1 EOR To answer your other question using my code above place an LEQ N7:1 4 in your spray permissive logic.

Share this post


Link to post
Share on other sites
To each his own , I prefer the one-shot.

Share this post


Link to post
Share on other sites
Mick I'm just old school. Worked with Assembly language years ago hence my love of mnemonics. Not to mention one CLR scans faster than 16 ONS's. Not that it matters much in most applications today.

Share this post


Link to post
Share on other sites
Yes, several ways to skin this cat. I probably would have used a up-counter and a down- counter ( same address) to keep track. There would have been no need for a one-shot then.

Share this post


Link to post
Share on other sites
Peter is right that you would be safer to clear the count integer and sum it back up each scan. Getting rid of the oneshots is not the reason. Getting rid of potential errors is a good reason. Get rid of the SUBtracts, and only add the ones that you are sure are running each scan after clearing the register. Trying to add and subtract without ever starting from zero could, at some point, lead to an inaccurate count. For example, what happens on an unexpected power cycle if there is a "3" in the register already? Paul

Share this post


Link to post
Share on other sites
REVISED CODE SAMPLE SOR CLR N7:0 EOR SOR XIC T4:1/EN XIO T4:1/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:2/EN XIO T4:2/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:3/EN XIO T4:3/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:4/EN XIO T4:4/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:5/EN XIO T4:5/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:6/EN XIO T4:6/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:7/EN XIO T4:7/DN ADD N7:0 1 N7:0 EOR SOR XIC T4:8/EN XIO T4:8/DN ADD N7:0 1 N7:0 EOR SOR MOV N7:0 N7:1 EOR 10 Rungs and no SUB Instructions

Share this post


Link to post
Share on other sites
Why not just use TT instead of EN + NOT DN?

Share this post


Link to post
Share on other sites
Are you sure you don't have to use one shots. I tried this and it continues to count very quickly as long as the EN bit is true. I am currently using the one shots with the EN and DN bit but the count is not reilable. Over the period of 30 minutes of so my count if off by at least 3. Is there a more reliable way than using the one shots?

Share this post


Link to post
Share on other sites
Jeremiah - BobLFoot has give you a workable and accurate solution. Have you tried it?

Share this post


Link to post
Share on other sites
REVISED 2nd TIME CODE SAMPLE SOR CLR N7:0 EOR SOR XIC T4:1/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:2/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:3/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:4/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:5/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:6/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:7/TT ADD N7:0 1 N7:0 EOR SOR XIC T4:8/TT ADD N7:0 1 N7:0 EOR SOR MOV N7:0 N7:1 EOR 10 Rungs and no SUB Instructions and a nice catch by b_carlton

Share this post


Link to post
Share on other sites
Yes I just tried it. It works great. I appreciate all your guys help on that one. I am still however having issues with preventing more than 4 tables from spraying at the same time. Bob mentioned putting a LEQ in series with my spray permitting logic. I have done that and it kind of works. When you first start the system each table has a 1 second delay before auctually starting so only the first 4 tables start, which is good. But after that it does not work. I am not quite sure why because everything happens so quickly. Might have to post some logic for this one. Any other suggestions based on this info. Thanks in advance. JS

Share this post


Link to post
Share on other sites
Without seeing your logic I'll go out on a limb. If you perform the logic to count the tables which are spraying before the logic to start an individual table spraying then the count is being used through the entire program. If one is permitted then all are permitted and if the decision to turn a given table on is made in the same pass as another then both will turn on. Try this. Dedicate a bit for use, call it 'A Table Is Starting'. As each table reaches the decision point test the bit, 'A Table is Starting' as OFF (XIO) as well as testing that less than 4 tables are already on. If a table is to be started then one-shot that decision and use the one-shotted condition to Latch the 'A Table Is Starting' bit. Unconditionally unlatch this bit at the extreme end of the scan (or at the very top of the next scan whichever is convenient. This way only one table can be started on each scan. Edited by b_carlton

Share this post


Link to post
Share on other sites
This won't actually work correctly, but your mention of the latch/unlatch is on the right track. This is a common pattern. It goes like this: Unlatch "inhibit bit" If condition A is true and not the inhibit bit then <do something> and latch "inhibit bit" If condition B is true and not the inhibit bit then <do something> and latch "inhibit bit" If condition C is true and not the inhibit bit then <do something> and latch "inhibit bit" ... Then either exactly 1 of the rungs will fire or none of them, and it's first-come, first served. If you prefer to make it more of a "queue" order (last one served is first one to trigger) then you will need to involve the support of some sort of queue.

Share this post


Link to post
Share on other sites
So lets see if I've got the desired sequence right? 1. Conditions are met to request a start of Table A Sprayer. 2. Timer A times for 1 second before actual start of Table A Sprayer. 3. When Timer A is Done and less than 4 Tables spraying then Table A starts spraying. And yes a code snippet will help.

Share this post


Link to post
Share on other sites
The only time the one second delays are used is when the system is started. Basically each table is controlled by 2 timers one is the amount of time the table will auctually spray, the other is the off time. Currently there really aren't any conditions to start a table besides its own timers, like a sprinkler system. However I would like to limit the number of tables to be sprayed at once to a number (probably 4) due to the chemical that we are spraying emitting an odor. The timer logic with the addition of the LEQ works, but on the first pass only. Then its just like B_Carlton said if there is more than one table that is ready to start when the 4th table shuts off, all of the tables start. I have tried his solution, and can' get it to work. I am stumped on this one. I appreciate your help and thanks in advance. By the way I use the EN bit of the running timer to latch around the LEQ and the DN bit of the off timer to break the latch if this helps at all. Edited by Jeremiah

Share this post


Link to post
Share on other sites
I understand why without scanning your code and it has to do with scanning order. Let see if I can explain. Your program looks like this in general terms. 1. Check for Table A to Start. 2. Check for Table B to Start. 3. Check for Table C to Start. 4. Check for Table D to Start. 5. Check for Table E to Start. 6. Check for Table F to Start. 7. Check for Table G to Start. 8. Check for Table H to Start. 9. Check count of Tables Spraying With the above logic table A,B,C,D start after the delay. when they stop the count is 0 and all tables are allowed to start. Now try this. Take the counting logic and place it in a subroutine of its own for my example SBR 99. Now modify your logic to look like this. 1. Check for Table A to Start. 2. JSR SBR 99 3. Check for Table B to Start. 4. JSR SBR 99 5. Check for Table C to Start. 6. JSR SBR 99 7. Check for Table D to Start. 8. JSR SBR 99 9. Check for Table E to Start. 10. JSR SBR 99 11. Check for Table F to Start. 12. JSR SBR 99 13. Check for Table G to Start. 14. JSR SBR 99 15. Check for Table H to Start. 16. JSR SBR 99 This way when table A stops the count drops to 3, but when E starts the count goes up to 4 before F,G & H are checked for starting not after. Hope I am clear. Without real code to look at I can only speak in assumptions and generalities.

Share this post


Link to post
Share on other sites
paulengr's explanation of the latch bit in post #19 was clearer than mine. This ensures you don't get the all at once thing. Make sure that the 'number of tables currently on' logic as described earlier is called at least once per scan. The test for the latched bit takes place at the same point where you are testing for the number of tables currently spraying. Make sure to use a one-shot method for a table which begins to spray to set this bit. This ensures that the logic of all other tables starting is inhibited and the 'count' code will execute. Then the 'total count' has a chance to control if another table wants to start. I just saw BobLFoots's suggestion. His will work also, calling the 'count' function after evaluating each table. Edited by b_carlton

Share this post


Link to post
Share on other sites
BobLfoot; Thank you very much. That works perfectly and makes perfect sense. I will definetely remember the neatness of using JSRs throughout the program. Again, I appreciate everyones help on this one. Now all I got to do is learn how to create a queue.

Share this post


Link to post
Share on other sites
That is no problem you're welcome. As to the queue read the help files for the instructions FFL and FFU. These will allow you to build and maintain a FIFO queue {First in First out - for the novices reading this post}

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