Which came First A or B?

Status
Not open for further replies.

Suraj143

Active Member
Hi all!

A & B is PIC input sensors. When it cross its giving an input to the PIC. What I want is

*When an object moves from A to B it must increment a value.

*When the object moves from B to A it must decrement the current value.

Any simple way to do this?

Code:
Out	btfss	PORTB,A		;has it cross A sensor?
	goto	In	
	btfsc	PORTB,A		;is still in front of A sensor?
	goto	$-1
	
	bsf	ENTER,IN
	bcf	ENTER,OUT
	goto	In

In	btfss	PORTB,B		;has it cross B sensor?
	goto	Out	
	btfsc	PORTB,B		;is still in front of B sensor?
	goto	$-1
	
	bcf	ENTER,IN
	bsf	ENTER,OUT
	goto	Out
 

Attachments

  • Detect.JPG
    5.2 KB · Views: 133
Hi,
IMO, PIC is running so fast, so it makes not much different checking either sensor A first or B first.

Seems you are doing a people counting system putting at the entrance?
 
Exactly I'm counting people.

The problem is when a person enters to A sensor & if he goes again outside without crossing B sensor the value will be jammed thats the problem I get.Any method to detect accurately?
 
Then you try to put both the sensors to be closer and see how. To make sure that the ppl can cross both of them.
 
A way to simplify it is to space A & B sensors so that as the object moves past the middle of the sensors it covers both sensors at the same time. So a movement from left to right would give this AB pattern:
00
10
11
01
00
From right to left:
00
01
11
10
00
Using this method you don't have to worry how fast the object moves between A&B to make the decision as to which way it is going.
 
Hi bananasiong keeping the sensors very closely will be the best.

Hi Kchriste thanks for your perfect idea. I’ll try to work on that. Soon I’m going to write a code on your method.
 

Classic Gray code as used in rotary encoders. Good thinking

Lefty
 
A slight simplification of kcriste's idea is to only count at one transition point.

Whenever the pattern goes from 10 to 11 then increment your counter.
Whenever the pattern goes from 11 to 10 then decrement your counter.

Mike.
 
Hi I wrote a basic code & I’m thinking about itself.

Code:
Out	btfss	PORTB,A		;has it cross A sensor?
	goto	In	
	btfss	PORTB,B		;has it cross B sensor?
	goto	In	
	btfsc	PORTB,A		;has it released A sensor?
	goto	In
	btfsc	PORTB,B		;has it released B sensor?
	goto	In
	incf	PEOPLE,F
	goto	In


In	btfss	PORTB,B		;has it cross B sensor?
	goto	Out	
	btfss	PORTB,A		;has it cross A sensor?
	goto	Out	
	btfsc	PORTB,B		;has it released B sensor?
	goto	Out
	btfsc	PORTB,A		;has it released A sensor?
	goto	Out
	decf	PEOPLE,F
	goto	Out

Pommie said:
A slight simplification of kcriste's idea is to only count at one transition point.

Whenever the pattern goes from 10 to 11 then increment your counter.
Whenever the pattern goes from 11 to 10 then decrement your counter.

Mike.

A very good point.
 
Hey, I don't think it is working because the people needs to run very very very very fast. Because after blocking the sensor, it takes so less time for the people to release from it.
 
You need to keep the old states and test them against the current states.

Something like,
Code:
Again	movfw	GateState	;get state
	movwf	OldState	;keep copy
	clrf	GateState
	btfsc	PORTB,A		;A covered?
	bsf	GateState,0	;yes, set bit
	btfsc	PORTB,B		;B covered?
	bsf	GateState,1
	movfw	GateState	;get new state
	xorwf	OldState,[COLOR="Red"]W[/COLOR]	;cmp old state [COLOR="red"]edited[/COLOR]
	btfsc	STATUS,Z	;same
	goto	Again		;yes, do nothing

; state has changed.

	movfw	OldState	;check the states and
	xorlw	b'10'		;inc/dec as appropriate
	btfss	STATUS,Z
	goto	NoIncrement
	movfw	GateState
	xorlw	b'11'
	btfss	STATUS,Z
	goto	NoIncrement
	incf	Count,F
	goto	Again

