PDA

View Full Version : Counter not counting !!!



lerameur
- 18th February 2009, 03:03
Hello,

I made a small disk counter with (wheel encoder with 2 part black and 2 part white) about 2 inches in diameter. I use a light to voltage sensor. It is working pretty well at low speed, but when I flick the disk, o Maybe a few turns per seconds the counter only counts one out of the 5 turns it made. My guess is that the clocking should be made higher.. any ideas?, The whole circuit is already soldered, I hope i do not need to get it in a 20Mhz crystal.
here is the code:

' Internal Oscillation program
' A/D testing -RA.1
' LCD

'/////////////////////////
'// Define section //
'/////////////////////////

INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
@ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_ON
OSCCON=$60 ' use internal 4MHZ osc

CMCON = 7 ' Turn OFF the comparators so pins can be used as digital I/O-pins


'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 0 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 1000


'/////////////////////////
'// PIN configuration //
'/////////////////////////

TRISA = %11100111 ' Set PORTA to all input
TRISB = %00001100 ' Set PORTB to all output
PortA = 0

'///////////////////////////////////////////////
'// Variable Declaration and initialization //
'///////////////////////////////////////////////
Output_Pot var byte
OldOutput_Pot var byte
Revolution var word
counter var byte

revolution = 0
Output_Pot = 0
OldOutput_Pot = 0
counter = 0

OldOutput_Pot = PortB.3

Mainloop:

'Calculate the distance
Output_Pot = PortB.3

if OldOutput_Pot == Output_Pot then
goto Mainloop
endif
if OldOutput_Pot != Output_Pot then
counter = counter +1 'If oldOutput_pot is different then Output_pot
OldOutput_Pot = Output_Pot
if counter =4 then
Revolution = Revolution + 1
counter =0
endif
endif

lcdout $FE,1, "Counter:",dec counter
lcdout $FE,$C0, "Revolution:",dec Revolution
pause 150


GOTO Mainloop
end

Jerson
- 18th February 2009, 03:19
Time to consider using interrupts for this. Increment within the interrupt. Keep it small and fast!! I don't recall if the 88 has interrupts on portB.3

lerameur
- 18th February 2009, 03:26
interrupt ... ok Guess I have to read up now.

jderson
- 18th February 2009, 04:53
I would suspect the "light-to-voltage sensor". Most of these have response times in the millisecond range, maybe too slow.

lerameur
- 18th February 2009, 04:55
I am not sure how interrupt can help in this case.
At slow speed the counter works, but at higher speeds it does not pick half the time or more.
I reduced the pause time to 20 after the LCDout, that did not help.

K

Archangel
- 18th February 2009, 06:15
Hi lerameur,
I would use a photo transistor and not a photocell, a Crystal or resonator running at 20 mhz rather than intosc @ 4mhz. those things might speed things up a bit. You might use interrupts to capture counts and display on an as time permits basis instead of watching every count.

lerameur
- 18th February 2009, 06:33
Hi,

I am using this little baby for a sensor
http://www.taosinc.com/productdetail.aspx?product=63

I think i will user TMR0 in my program

K

Archangel
- 18th February 2009, 07:06
I was thinking . . . make a subroutine called display and do this:
if OldOutput_Pot == Output_Pot then
gosub display
then do your lcd routines in there, it would display any time the counter stops incrementing.

Jerson
- 18th February 2009, 08:00
Well, the reason for suggesting an interrupt is simple. When you poll, you spend a finite time in checking the state of the input. If you miss this(fast revolutions), you will miss counts. However, if you use interrupts, you can be sure to catch a significantly higher number of pulses than you could using the poll technique. example - you may be able to read upto 20pulses per second using the poll techniqe, but upto 200 pulses per second or even more using interrupts.

Simple analogy to understand the difference between interrupts and polling.
Think of yourself seated at the PC doing some work. The time you take to respond to a person at the door is your 'poll time' and depends on what you are doing at the moment and how soon it will finish. This would be similar to checking every now and then to see if there is someone at the door.

On the contrary, if the person rings a doorbell (interrupts). You know that the door needs to be opened because of this signal. The way the processor handles it is to finish the current 'instruction' that it is executing and respond to the bell. This is much much faster than the earlier technique of checking the door now and then.

Please don't mind the over-simplification. It might help someone else understand.

I also second the idea that the opto interrupter may not be fast enough. But, from my experience, they work well into the KHz range.

I suggest your Main loop should just display the counts and the interrupt routine should just count.

