PDA

View Full Version : COUNT never counts properly! (16F870)



CuriousOne
- 30th August 2016, 09:12
Hello, I have simple code:



CIKLI:
count portc.3,15, batvolt
if batvolt<>0 then
lcdout $FE, $C0,#BATVOLT, " "
endif
GOTO CIKLI


The input sequence consists of series of pulses, which look like this:

First pulse lasts for 10ms then pause 1.8ms then 2nd pulse 0.8ms then pause 0.6ms and then again pulse 0.8ms
it takes about 15ms all this together

Hardware is 16F870, 4mhz clock. The "COUNT" statements returns any value, from 7 to 33, on each run. Any idea, how to fix?

Dave
- 30th August 2016, 11:59
For starters, There is too much variance between pulses and there is nothing in your code to SYNC the 10 Ms. start pulse with. You are only counting the pulses for 15 Ms. and with no SYNC 1 of the pulses is taking as much as 10 Ms. of the timing gate. I am not understanding the pulse pattern you are trying to decode. If the pulse train only lasts for 15 Ms. before it repeats then you will only ever count approx.9 counts. Am I correct? What in the data stream is changing? The number of pulses or the pulse width?

CuriousOne
- 30th August 2016, 12:05
This is fixed sequence, and I want PBP to return "3", since in 15ms period it gets 3 pulses.

HenrikOlsson
- 30th August 2016, 12:33
How often is this pattern repeating? Constantly?
Count will start counting immediately and then continue to count for 15ms. It won't sit there waiting for the first pulse and THEN count for 15ms.
What if the start of the command occurs in the middle of your 3 pulse sequence? Or in between two of those 3 pulse patterns?

The fact that always seem to get MORE than 3 counts indicates that your pin isn't driven to both states. Verify that you have well defined logic states for both '1' and '0' on the input.

/Henrik.

CuriousOne
- 30th August 2016, 13:51
Above code is launched, when signal on input pin arrives, I just missed that line here.

I discarded the COUNT statement, and wrote software substitute, which accurately counts amount of pulses:



UIDEDA:
if pulsi=1 then
FOR N=0 TO 300 'this is length of capture period, 300 for 16F870 @ 4mhz means approx 15ms.
IF PULSI=1 THEN
A=A+c
c=0
d=1
ELSE
B=B+d
d=0
c=1
ENDIF
NEXT
IF A<>0 AND B<>0 THEN
lcdout $FE,2, "A=",#A, " "
lcdout $FE,$C0,"B=",#B, " "
ENDIF
A=0
B=0
endif
GOTO UIDEDA


I'm interested, why count never works as it should.

Dave
- 30th August 2016, 19:18
Sounds like noise to me.... Try a schmidt trigger between what you are counting and the pic.

CuriousOne
- 31st August 2016, 08:26
If it was noise issue, why my code works perfectly?

Art
- 31st August 2016, 11:04
The manual says with a 4MHz oscillator as you have, the pin is sampled every 20us which is way too slow for the fractional pulse durations you stated.
The different results can easily be explained since any low or high period could be entirely missed.

Your code is still pretty slow.
The fastest I can think of right now in PBP is this:


newbitstate var bit
oldbitstate var bit
counter var word
count var word
duration var word

newbitstate = 0
oldbitstate = 0
duration = 9000 ‘ set duration to sample the input


count = 0 ‘ reset count

for counter = 0 to duration
newbitstate = portb.0
if newbitstate != oldbitstate then
count = count + 1
endif
oldbitstate = newbitstate
next duration


Then Count will be the number of pin changes.
To get the pulse count, rather than check in the routine and slow it down,
just divide Count by 2 at the end, to get the number of rising edges,
and if the remainder is 1, the duration ended while the port pin was high.

CuriousOne
- 1st September 2016, 05:43
0.8ms=800us, so it fits very well :)

Art
- 5th September 2016, 15:31
lol I was reading ms as microseconds.
If your code works better than Count then use it :D I’d sure like to see a disassembly of Count in your loop though, which I don’t have the tools to do handy at the moment.