Is there any way to detect which bit is first ON in my program

Yes*.

TL;DR



Is this homework or work-work? If homework, I suggest you try both methods, and see if you can find others.


Sidebar: If you show the work you have attempted so far, you are likely to get more helpful responses.


* As long as two or more of the the set of source bits are not detected as changing from 0 to 1 on the saem scan.


Method 1: use one-shot (Allend-Bradley) a.k.a. pulse (Siemens, others) instructions to detect the rising edges of all the source bits in the set of bits to test. If only one one-shot is on, then its source bit is the first.


OR



Method 2: pass each of those N source bits (N<17 or N<33) to test into the N low bits of an integer, and ensure the high (16-N) or (32-N) bits are 0. When the integer was 0 on the previous scan and non-zero on the current scan, then if that integer contains a value that comprises a single 1-bit and 15 (or 31) 0-bits (e.g. 1, 2, 4, 8, ...), then that single 1-bit came on first during the current scan. There is a simple two--or three-instruction test for a 1-bit integer.
 
I have 8 button I want to know which button is first pressed,which button is second pressed,third,fourth etc
Is it possible
 
I have 8 button I want to know which button is first pressed,which button is second pressed,third,fourth etc
Is it possible


Yes.


What is your level of experience with programming PLCs? That will make it easier to tailor a response to you, but without preventing learning in case you are a student and this is a homework assignment.


What brand of PLC is being used? What language is being used (ladder, structured text, etc.)?
 
Last edited:
Make array of 8 bits that is equal to one byte. On every change push the byte to shift register. By analyzing the shift register you will know it.
 
the way to do it is have create a tag as INT if the tag = 0 then each button when pressed will a value into the tag example
button 1 moves the value 1 into the tag
button 2 moves the value 2 into the tag
button 3 moves the value 3 into the tag
only the first button received while the tag value = 0 can place the a value in the tag
the down side is that ladder code runs to to bottom so if 2 buttons were received in the same scan only the first scanned will move the value
so for 99% of the time this system will work
 
Read the post the OP wants to know the sequence in which the buttons are pressed, so this could possibly more than 8 presses, however, assume less than or = to a max of 8 buttons then I suggest the following.
Check the 8 bits for a button press, set a latch that starts a timer (idle time to reset when times out).
Check the buttons put a value into a shift register i.e. 1 for button 1 , 2 for button 2 etc. increment the shift. after a given time, reset the latch.
This way when operator presses a buttons in a combination, the shift register will show the order of the buttons, after a time the sequence is reset.
Scenario,
Operator selects first button, then second button & so on, the timer has a timeout i.e. 5 seconds so the operator only has 5 seconds to enter the digits or it will start over again, you could make it so the OP has to enter say 4 digits (if it will always be fixed length), or a time out, could also have a delay time before operator can enter the digits again.
It will depend on what this application is for, to get a definitive answer we would need to know exactly what the operator is likely to do what you want it to do etc. etc.
 
...
the down side is that ladder code runs to to bottom so if 2 buttons were received in the same scan only the first scanned will move the value
so for 99% of the time this system will work


Reset a bit, tag TheBit, to 0 at the start of each scan.


The first button that is discovered as pressed during a scan sets TheBit to 1 and puts the button number (1, 2, 3, ..., 8) into the tag array at the tag index and increments the tag index



When any subsequent button is discovered as pressed during a scan, if TheBit is 1 then put the negative of the button number (-2, -3, -4, ..., -8) into the tag array at the tag index and increments the tag index.
 
the original post First ON
either way a simple FIFO will give you what you want
Button press move the value trigger the FIFO or a simple shift
the values in the file will be in the order received
 
My first read of the OPs query was that he wanted to see which button was pressed in a "set" of buttons, and that is relatively simple to do - find the first button input ON and ignore the others. But reverse the order of the rungs of code, and you'll get a different answer.

But I have re-read and re-thought it, and it seems that he wants to know which button was pressed first. For that we have to use timestamps somehow, and not rely on PLC scan order, another button being ON can have been pressed earlier than the one found in the code scan.

More than one button can come ON in any given I/O update, and you cannot tell which button was pressed first, a subtle difference to detecting the lowest, or highest, addressed input.

Simply put, a PLC cannot give the answer the OP asked for without external, or more expensive, hardware.

In Logix5000 you can use an Event task to monitor an input module's data-state change for an input coming ON, and you can quickly detect which button, and timestamp it, but it will only be effective for one button only. You still have the same code to go through, detecting which button, and there may be more than one.

You cannot deal with multiple inputs (buttons) coming on simultaneously, The event task will be fired just once no matter how many inputs have changed.
 