lerameur
- 19th February 2009, 04:06
Hi,

Ok I added an interrupt and wrote the program from what you said. Althouth I get zero on the LCD, seems that the interrupt is not working, can you help me debug it? Do I need to initialize some parameter . I am using the pic16f88
Ken


' Internal Oscillation program
' LCD
' Main loop display the counts and the interrupt routine counts

'/////////////////////////
'// Define section //
'/////////////////////////

INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
@ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_ON
OSCCON=$60 ' use internal 4MHZ osc

CMCON = 7 ' Turn OFF the comparators so pins can be used as digital I/O-pins

'///////////////////////////
'// Interrupt section //
'///////////////////////////
OPTION_REG = %00111000
'Transition on TOCKI (RA4),
'Increment on falling edge
'Prescalar assigned to WDT for a 1:1 TMR0 ratio.
INTCON.2 = 0 ' Clear Timer0 int flag
INTCON.5 = 1 ' Enable Timer0 int
TMR0 = $FF ' Set TMR0 to 255. So one more tick and TMROIF will be set.

'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 0 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 1000


'/////////////////////////
'// PIN configuration //
'/////////////////////////

TRISA = %11110111 ' Set PORTA to all input
' Set PORTA.4 (TOCKI) to input for timer0
TRISB = %00001111 ' Set PORTB to all output
PortA = 0

'///////////////////////////////////////////////
'// Variable Declaration and initialization //
'///////////////////////////////////////////////

Revolution var word
Counter var word
oldCounter var word
feet var word
feet_left var word
feet_right var word

revolution = 0
Counter = 0
feet = 0
PortB.2 = 1 'Put to 5v via a resistor and a pushbutton to ground for reset

ON INTERRUPT GOTO LapCount

Mainloop:
if PortB.2 = 0 then
goto Reset_variables
endif

lcdout $FE,1, "Cter:",dec Counter, " Rev:",dec Revolution
lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12 'This will save feet, and the // will print the decimal to two decimal point
pause 20
GOTO Mainloop

Reset_variables:
revolution = 0
Counter = 0
feet= 0
lcdout $FE,1, "Counter:",dec Counter , " Rev:",dec Revolution
lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12
pause 20

GOTO Mainloop

disable
LapCount:
If INTCON.2 = 1 then
Counter = Counter + 1
endif
toggle PORTB.3
TMR0 = $FF ' Indicate we're in interrupt handler
INTCON.2 = 0 ' Clear TMR0 Interrupt Flag (Bit 2)

'Calculate the distance

if Counter =4 then
Revolution = Revolution + 1
Counter =0
endif

feet_left = Revolution *3
feet_right = Revolution *25
feet_right = feet_right / 100
feet= feet_left +feet_right

Resume
Enable
end

lerameur
- 19th February 2009, 04:21
by the way I connected the sensor to portA.4
ken

Archangel
- 19th February 2009, 08:38
Hi,

Ok I added an interrupt and wrote the program from what you said. Althouth I get zero on the LCD, seems that the interrupt is not working, can you help me debug it? Do I need to initialize some parameter . I am using the pic16f88
Ken


' Internal Oscillation program
' LCD
' Main loop display the counts and the interrupt routine counts

'/////////////////////////
'// Define section //
'/////////////////////////

INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
@ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_ON
OSCCON=$60 ' use internal 4MHZ osc

CMCON = 7 ' Turn OFF the comparators so pins can be used as digital I/O-pins

'///////////////////////////
'// Interrupt section //
'///////////////////////////
OPTION_REG = %00111000
'Transition on TOCKI (RA4),
'Increment on falling edge
'Prescalar assigned to WDT for a 1:1 TMR0 ratio.
INTCON.2 = 0 ' Clear Timer0 int flag
INTCON.5 = 1 ' Enable Timer0 int
TMR0 = $FF ' Set TMR0 to 255. So one more tick and TMROIF will be set.

'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 0 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 1000


'/////////////////////////
'// PIN configuration //
'/////////////////////////

TRISA = %11110111 ' Set PORTA to all input
' Set PORTA.4 (TOCKI) to input for timer0
TRISB = %00001111 ' Set PORTB to all output
PortA = 0

'///////////////////////////////////////////////
'// Variable Declaration and initialization //
'///////////////////////////////////////////////

Revolution var word
Counter var word
oldCounter var word
feet var word
feet_left var word
feet_right var word

