Optoswitch as rev counter

Jolie Brise

New Member
I built a basic circuit sucessfully using a slotted disc sinking a red led and sourcing a green led from pin1 to check it was working.

Code:
do
        if pin4 = 1 then high 1
   elseif pin 4 = 0 then low 1
   endif
loop
I now want to add a counter on pin2. Tried simple b0 = b0 + 1 but it did not work. So I put an orange led on pin2 to check if it was going high when pin1 went high.



Code:
do
        if pin 4 = 1 then high 1,2
   elseif pin4 = 0 then low 1
   endif
loop

This did not work. 
I tried changing the code by adding elseif pin4 = 1 then high 2
All leds on when loading the programme. Both red and green on permanently.

How do I get output pin2 to go high when input pin4 goes high.

Tony
 

Andrew Cowan

Senior Member
The only way both red and green can be on is if pin 1 is tristated - ie not set as an output.

The code:
Code:
do
if pin 4 = 1 then
  high 1,2
else
  low 1,2
endif
Should work without any problems - can you explain exactly what happens when you run it?

A
loop
 

eclectic

Moderator
I've used an AXE091.
Built the circuit as shown in post #1. (LED reversed)

In place of the opto, I simply used a switch

Program
Code:
#picaxe 08M

symbol counter = W0
counter = 0

