# 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

#### gengis

##### New Member
Probably just an error in the drawing - but the red led is reverse biased.

#### marks

##### Senior Member
i think your circuit is the problem try connecting your leds like this!

#### Attachments

• 69.8 KB Views: 68

#### 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.

#### techElder

##### Well-known member
Do you really mean that the circuit worked as shown in the schematic?
... Built the circuit as shown in post #1. (LED reversed).... It works. It also looks OK in simulation.

#### 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

• 39.8 KB Views: 27

#### hippy

##### Ex-Staff (retired)
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 -

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``````

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

##### Ex-Staff (retired)

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

##### Ex-Staff (retired)
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

##### Ex-Staff (retired)
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

• 38.1 KB Views: 22

#### 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
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

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

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

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