revolution = 0
Counter = 0
feet = 0
PortB.2 = 1 'Put to 5v via a resistor and a pushbutton to ground for reset

ON INTERRUPT GOTO LapCount

Mainloop:
if PortB.2 = 0 then
goto Reset_variables
endif

lcdout $FE,1, "Cter:",dec Counter, " Rev:",dec Revolution
lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12 'This will save feet, and the // will print the decimal to two decimal point
pause 20
GOTO Mainloop

Reset_variables:
revolution = 0
Counter = 0
feet= 0
lcdout $FE,1, "Counter:",dec Counter , " Rev:",dec Revolution
lcdout $FE,$C0, "Feet:",dec feet/12, ".", dec2 feet//12
pause 20

GOTO Mainloop

disable
LapCount:
If INTCON.2 = 1 then
Counter = Counter + 1
endif
toggle PORTB.3
TMR0 = $FF ' Indicate we're in interrupt handler
INTCON.2 = 0 ' Clear TMR0 Interrupt Flag (Bit 2)

'Calculate the distance

if Counter =4 then
Revolution = Revolution + 1
Counter =0
endif

feet_left = Revolution *3
feet_right = Revolution *25
feet_right = feet_right / 100
feet= feet_left +feet_right

Resume
Enable
end


TRISA = %11110111 ' Set PORTA to all input
<font color=red> PortA.3 as output</font color>
' Set PORTA.4 (TOCKI) to input for timer0
TRISB = %00001111 ' Set PORTB to all output
<font color=red> PortB.0:3 as inputs</font color>
PortA = 0

For starters, check this to see if it is what you really want.
PortA.4 is Schmitt Trigger input so a pulldown resistor as shown in the opto's datasheet will be a necessity, it says it outputs min 3.0v so it should swing the S T input OK. The 16F88 has a ton of analog you need to attend to if you want to use it, I am not seeing any code to do that.

lerameur
- 19th February 2009, 18:28
Hi,

the hardware seems good, like I said it works at slow speed. In my case I have to use port RA4 right? to get the timer0 from my program.
I looked through the datasheet and nowhere there is mention on how to disable the schmitt trigger.

ken

Acetronics2
- 19th February 2009, 19:13
Hi, Ken

IF you want your Thing to work properly ...

You HAVE to use QUICK Interrupts and not " On Interrupt" ... especially if using a LCD.

So, Have a look to asm interrupts or Darrel Instant Interrupts ...

Alain

Bruce
- 20th February 2009, 01:23
Why not just let hardware handle most all of this for you?


' include your hardware/config stuff here

Revs VAR BYTE ' holds up to 255 revolutions
ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators
OPTION_REG = %00110001 ' RA4 = count input
' inc count every 4th falling edge with 1:4 prescale
' assigned to TMR0

Mainloop:
TMR0 = 0 ' clear count before pause
PAUSE 20 ' Adjust this to set how long it counts revolutions here
Revs = TMR0 ' TMR0 counts 1 rev for every 4 pulses
LCDOUT $FE,1,"Revs: ",DEC Revs

' do other stuff here, then return to get more counts
GOTO Mainloop
This will be a LOT faster than interrupting on every single pulse, and counting
in software. You should be able to give the wheel a pretty good spin without
missing anything.

lerameur
- 20th February 2009, 14:10
HI, I am not able to make this code work, always leaves me with ORevs = 1 on the LCD.
I also change the oscillation to 20 Mhz but did not see any difference.
ken



' Internal Oscillation program
' LCD
' Main loop display the counts and the interrupt routine counts

'/////////////////////////
'// Define section //
'/////////////////////////

INCLUDE "modedefs.bas" 'Includes supoprt for PicBasic language
@ DEVICE pic16F88, INTRC_OSC, MCLR_ON
OSCCON=$60 ' use internal 4MHZ osc
ANSEL = 0 : ADCON1 = 7
CCP1CON = 0 'CCP1 module off


'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 0 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 1000


'/////////////////////////
'// PIN configuration //
'/////////////////////////

TRISA = %11111111 ' Set PORTA.4 (TOCKI) to input for timer0
TRISB = %00001111 ' Set PORTB
PortA = 0

'///////////////////////////////////////////////
'// Variable Declaration and initialization //
'///////////////////////////////////////////////

Revs var word
ORevs var word

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators
OPTION_REG = %00110001 ' RA4 = count input
' inc count every 4th falling edge with 1:4 prescale
' assigned to TMR0