Without a dough with any system you have the programming code operated top down left to right so you will always have the chance of 2 input true in the same scan but with scan time of 200 ps or 200 10,000 th of a second the chance of 2 simultaneous input is not worth even thinking about
As at FIFO is the way yo handle it.
 
There's a similar question on Siemens S7-1200 forum section so it's the same person or from the same class. Nice assignment, I will put it on my list for playtime when .....
 
Here is some logic that in the normal scan will put the first pressed to last pressed in a set of registers (array) so the first register will contain the button number and so on, This is based on an operator entering a sequence of buttons assuming he does not press more than one at a time, based on an average scan time of 10ms it will detect the difference between two buttons pressed with a window of the scan time i.e. providing the difference is greater than the scan time then in this case two buttons being pressed has to be greater than 10 ms (for true differentiation then call it 20ms).
This code could be called in a time interrupt of say 5ms (many PLC's are capable of this). or as I/O interrupts (in that case each bit could be evaluated individually in each interrupt so split the code), note as I do not know that platform the OP is using I have written this in long winded but simple sort of ladder/FBD. I would not have done it like this but by indirect / loop logic or even in ST so it is only to demonstrate how to detect the order of key presses.
I included timers not knowing this was probably a simple Simon or game logic but based it on an operator selecting up to 8 products in a sequence with simple selections of 8 buttons so is probably not what the OP wants but will work within the constraints mentioned above. this is where OP's need to give as much information as possible to allow us to understand and supply the correct solutions, however, it is obvious that not all of us read the whole posts so very often get it wrong me included.
Again I re-iterate, this code is long winded for a reason as mentioned above.
So not comments on It could be done simpler until we know that PLC it is please.
 
@parky: sweet!


Here is a way to deal with ties i.e. when the first presses for multiple buttons are detected on the same scan.

The ordinals[] array will store which ordinal position each button was pressed, so if buttons 4 and 7 were pressed on the same scan before any others, ordinals[4] and ordinals[7] will both contain the value 1, indicating those buttons "tied" for first.

The order[] array will store the order in which buttons were detected, with no discrimination for ties. So in the example above, order[0] will contain the value 4, and order[1] will contain the value 7.

This does not work for Simon-Says, the canonical version of which allows each button to be pressed more than once in the same sequence.

Ordinal for any button(s) pressed during this scan is one more than the number of buttons pressed so far i.e. as of the start of this scan
Code:
--[ADD             ]--
  [SourceA    sofar]
  [SourceB        1]
  [Dest     ordinal]
If this is the first time button 0 has been pressed, then assign its ordinal in the ordinals[] array, place its ID (0) in the order[] array, and increment the number of buttons pressed so far
Code:
  btn0   sto0
--] [----]/[---+--[MOV                ]------+--
               |  [Source      ordinal]      |
               |  [Dest    ordinals[0]]      |
               |                             |
               +--[MOV                 ]-----+
               |  [Source             0]     |
               |  [Dest    order[sofar]]     |
               |                             |
               +--[ADD           ]-----------+
                  [SourceA  sofar]
                  [SourceB      1]
                  [Dest     sofar]
Duplicate previous rung for remaining 7 buttons, btn0=>btnN, sto0=>stoN, 0=>N; ordinals[0]=>ordinals[N], for N=1,2,3,...,7

N.B. the order[] array records the button, for which those rungs are executed earlier in this ladder program, as being pressed earlier when multiple button presses are detected on the same scan; the ordinals[] array can be used to detect such events, so the ordering of these rungs is relevant



Reset program
Code:
 Reset
--] [---[MOV          ]--
        [Source      0]
        [Dest    sofar]
Maintain or reset states using Start/Stop circuit; Set/Latch is an alternative, with separate rung for resets
Code:
     btn0    Reset    sto0
--+--] [---+--] [-----( )---
  |        |
  |  sto0  |
  +--] [---+
Duplicate previous rung for remaining 7 buttons, btn0=>btnN, sto0=>stoN, for N=1,2,3,...,7
...
 

Similar Topics

Hi All I have x number of bits representing an active state on x number of valves and I want to be able to detect when more than one valve is...
Replies
7
Views
1,964
I would like to have contact with someone who has used Diagnostic Instructions for the PLC-5. I have the manual and the Allen Bradley web site...
Replies
1
Views
3,027
Does anyone know of a way to detect if someone is online with the controller in ControlLogix (from logic) I'm thinking that maybe there is a CIP...
Replies
7
Views
376
Hi all, I am trying to find a way of detecting a motor is not isolated before attempting to run an inverter. We would normally use a 4 pole...
Replies
19
Views
3,071
Hello everybody, I have a vendor system that has some remote monitoring (read only) and remote control (read/write) data that is available via...
Replies
7
Views
2,868
Back
Top Bottom