do
if pin4 = 1 then 
high 1,2
counter = counter + 1
 sertxd (#counter, "  ")

endif

if pin4 = 0 then
 low 1,2 
endif

loop
It works.
It also looks OK in simulation.

e
 

inglewoodpete

Senior Member
3 questions to the OP:

When the IR path is blocked, does the PICAXE detect it?

If so, if the shaft is turned really slowly, does the PICAXE detect it?

In either case, using a multimeter across the optoswitch output and ground, what voltages do you read?
 

Dippy

Moderator
Absolutley.

Test your hardware before spending hours fiddling with code ... and then find the Photo-T isn't behaving as expected. Be ordered in your testing.

A photo-t can saturate quite easily and very often (esp in high ambient light) the device will need shrouding so that it only 'sees' your source.

I prefer to have the photo-t acting as a low side switch but that's my preference as it can often give a better response.

So, test number 1 is IP's last sentence.
REMEMBER the PICaxe input high/low threshold voltages... they're in Manual 1 and there is some extra information. You'll have to look for yourself.:eek:
 

Jolie Brise

New Member
Thanks for info.

My fault lay with a faulty Problock track. Tried moving inputs/outputs, swapping components, no sucess until I moved the leds over one row. Lack of coding confidence.

I am using IR optoswitches KTIR0611S as they are not effected by ambient light and the 1mm slotted card disc does not have to be tight in the slot. The voltage across input pin/ground was 4.10/0.07v. Supply 4.23v. Works at very slow speeds. Slots 2mm wide, may be too wide, will experiment, my speed is 70rpm.

Top led wrong, I flipped the bottom image.

I am using 08m,
my count code is below, does not work as it is php logic not picaxe.
Working on the principle of adding 1 to variable b0 each time it loops through Main until it reaches 10 x pin3 highs then turns pin2 high.

Code:
init:	b0 = 0
main:
	        if pin3 = 1 then high 1
	    elseif pin3 = 0 then low 1
	     endif
	    
	        if pin3 = 1 then let b0 = b0 + 1
	    elseif b0<10  then low 2			;less than 10 
	    elseif b0=>10 then high 2			;equal and more than 10
	     endif
goto main
Below is part of Electic's code

Code:
[COLOR="Red"]symbol counter = W0
counter = 0[/COLOR]
do
if pin4 = 1 then 
high 1,2
counter = counter + 1
[COLOR="Green"] sertxd (#counter, "  ")[/COLOR]
The first two line could be written as W0 = 0 what is the reason for this code?
What is the function of sertxt line as it has no influence on the code?

Tony
 
Last edited:

eclectic

Moderator
Below is part of Electic's code

snipped

The first two line could be written as W0 = 0 what is the reason for this code?
What is the function of sertxt line as it has no influence on the code?

Tony
1. "Counter" seems logical. W0 could be anything.

2. So that the "Counter" result can be seen during testing. :)

e
 

Attachments

hippy

Technical Support
Staff member
symbol counter = W0
counter = 0

The first two line could be written as W0 = 0 what is the reason for this code?
You could use 'w0', any other variable or any name in the SYMBOL definition. The advantage of using a name is that it lets other people reading your code get a good idea of what the variables are used for and what the code may be doing without having to fully understand it.

For example, trying to work out what the following means -

L001:
w0 = w1 * 2 / 100
w1 = w1 + w0 + w7
Return

Is much harder than when you are given labels and variables meaningful names -

AddPayCheque:
interest = bankbalance * 2 / 100
bankbalance = bankbalance + interest + paid
Return
 

eclectic

Moderator
@Tony
From post #9
I am using 08m,
my count code is below, does not work as it is php logic not picaxe.
Working on the principle of adding 1 to variable b0 each time it loops through Main until it reaches 10 x pin3 highs then turns pin2 high.

Code:
init:	b0 = 0
main:
	        if pin3 = 1 then high 1
	    elseif pin3 = 0 then low 1
	     endif
	    
	        if pin3 = 1 then let b0 = b0 + 1
	    elseif b0<10  then low 2			;less than 10 
	    elseif b0=>10 then high 2			;equal and more than 10
	     endif
goto main
It does work, as is,
but leaves output 2 high.

I've tried the following modifications
Code:
;http://www.picaxeforum.co.uk/newreply.php?do=postreply&t=18490

#picaxe 08m

dirs = %00010111
 
 symbol Tencount = b0
 symbol counter = W1

;All variables initialised to 0 on startup
 
main:
         pin1 = pin3 ; high = high / Low = Low
     
         if pin3 = 1 then let tencount = tencount + 1         
                
         endif
     
     If tencount = 10 then 
     high 2 
     pause 500 ;just for testing
     low 2
     
     counter = counter + 1
     tencount = 0     
       
     endif
      
      Sertxd (#tencount ," ", #counter,cr,lf) ; for checking
      
goto main
It's not meant to be an exemplar,
but may help.

e
 

Jolie Brise

New Member
Eclectic.
Tried your code, output 2 comes on at the same time as output 1 but flashes.
Sertxd gave a stream of numbers which, to me, are meaningless.

I want the shaft to rotate 10 slots then output 2 go on permanently.



My code below does not work
At start
Power off
input 3 low (Gap blocked)
output 1 off
output 2 off

Power on, both outputs off

Move slotted disc until input 3 goes High
Both outputs 1,2 go high

Move dics until input 3 goes low.
Output 1 goes low
Output 2 remains permanemtly on.

Code:
#picaxe 08M

init:
	symbol counter = W0
		 counter = 0

do
     if pin3 = 1 then high 1
       counter = counter + 1
  endif  
      
     if counter =>10 then high 2
       
         sertxd (#counter, "  ")
  endif

     if pin3 = 0 then low 1 
  endif
  
loop
Hippy, take your point about symbols. In PHP you name your own variables $count = 1
 
Last edited:

hwholmes

Member
I want the shaft to rotate 10 slots then output 2 go on permanently.
I think you might not be seeing the light as an edge but just as a switch.
When the light get through the counter starts incrimenting and is greater than 10 in microseconds.

Try using a sample variable to determine if the input is different from the immediate past or not.

The following is pseudo code not true basic.

init:
past = input

do
sample = input
if sample is true and (sample is not equal to past)
then incriment counter
if counter >= 10 then turn on output endif
endif
past = sample
loop
 
Last edited:

Dippy

Moderator
I think hwh has hit nail on head.

You can compare your code with pressing buttons.

DippyCode.

Is buttonpressed?
If so, sit in loop until button released...
Is button released?
Do whatever and move on.

PS. With the X2 you would be able to do edge triggered interrupts...
 

Jolie Brise

New Member
Too complicated

Lets go back to #08m basic principles.

Switch as input on pin3 and led as output on pin1

Count five switching on/off then output goes and remains high. This high will be linked to another 08m allowing a function to occur.



This counts the high/low as one pulse. I have tried different codes without success based on my previous modules. 1 pulse = 70ms

Tony
 

inglewoodpete

Senior Member
Forgive any ignorance on my part but have you tried either using the PulsIn or Count commands?

Using discrete code in a small (Ie slower) PICAXE for something like a rotating shaft is fraught with the problems that you are encountering.
 

hippy

Technical Support
Staff member


I can't see anything fundamentally wrong with the concept so if it doesn't work the question must be, in what way does it not work for you, what doesn't happen or what does happen which isn't expected ?

I'm not sure what's driving pin 3 input but have you tried replacing whatever that is with a push button switch to +V and a pull-down 10K to 0V ?

The most likely problem could come from switch bounce, each push or release appearing as multiple on and off signals in fast succession. Adding PAUSE's after each test of pin 3 level will help with that.
 

joliebrise

New Member
Count and Pulsin both count pulses in a specified time. The period of time switching is random.
The input is a switch as mention.
I previously constructed and tested the switch bounce at Manual 3 pg 27

For .. next loops through a number of times then exits. I want continuous counting.

Code:
	let b0 = 0
main:
      if pin3 = 0 then main
      if pin3 = 1 then    
	pause 300
      let b0 = b0 + 1
        if b0 < 5 then main
          high 1
        endif
     goto main

Switch on, output goes high after the pause.

The problem, I see,  is latching the input so it is only read once, not continually the input is high.
How do you do this?

Tony
 

Dippy

Moderator
Your code example isn't like your flow so I'm worried I have misunderstood.

How about something along the lines of...

Code:
MyMain:
b0=0      ' Reset/clear b0 value
do
   do
   loop while pin3=0   ' Sit here while pin3=0
   do
   loop until pin3=1   ' Sit here while pin=1 (TR on period)
   inc b0    ' increment b0
loop while b0<5    ' Do this until b0 = 5
high 1
' ??? for some time period??? unclear...
pause 500     ' for testing
low 1
goto MyMain
If I have wrong end of stich then GOTO OOPS....
But at least it'll get you started (I hope??) ;)

PS. you can do a similar thing for push-button switches. If you stick a small delay in the spin3=1 loop that gives a meagre debounce function.

Have you determined ABSOLUTELY that your circuit provides true High/Low (1/0 or True/False) to the input pin. It has been mentioned several times with no definitive reply. ALWAYS, ALWAYS check your hardware is working properly BEFORE fannying around with code ;)
 

hippy

Technical Support
Staff member
The problem, I see, is latching the input so it is only read once, not continually the input is high.
How do you do this?
I don't really understand the question, how you mean by only reading the input once ?

The flow of the code is such that it does not progress until high, does not progress until low, does not progress until high again and so on. That's what you have in your flowchart and what you appear to have implemented in your code ( though it's slightly different to the flowchart ).
 

Dippy

Moderator
My assumption.
His code doesn't really check the input has toggled off again, so I assume he means that he keeps reading and incrmenting.
Thats why I gave the snippet on the previous page.

If I've got that wrong then he needs to clarify, but he MUST check his hardware first otherwise all our time writing code is wasted :(
 

hippy

Technical Support
Staff member
Thanks Dippy. Posted at same time and missed your code over the page.

You're right, the code is more different to the flowchart than I realised, will continually increment b0, hit 5 almost immediately, and there's the problem ... probably. Your code example should work - and saves me typing what I would have used as well !

There's a moral there for testing in simulation.
 

eclectic

Moderator
Just to make absolutely sure,

The circuit in post #13 shows Pin4 ("Leg" 3) as input.

The code in post #19 shows Pin3 as input.

Is there a typo somewhere?

Code:
let b0 = 0
main:
if pin3 = 0 then main
if pin3 = 1 then 
pause 300
let b0 = b0 + 1
if b0 < 5 then main
high 1
endif
goto main
e
 

Attachments

joliebrise

New Member
Eclectic
Simplified the circuit to reduce room for errors.



Used Dippy's code and added the switch bounce routine at the start.
This is now as the flowchart with input being held high until it goes low triggering the count increment.
My thoughts are that as the count increment is being done when the input goes low there is not need for the switch bounce routine.

Anyway, it does nothing. Circuit checked with meter.
Chip voltage at switch on are +4.33/0/0/4.33//0/0/0/-ve All at zero at off.

Code:
      symbol bounce = b0	;define bounce variable
      symbol counter = b1	;define count variable
	bounce  = 0
	counter = 0
bound:
         if pin3 = 1 then add       ;goto bounce routine
         if pin3 = 0 then bound    ;waits for input high
add:
         pause 100
         let bounce = bounce + 1
         if bounce < 5 then bound

counting:
         do
          loop while pin3 = 1	' Sit here while pin3 is high
   	
   	   pin3 = 0    		' pin3 going low triggers counting
            inc counter		' increment by +1
             goto counting		' loop back waiting for the next high/low
             		
	   if counter>5 then 	' check for condition counter higher than 5
	    do
	     loop while pin1 = 1	' pin1 goes permanently high
	   endif
 

Piers

New Member
Hi Tony,

apologies if I'm off the mark here, but does this do what you want..? If not, I'll go back to my nap.

Code:
	symbol bounce = b0		;define bounce variable
	symbol counter = b1		;define count variable
	bounce  = 0
	counter = 0

bound:
	if pin3 = 1 then add       	;goto bounce routine
	if pin3 = 0 then bound    	;waits for input high

add:
	pause 100
	let bounce = bounce + 1
	if bounce < 5 then bound

counting:
	do
		loop while pin3 = 1	' Sit here while pin3 is high
	inc counter				' increment by +1
	if counter>5 then 		' check for condition counter higher than 5
		high 1
	endif	
	goto counting			' loop back waiting for the next high/low
It's basically your last code snippet with the counting section modded slightly. Reason it wasn't switching the output is that it was looping back at the goto counting and never getting as far as checking the value of counter

Piers
 
Last edited:

Dippy

Moderator
I'm confused by your code....:confused:

You do an IF pin3 and the next line you say
pin3 = 0 ' pin3 going low triggers counting
eh?

In your very first post, did your very first bit of code work?

In your last snippet is something missing? It doesn't look right and it looks a bit lacking structure.
 

joliebrise

New Member
Piers, thanks for the code mods, this is the result

Input low at power on. Output low
When input goes high, output remains low
When input goes low, output goes high and remains high

Input high at power on, output low
When input goes low output goes high and remains high

It is not counting 5 high/low pulses before output going high.

The objective of this module is to do 5 on/off switching then output goes high and remains high.

The application is to count 7 shaft revolutions before turning off the motor. The motor carries on turnig for half a turn before stopping. The counter has carry on counting as when the motor is reversed it has to go back to zero count to get back to its original position. The reverse rotation is another story but lets get to that when we can count in the forwards direction first.

An IR optoswitch works with a 12 slot disc ie 84 pulses before turning motor off. The disc can be left stationary with high or low input for 30mins +
So to initiate the count the input must be high or go high before going low to trigger the count.

Nothing has worked to solve the problem. The initial coding was made too complex as I was trying to do too much, hence reducing it down to a switch and led.

Is there a totally different solution to this problem?
 
Last edited:

Piers

New Member
Tony,

ah understand now I think...

Try this...
Code:
	symbol bounce = b0		;define bounce variable
	symbol counter = b1		;define count variable
	bounce  = 0
	counter = 0

bound:
	if pin3 = 1 then add       	;goto bounce routine
	if pin3 = 0 then bound    	;waits for input high

add:
	pause 100
	let bounce = bounce + 1
	if bounce < 5 then bound

counting:
	do
		loop while pin3 = 1	' Sit here while pin3 is high
	inc counter				' increment by +1
	if counter>5 then 		' check for condition counter higher than 5
		high 1
	endif
	do
		loop while pin3 = 0	' Sit here while pin3 is low	
	goto counting			' loop back waiting for the next high/low
Piers
 
Last edited:

techElder

Well-known member
Initialization is important

I see where you initialize bounce and counter to zero when first run, but I don't see any initialization of these two variables after you start incrementing. That's important because you are comparing them to constants in your loops.
 

Dippy

Moderator
...and

Piers, your 'counting: / goto counting' loop looks like a long winded version of my snippet I gave...?

"The objective of this module is to do 5 on/off switching then output goes high and remains high."
Do you mean:
"The objective of this module is to DETECT 5 on/off from opto-switch then output goes high and remains high."

How does this relate to:
"The application is to count 7 shaft revolutions before turning off the motor."
and
"An IR optoswitch works with a 12 slot disc ie 84 pulses before turning motor off."
??
I realise that 12x7 = 84 but where does the "5" come into it?

Don't you need to count 84 then switch-off but carry on counting so that you know where you are?


I'm sure you'll get this sorted once you have sorted your flow. Good luck.
 

joliebrise

New Member
The solution

Piers.

I works as it says on the tin. Thanks you and all the others who have helped.

I have written it up on my website with an explanation of how it works.

6 Switch pulse counter

Now to get this working on the prototype winch to see if the slots on the disc are the correct size.

Then onto the next coding which is to sense the direction of shaft rotation. I will post it as "Input shaft direction" as I am sure I will need your help.
It's gratifying to sense the knowledge gain in such a short time all with your help.

Thanks to you all
Tony
 

Dippy

Moderator
Well done to us then :)
Your webpage link.
It might be nice to acknowledge the Forum who, after all, supplied the solution.....


"Input shaft direction"
- all this sort of stuff has been done for years.
Why not do some research (i.e. Googling) on nerdynet? There must be hundreds of documents on rotation sensing/direction/position.
If you get to grips with the basics of encoders/techniques then perhaps we can deal with the 'finishing touches' here.
Or, are you 'getting us ready'? ;)

Tom2000 did some great work on encoder wheels and produced a really nice App. for DIY encoders.
 
Top