Mainloop:
TMR0 = 0 ' clear count before pause
PAUSE 20 ' Adjust this to set how long it counts revolutions here
Revs = TMR0 ' TMR0 counts 1 rev for every 4 pulses
ORevs = Revs +1
LCDOUT $FE,1,"ORevs: ",DEC ORevs

GOTO Mainloop
end

Bruce
- 20th February 2009, 15:28
As Joe already mentioned earlier, RA4 T0CKI is a Schmitt Trigger input. If your sensor doesn't output a minimum voltage of 0.8 * VDD for logic 1 and 0.2 * VDD or less for logic 0, then the Schmitt Trigger input isn't seeing the correct logic levels, and TMR0 isn't counting your pulses.

Here's a quick little test program to show how it works when RA4/T0CKI is connected to an I/O-pin to increment the counter.


@ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_OFF

DEFINE HSER_BAUD 2400

Loops VAR BYTE
Revs var BYTE

OSCCON=$60 ' use internal 4MHZ osc

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators

TRISA.4=1 ' RA4/T0CKI = input (Timer0 clock input)
PORTB.5=1 ' USART TX pin idles high
PORTB.0=1 ' clock output pin to RA4 starts high
TRISB.0=0 ' clock out pin to RA4/T0CKI = output
TRISB.5=0 ' USART TX = output

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators
OPTION_REG = %10110001 ' clk on RA4/T0CKI, falling edge, 1:4 prescale

Mainloop:
TMR0 = 0 ' clear count before each pass

' output 8 clocks on RB0 to RA4/T0CKI
FOR Loops = 0 TO 7
PORTB.0=1 ' RB0 connects to RA4/T0CKI
PAUSE 5
PORTB.0=0 ' counter increments on falling edge
PAUSE 5
NEXT Loops

Revs = TMR0 ' get TMR0 count
IF OPTION_REG.0 THEN
HSEROUT ["Counts at 1:4 prescale: ",dec Revs,13,10]
ELSE
HSEROUT ["Counts at 1:2 prescale: ",dec Revs,13,10]
ENDIF
OPTION_REG.0 = OPTION_REG.0 ^ 1 ' toggle 1:4 or 1:2 prescale
GOTO Mainloop

end

It works great, but only as long as the input signal meets the threshold levels the Schmitt Trigger input buffer on RA4/T0CKI expects.

Archangel
- 20th February 2009, 16:47
As Joe already mentioned earlier, RA4 T0CKI is a Schmitt Trigger input. If your sensor doesn't output a minimum voltage of 0.8 * VDD for logic 1 and 0.2 * VDD or less for logic 0, then the Schmitt Trigger input isn't seeing the correct logic levels, and TMR0 isn't counting your pulses.

Here's a quick little test program to show how it works when RA4/T0CKI is connected to an I/O-pin to increment the counter.


@ DEVICE pic16F88, INTRC_OSC, CCPMX_ON, MCLR_OFF

DEFINE HSER_BAUD 2400

Loops VAR BYTE
Revs var BYTE

OSCCON=$60 ' use internal 4MHZ osc

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators

TRISA.4=1 ' RA4/T0CKI = input (Timer0 clock input)
PORTB.5=1 ' USART TX pin idles high
PORTB.0=1 ' clock output pin to RA4 starts high
TRISB.0=0 ' clock out pin to RA4/T0CKI = output
TRISB.5=0 ' USART TX = output

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators
OPTION_REG = %10110001 ' clk on RA4/T0CKI, falling edge, 1:4 prescale

Mainloop:
TMR0 = 0 ' clear count before each pass

' output 8 clocks on RB0 to RA4/T0CKI
FOR Loops = 0 TO 7
PORTB.0=1 ' RB0 connects to RA4/T0CKI
PAUSE 5
PORTB.0=0 ' counter increments on falling edge
PAUSE 5
NEXT Loops

Revs = TMR0 ' get TMR0 count
IF OPTION_REG.0 THEN
HSEROUT ["Counts at 1:4 prescale: ",dec Revs,13,10]
ELSE
HSEROUT ["Counts at 1:2 prescale: ",dec Revs,13,10]
ENDIF
OPTION_REG.0 = OPTION_REG.0 ^ 1 ' toggle 1:4 or 1:2 prescale
GOTO Mainloop

end

It works great, but only as long as the input signal meets the threshold levels the Schmitt Trigger input buffer on RA4/T0CKI expects.
I learned something again! I thought Schmitt trigger would switch at 3v, so 80 percent huh? I'm going to write that down. Thanks Bruce !