NoIncrement
	movfw	OldState
	xorlw	b'11'
	btfss	STATUS,Z
	goto	NoDecrement
	movfw	GateState
	xorlw	b'10'
	btfss	STATUS,Z
	goto	NoDecrement
	decf	Count,F
	goto	Again

NoDecrement
	goto	Again

Edit, I spotted a mistake.

Mike.
 
Last edited:
OMG What a piece of code.A backup up routine never came to my mind.Thats the only way to do.Thanks for the superb coding Mike.
 
I made a mistake in the above code and so I have edited it.

Let us know if it works.

Mike.
 
If you look at kcriste's sequence then when it goes from 10 to 11 it is going left to right. So, b'10' is correct.

Mike.
 
Yes that is right, but we are setting the "0" bit of the gatstate register when some one cross the A sensor.So the compare value will be '01'.

It will be all right by changing these bits according to the direction.So no problem.

Thanks
 
Just wanted to mention another method for determining direction is to exclusive-or the current A or B bit with the opposite bit from the old reading. It opens the door to some interesting coding options.

Here's an example which I believe may be similar in function to what you're trying to accomplish.

Have fun guys. Mike

Code:
;
;  check the Rotary Encoder A and B switches (bits 0 and 1 in
;  the debounced SWDAT2 variable) for a change
;
ISR_Encoder
        movf    SWDAT2,W        ; load switch data                |B0
        andlw   b'00000011'     ; mask encoder B and A switches   |B0
        xorwf   ENCOLD,W        ; same as last reading?           |B0
        bz      ISR_Next        ; yes, branch (no change), else   |B0
        xorwf   ENCOLD,W        ; restore encoder bits in W       |B0
        rrf     ENCOLD,f        ; prep for B-old ^ A-new          |B0
        xorwf   ENCOLD,f        ; ENCOLD bit 0 = direction        |B0
        rrf     ENCOLD,f        ; now Carry bit = direction       |B0
        movwf   ENCOLD          ; update ENCOLD (new BA bits)     |B0
;
;  encoder position has changed but we only act on a change
;  that occurs when the encoder falls into one of the detent
;  positions (we ignore the changes between detents)
;
        xorlw   b'00000011'     ; detent position (BA = 11)?      |B0
        bnz     ISR_Next        ; no, branch, else                |B0
;
;  set encoder pseudo 'DEC' or 'INC' switch bits in the SWITCH2
;  variable based on the Carry bit for Main program processing
;
 
Last edited:
this is a classic application of a finite state machine. put all the logic into a 2 dimensional table with one dimension as the current state and the other as the sensor values. the code is tiny - a simple loop that gets input and uses it plus the current state to determine the new state. then you take actions (inc/dec) based on the new state.

you will probably want to track the progress of a person through the sensors so don't just look for one transition but rather a sequence. the FSM makes that trivial to do. for example you want to see 00 to 01 to 11 to 10 to 00 to count an entrance. that would be accomplished with 4 states. Start in the idle state (00 sensor input), when you see 01 while in the idle state, move to state 1. when you see 11 in state 1, you move to state 2 and so on until you move from state 3 to state 4 which is the completion of the person moving past the sensors. Similar for the other direction.

the beauty of the FSM is you can take action on any sequence of sensor values so you can catch the person that moves into the doorway and then goes pack the way they came.
 
Last edited:
Suraj143 said:
Exactly I'm counting people.

The problem is when a person enters to A sensor & if he goes again outside without crossing B sensor the value will be jammed thats the problem I get.Any method to detect accurately?

There is another potentially confounding factor. Assuming the passage way is wide enough for a person to turn around and leave again, is it also wide enough for 2 (or more) people to enter from the same side or opposite sides at about the same time (call it "concordance"). Each of those situations could change the on-off pattern and disrupt the counts.

How accurate do your counts need to be? You may want to add a reset after a given period, set a maximum time between state changes, or use some other method to account for concordance. John
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…