lerameur
- 20th February 2009, 17:14
Hi

well I am only getting about 3volt, so 0.8 * 5v = 4v, one volt away from triggering. I will a simple amplifier or inverter to the output of my sensor and feed that to the chip

ken

lerameur
- 20th February 2009, 21:15
I think I am getting there but just not quite.
your program works with the loop for incrementing. I removed the loop , because I have a sensor output, The output is going through an inverter, so now I get either 0 or 5v going into RA4.
What I now see on the LCD is the incrementation going up high without any look at the input. it goes up to a 1000 in about 3 seconds with the sensor laying there not moving:

Here is the code I have, mainly Bruce,s code with the addition of the LCD and external oscillation.


@ DEVICE pic16F88, CCPMX_ON, MCLR_OFF

DEFINE OSC 20 'use external 20mhz crystal
ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators

TRISA.4=1 ' RA4/T0CKI = input (Timer0 clock input)

ANSEL = 0 ' disable A/D so RA4 is digital
CMCON = 7 ' disable comparators
OPTION_REG = %10110001 ' clk on RA4/T0CKI, falling edge, 1:4 prescale

Revs var BYTE
ORevs var word
Counter var word

'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 0 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits) '4 therefore put wire at 4, 5, 6 and 7 of LCD
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 1000

Counter =0

Mainloop:
TMR0 = 0 ' clear count before each pass

' output 8 clocks on RB0 to RA4/T0CKI
'instead, input from sensor


Revs = TMR0 ' get TMR0 count
Counter = Revs + 1
IF OPTION_REG.0 THEN
LCDOUT $FE,1,"Counter1: ", DEC Counter
ELSE
lcdout $FE,$C0, "Counter2: ", DEC Counter
ENDIF
OPTION_REG.0 = OPTION_REG.0 ^ 1 ' toggle 1:4 or 1:2 prescale
GOTO Mainloop

end

lerameur
- 20th February 2009, 21:32
Hi,

also, I used your program andn it seemed to work but I realized that even if I remove the Loop: (or simply remove the connection between RA4 and RB3)
FOR Loops = 0 TO 7
PORTB.3=1 ' RB0 connects to RA4/T0CKI
PAUSE 5
PORTB.3=0 ' counter increments on falling edge
PAUSE 5
NEXT Loops

the incrementation stays the same change, so I guess there si not effect on TMR0.

K

Bruce
- 20th February 2009, 21:32
Try this;

Mainloop:
TMR0 = 0 ' clear count before each pass
PAUSE 5000 ' give it some time to count pulses
Revs = TMR0 ' get TMR0 count
Counter = Counter + 1
LCDOUT $FE,1,"Counter1: ", DEC Counter
LCDOUT $FE,$C0, "Revs: ", DEC Revs
GOTO Mainloop
Counter of course is always going to change every 5 seconds or so, but Revs shouldn't until you have pulses in on RA4.

Timer0 will automatically count pulses. You don't need to check any regs, bits, etc, just read it & clear it as required.

lerameur
- 20th February 2009, 21:46
I did output the Revs and it increment without any input:
not as fast, takes about 2 seconds to get to ten.
The odd thing is that it increment without changes to RA4.
I am going to try your code you posted and be back later
thanks for your time

Mainloop:
TMR0 = 0 ' clear count before each pass

' output 8 clocks on RB0 to RA4/T0CKI
'instead, input from sensor


Revs = TMR0 ' get TMR0 count
Counter = Revs + 1
IF OPTION_REG.0 THEN
LCDOUT $FE,1,"Revs: ", DEC Revs
ELSE
lcdout $FE,$C0, "Counter2: ", DEC Counter
ENDIF
OPTION_REG.0 = OPTION_REG.0 ^ 1 ' toggle 1:4 or 1:2 prescale

GOTO Mainloop

end

lerameur
- 20th February 2009, 21:59
Hi again

I set my function generator to 100Hz and the Revs outputs 127, when I set it to 1000Hz, I get Revs 225 on my LCD.
I get a specific number to from different frequency input.

Ken

Bruce
- 20th February 2009, 22:15
That's a good sign. Higher frequency should = a higher count in a given time period.

FYI: You really don't need to keep flipping OPTION_REG.0. That was just a part of my
previous example to show the count difference with different prescaler values. I would
leve it set at one prescale if you want valid counts.