Searching \ for '[PIC]counting rpm with a 16F84A' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/time.htm?key=count
Search entire site for: 'counting rpm with a 16F84A'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]counting rpm with a 16F84A'
2009\01\04@104442 by 4e fte

picon face
considering rpm ignition signal to be a square wave (in the case of a
toyota ignition system at least), could someone please guide me as to
how I could count the rpm when properly interfaced to a 16F84A.

2009\01\04@110111 by olin piclist

face picon face
4e fte wrote:
> considering rpm ignition signal to be a square wave (in the case of a
> toyota ignition system at least), could someone please guide me as to
> how I could count the rpm when properly interfaced to a 16F84A.

No, that would be silly.  Return the 16F84A before the museum finds it
missing, and get a real PIC with a CCP module.  A CCP module in capture mode
is the best thing for doing what you want.  The 16F88 and 16F648A both have
CCP modules, various other possibly useful peripherals, come in the same
footprint, and cost less than the 16F84A.

Since this is apparently a one-off hobby project, I wouldn't even bother
with a PIC 16 at all.  Unless you really need the space, get a handful of
18F2620 and use them for this project and future ones.  Think of the 12 and
14 bit cores as being for high volume projects.  About their only advantage
for hobbyists is if a small package is really required, but that's rare.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\01\04@111704 by Carl Denk

flavicon
face
I'm not going to get into the PIC part, but the signal might have a
frequency that is not the actual RPM, but some multiple (including a
divisor) of the RPM depending on the sensor location and if there is any
preprocessing. It could be:
Once for each cylinder firing and each cylinder fires ever other revolution
Once for one cylinder firing.
Some really goofy multiple of RPM where the sensor looks at a toothed
wheel with some odd number of teeth on the crank, cam, or somewhere else.

Might look at the OBDII output if it is 1996 or later this is likely to
be easier to work with, and then the equipment likely would be portable
to other vehicles, even if it is a permanent type installation .

And not saying anything poor about the suggestion of a more advanced
PIC, The more elementary PIC, as a learning experience isn't that bad,
though I probably would look for the easy out and the chips are readily
available, inexpensive, unless one is at a far off land where shipping
is slow. unreliable, and costly. :)


4e fte wrote:
> considering rpm ignition signal to be a square wave (in the case of a
> toyota ignition system at least), could someone please guide me as to
> how I could count the rpm when properly interfaced to a 16F84A.
>  

2009\01\04@111952 by Larry Bradley

flavicon
face
The tachometer (counting RPM) is a frequency counter. You can figure out the frequency from the number of cyclinders, and  the fact that it is a 4 cycle engine. (Left as an exercise for the student).

There are MANY frequency counter projects on the internet - Google "pic frequency counter" and then duck. Most of them use the 16F84. It all started with a Microchip app note on the subject, which is where to start.

The basic idea is to count the input pulses for a fixed period of time (for example, 1 second)

They all use tricks to be able to count to higher frequencies than the basic 8 bit timer of the 16F84 allows.  

My current project is a general purpose frequency counter using an 18F252 - the newer chips make life a lot easier.

But the original F84 design is just fine for what you want, since you are only dealing with a few tens of Hertz.

However, at low frequencies, such as what you are dealing with for a tach (e.g 3600 rpm = 60 revs/sec), you won't get very good resolution by measuring pulses for 1 second. 10 seconds would be better, but then the responsiveness to change is lousy.

A better method is to measure the period of the signal. If you have a good clean signal, you can measure the time between two leading edges of the signal, then frequency = 1/period.

To measure the period, you wait in a loop until the signal goes high. Start the timer running. Wait in a loop until the signal goes low. Wait in a loop until the signal goes back high again, then stop the timer. The timer value is now the period in "timer tics" which you have to convert into real wordl units (seconds, milliseconds, whatever)

There are many ways to skin this particular cat.

Have fun!

Larry



Original Message:
>
considering rpm ignition signal to be a square wave (in the case of a
toyota ignition system at least), could someone please guide me as to
how I could count the rpm when properly interfaced to a 16F84A.

2009\01\04@112715 by Joseph Bento

face
flavicon
face

On Jan 4, 2009, at 9:01 AM, Olin Lathrop wrote:

>
> Since this is apparently a one-off hobby project, I wouldn't even  
> bother
> with a PIC 16 at all.  Unless you really need the space, get a  
> handful of
> 18F2620 and use them for this project and future ones.  Think of the  
> 12 and
> 14 bit cores as being for high volume projects.  About their only  
> advantage
> for hobbyists is if a small package is really required, but that's  
> rare.

You guys are aware that I'm at the beginning stages of learning PIC  
programming.  Everyone seems to recommend staying away from the  
baseline and even midrange PICS and jump right into the high-end 18F  
devices.  Problem is, if you are learning and need examples to study,  
material appropriate for a beginner tends to use these 'museum piece'  
16F84 or like devices.

Joe
 
 

2009\01\04@114305 by Larry Bradley

flavicon
face
Joe, you can be as primitive with the 18F series as with the F84 - you don't have to use all the bells and whistles. But the point is that you soon will WANT to use the bells and whistles.

For example, the tach project. Start out doing things the hard way - ignore the CCP modules, for instance. Ignore the timers if you want - use delay loops for counting time. Once you have something that works the hard way, start using some of the more advanced features of the chip.

You may want to use something other than assembly language. If you start out with the 16 series, then later move to the 18f series, you may have to switch to a different compiler. And perhaps a different programmer, although I suepect most programmers, either commercial or home-made can handle both series.

There is really NO advantage to using the older chips. Get something like the 18F2620. It is probably overkill for most of the things you will do, but the minute you run out of memory or timers or something on the old chips, you will have to switch. So might as well start out with the powerfull ones. They are all cheap.

Larry




Original Message:

You guys are aware that I'm at the beginning stages of learning PIC
programming. Everyone seems to recommend staying away from the
baseline and even midrange PICS and jump right into the high-end 18F
devices. Problem is, if you are learning and need examples to study,
material appropriate for a beginner tends to use these 'museum piece'
16F84 or like devices.

Joe


2009\01\04@114841 by Bob Blick

face
flavicon
face

On Sun, 4 Jan 2009 13:27:44 +1200, "4e fte" <spam_OUT4eftefjTakeThisOuTspamgmail.com> said:
> considering rpm ignition signal to be a square wave (in the case of a
> toyota ignition system at least), could someone please guide me as to
> how I could count the rpm when properly interfaced to a 16F84A.

Set up two interrupt sources: TMR0 and RB0. In the interrupt, test for
which one caused the interrupt(and clear it). If it's TMR0, increment a
variable you could call "time". If it's RB0 that caused the interrupt,
increment a variable called "spark". Compare "time" with how ever many
it counts in one second. At that point, "spark" is the number of sparks
in one second. Multiply by 120 for RPM. Clear both "time" and "spark"
and begin again.

There are better ways to do this, but you can do it this way easily.

Note that some vehicles without distributors have variable numbers of
sparks per revolution depending on RPM so normal methods will not work.

Cheers,

Bob

--
http://www.fastmail.fm - The way an email service should be

2009\01\04@120057 by Adam Field

flavicon
face
> You guys are aware that I'm at the beginning stages of learning PIC
> programming.  Everyone seems to recommend staying away from the
> baseline and even midrange PICS and jump right into the high-end 18F
> devices.  Problem is, if you are learning and need examples to study,
> material appropriate for a beginner tends to use these 'museum piece'
> 16F84 or like devices.
>

I started with 16F628A and have used the 16F690, 16F877A and 16F876A
parts since then. I like the lower cost of the 16F series because I'd
hate to smoke a costly (comparatively) 18F part during prototyping.
Also, it bothers me to think of seemingly wasting a higher end part
for some of the simple things I've designed and built (clocks,
temperature gauges, remote control decoders).

2009\01\04@121102 by Joseph Bento

face
flavicon
face

On Jan 4, 2009, at 9:42 AM, Larry Bradley wrote:

>
> There is really NO advantage to using the older chips. Get something  
> like the 18F2620. It is probably overkill for most of the things you  
> will do, but the minute you run out of memory or timers or something  
> on the old chips, you will have to switch. So might as well start  
> out with the powerfull ones. They are all cheap.

I really should use this advice.  I've got my feet wet with a few  
assembly programs lighting and flashing LEDs on a 16F84.  I do have  
the C18 compiler courtesy of a group license purchased at work, so I  
suppose I should jump right in and start some C tutorials.

You guys have been kind enough numerous times with advice, so now I  
think I should take that advice and concentrate my learning to the  
18F2620 and store my 16F parts.  I'm sure an LED will light or blink  
just as well on the 18F2620 - I just need to learn the differences.  I  
assume that assembly language still works (I'd like to try and convert  
some 16F tutorials), except there are now 75(!) core instructions!

Thanks!




2009\01\04@125918 by olin piclist

face picon face
Joseph Bento wrote:
> Problem is, if you are learning and need examples to study,
> material appropriate for a beginner tends to use these 'museum piece'
> 16F84 or like devices.

The data sheets exist and are well written for all PICs.  I wouldn't put too
much stock in examples.  Many of them are examples only of how not to do
things.  The 18F architecture is a little nicer in that it's easier to
program and less likely for you to mess up things like banking.  Inattention
to banking is a very common newbie mistake.  If you see code with BSF or BCF
on RP0 or RP1 in STATUS, get out of there fast.  That's a clear indication
of incopetence, and is unfortunately quite common.

Think about it.  The kind of guy that spends four weeks getting a LED to
blink is more likely to feel its some major accomplishment and put up a web
page showing off "Looky me everyone, I done blinked a LED!!".  Studying his
bugware will only teach you bad habits.  Those that know what they're doing
and get past the first blinking LED in a few hours don't feel it's a big
deal and aren't likely to show it off.

In other words, read the data sheet carefully.  Then you'll know how to make
your own examples.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\01\04@130443 by solarwind

picon face
On Sun, Jan 4, 2009 at 11:01 AM, Olin Lathrop <.....olin_piclistKILLspamspam@spam@embedinc.com> wrote:
> 4e fte wrote:
>> considering rpm ignition signal to be a square wave (in the case of a
>> toyota ignition system at least), could someone please guide me as to
>> how I could count the rpm when properly interfaced to a 16F84A.
>
> No, that would be silly.  Return the 16F84A before the museum finds it
> missing, and get a real PIC with a CCP module.  A CCP module in capture mode
> is the best thing for doing what you want.  The 16F88 and 16F648A both have
> CCP modules, various other possibly useful peripherals, come in the same
> footprint, and cost less than the 16F84A.
>
> Since this is apparently a one-off hobby project, I wouldn't even bother
> with a PIC 16 at all.  Unless you really need the space, get a handful of
> 18F2620 and use them for this project and future ones.  Think of the 12 and
> 14 bit cores as being for high volume projects.  About their only advantage
> for hobbyists is if a small package is really required, but that's rare.
>

18F2620 - $5

16F886 - $2

For simple one off projects, I'd rather buy a handful of 886s.

10 x 16F886 = $20

10 x 18F2620 = $50

Starts adding up - but only if you're a student and on a budget like I am.


--
solarwind

2009\01\04@131453 by solarwind

picon face
You could also get the 12F683 - just buy like, 20 of em. For single
purpose applications, like the one you're going for, they're great.
They're only a $1.20 each.

2009\01\04@150041 by olin piclist

face picon face
solarwind wrote:
> 18F2620 - $5
>
> 16F886 - $2
>
> For simple one off projects, I'd rather buy a handful of 886s.

Then you'll need to get different PICs for other projects, and you'll have
to deal with the different banking and paging architecture of the 14 bit
core.  Also, most projects are going to cost a lot more than $3, so the
difference in the price of the single PIC is going to be noise much of the
time.

> Starts adding up - but only if you're a student and on a budget like
> I am.

Exactly.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\01\04@170025 by Gerhard Fiedler

picon face
On 2009-01-04 14:48:17, Bob Blick wrote:

> On Sun, 4 Jan 2009 13:27:44 +1200, "4e fte" <4eftefjspamKILLspamgmail.com> said:
>> considering rpm ignition signal to be a square wave (in the case of a
>> toyota ignition system at least), could someone please guide me as to
>> how I could count the rpm when properly interfaced to a 16F84A.
>
> Set up two interrupt sources: TMR0 and RB0. In the interrupt, test for
> which one caused the interrupt(and clear it). If it's TMR0, increment a
> variable you could call "time". If it's RB0 that caused the interrupt,
> increment a variable called "spark". Compare "time" with how ever many
> it counts in one second. At that point, "spark" is the number of sparks
> in one second. Multiply by 120 for RPM. Clear both "time" and "spark"
> and begin again.
>
> There are better ways to do this, but you can do it this way easily.
>
> Note that some vehicles without distributors have variable numbers of
> sparks per revolution depending on RPM so normal methods will not work.

This is a better way to do it. Someone else suggested to count the rpm
pulses in a second; that often doesn't work well. The rpm pulse often is
something between 2 to 3 pulses per rev. At 1000 rpm, that's 2000 to
3000 pulses per minute, or 33 to 50 pulses per second. Not good enough
to display the rpm with more than two digits (which may be good enough,
but possibly not what you expect).

Gerhard

2009\01\04@172734 by Bob Blick

face
flavicon
face
Actually I specified 120 as the multiplier but since you're probably
picking the signal off the low side of the coil it will be 30 for a 4
cylinder engine, 20 for a 6 cylinder, 15 for an 8 cylinder(I assume if
you have a 12 cylinder engine in your car it probably already has a
tachometer :)

Cheers,

Bob

Bob Blick wrote:
{Quote hidden}

2009\01\04@172749 by Chetan Bhargava

picon face
You can build this extra simple frequency counter using a PIC16F628A

http://freenet-homepage.de/dl4yhf/freq_counter/freq_counter.html

I had built one some time ago using the common anode displays. Author
Wolfgang "Wolf" Büscher was pretty helpful as he converted existing
firmware for common cathode to common anode displays.

http://blog.bhargavaz.net/2005/03/dl4yhfs-frequency-counter.html

If you want to learn, you should follow Olin's advise and get yourself
PIC18F chips to start with.


Chetan Bhargava
Web: http://www.bhargavaz.net
Blog: http://microz.blogspot.com



On Sat, Jan 3, 2009 at 5:27 PM, 4e fte <EraseME4eftefjspam_OUTspamTakeThisOuTgmail.com> wrote:
> considering rpm ignition signal to be a square wave (in the case of a
> toyota ignition system at least), could someone please guide me as to
> how I could count the rpm when properly interfaced to a 16F84A.
>

2009\01\04@221103 by David Meiklejohn

face
flavicon
face
Olin Lathrop wrote:

> Joseph Bento wrote:
>> Problem is, if you are learning and need examples to study,
>> material appropriate for a beginner tends to use these 'museum piece'
>> 16F84 or like devices.
>
> The data sheets exist and are well written for all PICs.  I wouldn't put
> too
> much stock in examples.  Many of them are examples only of how not to do
> things.  The 18F architecture is a little nicer in that it's easier to
> program and less likely for you to mess up things like banking.
> Inattention
> to banking is a very common newbie mistake.  If you see code with BSF or
> BCF
> on RP0 or RP1 in STATUS, get out of there fast.  That's a clear indication
> of incopetence, and is unfortunately quite common.

I agree with all this.

> Think about it.  The kind of guy that spends four weeks getting a LED to
> blink is more likely to feel its some major accomplishment and put up a
> web
> page showing off "Looky me everyone, I done blinked a LED!!".  Studying
> his
> bugware will only teach you bad habits.  Those that know what they're
> doing
> and get past the first blinking LED in a few hours don't feel it's a big
> deal and aren't likely to show it off.

But this I have to respond to, as someone who has spent a lot of my spare
time in the last couple of years writing PIC tutorials
(http://www.gooligum.com.au/tutorials.html)

My tutorials - for baseline (12-bit) and midrange (14-bit) cores, using
assembler and C (four series, and 25 lessons in total so far), start not
even with flashing an LED, but simply lighting one.  Flashing using "busy
wait" delay loops is lesson 2, then after introducing relocatable coding
techniques (let's put that delay code into a subroutine, or even an
external module...), I show how to do the same flashing with timers (and
do other things like respond to a switch, while the flashing continues),
and then, in the lesson I've just finished, I show how interrupts can be
used to do achieve the same thing, as a "background" process.  So I see
"flashing an LED" as a useful exercise, for demonstrating a number of
techniques.

And that first step - simply turning on an LED - is a "big deal", in that,
to do that small thing, you need a PIC in a working circuit, and you need
to have successfully programmed that PIC, so it validates the whole tool
chain from PC and software through to demo board.  It's something to build
on.

As for starting with 16Fs - as I've said before, I seriously considered
starting the tutorials with 18Fs, and ignoring the 12- and 14-bit cores.
I do see the merits in that argument.  However - I started writing my
tutorials after seeing some of the questions asked on the Microchip forum
and at my local PIC users group.  Some people seem to be overwhelmed by
how much there is to learn at once - they'll be told "remember banking and
paging and make sure you disable analog inputs and comparators if you want
to use these pins but not those ones, and check that you don't have LVP
enabled" - it can be all too much.

So my approach was to start with the 12F508, which has only one bank and
one page and no analog, allowing me to ignore those complications until
introducing them, one at a time, in later lessons.

I'm NOT saying that that's the only way, or that it's better than starting
with 18Fs (I'll concede for example that I wouldn't have had to write up
an explanation of read-modify-write and the use of shadow registers, had I
started on an 18F, nor would I have had to introduce jump tables in
response to an addressing limitation in the call instruction on 12-bit
parts).

What I object to is the assumption that those who write tutorials on
blinking LEDs using 16Fs do so out of ignorance.  In my case, it was a
carefully considered decision.


David Meiklejohn
http://www.gooligum.com.au


2009\01\05@023210 by Vitaliy

flavicon
face
"solarwind" wrote:
> 18F2620 - $5
>
> 16F886 - $2
>
> For simple one off projects, I'd rather buy a handful of 886s.
>
> 10 x 16F886 = $20
>
> 10 x 18F2620 = $50
>
> Starts adding up - but only if you're a student and on a budget like I am.

If you figure in the value of your time, the extra cost of the higher end
chip becomes irrelevant.

Vitaliy


2009\01\05@024330 by Vitaliy

flavicon
face
"Adam Field" wrote:
> I started with 16F628A and have used the 16F690, 16F877A and 16F876A
> parts since then. I like the lower cost of the 16F series because I'd
> hate to smoke a costly (comparatively) 18F part during prototyping.

How often does that happen?


> Also, it bothers me to think of seemingly wasting a higher end part
> for some of the simple things I've designed and built (clocks,
> temperature gauges, remote control decoders).

If you spend more than an hour of your time on a project, it's likely that
the "niceness" of a higher end architecture will justify the extra cost.

There are, of course, other factors: for example, you may already own and be
very familiar with the 16F tool chain. In this case, the extra expense of
switching to a different architecture may not be worth it.

However, IMHO suggesting that a person new to PICs start with an 16F, is
doing them a bad service.


Vitaliy

2009\01\05@052026 by John Chung

picon face
The amount of documentation on PIC 16F84A is plentiful. I do however recommend that you printout the datasheet of other PIC16 and see the difference yourself. It is hardly that much difference after reading it through. Still if you want to wire the chip like the tutorial I suggest you use the PIC 16F84A until you are comfortable with better PIC16. BTW I hardly see any tutorials that work just by following it blindly. Nevertheless we are here to assist you :)

John


--- On Sun, 1/4/09, Joseph Bento <josephspamspam_OUTkirtland.com> wrote:

{Quote hidden}

> --

2009\01\05@061727 by Jinx

face picon face
> Everyone seems to recommend staying away from the baseline
> and even midrange PICs and jump right into the high-end 18F

The 16F84A is fine to get started on but it's not one that you'd want
to stick with when there are so many other newer PICs in the range
that are often cheaper. If you have 16F84As to use and practice on
then that's good, there's nothing wrong with them per se as a micro

Once you've got a grip on the basics and see what it can and, more
importantly, can't do then you will have to look at what's next to
tackle. Possibly compare the 40-pin 16F and 18F devices

The 18F1220 or 18F1320 would be an OK 18F to start with. It's
18-pin, reasonably inexensive, and can do so much more than the
16F84A. And with less programming effort too

http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf

I'm not sure what Microchip's sampling policy is now. Not so long ago
getting 18F samples was free and pretty straight-forward

> Problem is, if you are learning and need examples to study, material
> appropriate for a beginner tends to use these 'museum piece'  16F84
> or like devices

If there weren't PICList and Microchip forums I'd agree. But there's
no end of help available for the beginner on any device

Speaking personally, I use an 18F whenever possible because I got
tired of the limitations of the 16F. For example, you *could* make
a 16F program work with only one FSR/INDF and that wretched
banking, but man, the hassle compared with even a basic 18F that
has three FSRs and no banking. I still use 16F but not nearly so much
as I used to

2009\01\05@094838 by peter green

flavicon
face

> The 18F1220 or 18F1320 would be an OK 18F to start with. It's
> 18-pin, reasonably inexensive, and can do so much more than the
> 16F84A. And with less programming effort too
>  
Apparently early revs of those chips had major problems some of which
microchip admitted to in the errata and others they didn't.

So I would only suggest buying those chips if you can be sure you are
getting a recent rev. Otherwise I would probablly go for a 28 pin such
as the 18F252 or it's second gen sucessor the 18F2520 (I don't reccomend
40 pin chips for a beginner unless they are using them on a ready made
board because thier extra width makes them cover lots of the holes in
your breadboard).

>> Problem is, if you are learning and need examples to study, material
>> appropriate for a beginner tends to use these 'museum piece'  16F84
>> or like devices
>>    
There is a book called "Embedded design with the PIC18F452
Microcontroller" which some people have reccomended to me and from what
i've seen of it (I've used it for reference but I already new the 18F
line when I first came across it) it seems like quite a good intro for
the newcomer. They even include a demo board (though you have to supply
the parts to build it up yourself.


2009\01\05@125506 by olin piclist

face picon face
David Meiklejohn wrote:
> What I object to is the assumption that those who write tutorials on
> blinking LEDs using 16Fs do so out of ignorance.  In my case, it was a
> carefully considered decision.

I didn't mean people who write tutorials, and certainly not your tutorials.
Those that set out from the start to teach usually know what they are doing.

Unfotunately your instance is a rarety.  Most examples out there about PICs
is written by knuckle dragging apes that barely understand what banking is
and think BSF STATUS,RP0 is a prefectly good way to "go to bank 1".


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\01\14@225340 by 4e fte

picon face
thanks and appreciated. however, upon some digging on the net, i found
a project made by someone called the "a tacho for your car". i
downloaded the source code and the schematic as well.

here it is:

http://www.2shared.com/file/4649538/a24b0879/tacho.html

now, can someone with experience just go thru this code and tell me
which part only deals with tacho/rpm pulse counting/interrupt? the
RB0/INT pin is the one connected to the -ve of the ignition coil for
rpm pulse pick up point.


On Mon, Jan 5, 2009 at 10:20 PM, John Chung <RemoveMEkravnusTakeThisOuTspamyahoo.com> wrote:
{Quote hidden}

>> --

2009\01\15@102141 by Richard Seriani, Sr.

picon face

----- Original Message -----
From: "4e fte" <4eftefjEraseMEspam.....gmail.com>
To: "Microcontroller discussion list - Public." <EraseMEpiclistspammit.edu>
Sent: Wednesday, January 14, 2009 10:53 PM
Subject: Re: [PIC]counting rpm with a 16F84A


{Quote hidden}

You wrote that you were in the beginning stages of learning to program the
PIC. How far have you gotten with your studies? Have you downloaded and
studied the datasheet? Do you understand the basics of the 16F84A,
especially interrupts and timers? If not, it would be futile for anyone to
try to explain the code to you in terms you will understand. If you have
gotten through the beginning stages (studied the datasheet and at least some
of the available tutorial info), which part of the code don't you
understand?

As for the code, I was unable to download it but I doubt if it is much
different than other implementations (counting pulses over a period of time
and doing the math to output it as RPM). If you are having problems
understanding a particular part of it, please post that part along with
specific questions and you will probably get more help from the denizens of
the PIClist than you want!

Good luck.

Richard



2009\01\15@114230 by Maarten Hofman

face picon face
>
> here it is:
>
> http://www.2shared.com/file/4649538/a24b0879/tacho.html
>
> This link seems to merely open several pages of ads and popups, with no
source code to be seen.

Greetings,
Maarten Hofman.

2009\01\15@122832 by Alan B. Pearce

face picon face
> here it is:
>
> http://www.2shared.com/file/4649538/a24b0879/tacho.html
>
> This link seems to merely open several pages of ads and
> popups, with no source code to be seen.

The link to the source is down the bottom in fine print. I know it took me a
minute or so to find it. Initially I thought like you, and was trying the
large text at the top, but that is only eye candy to get you to look at the
thing carefully.

2009\01\17@042058 by 4e fte

picon face
On Fri, Jan 16, 2009 at 11:44 AM, 4e fte <RemoveME4eftefjEraseMEspamEraseMEgmail.com> wrote:
{Quote hidden}

>> {Original Message removed}

2009\01\17@053128 by Jinx

face picon face
> I want to understand how rpm pulses will be counted from this
> source code only, as this is someones working project and how
> is interrupt and timer0 setup to do this task.

These are some of the relevant parts of that code

=======================

INTRUPT

LIGHT bcf     INTCON,T0IF     ; clear interrupt flag
       movf    TMR0,w          ; timer value
                               ; freq is 4MHz/4/2/(256(-8+2)) = 2kHz or 0.5ms
period
       addlw   0x08            ; add to timer register and takes 2 cycles to
start counting
       movwf   TMR0            ; place in timer register

; tachometer update

TACHO bcf     INTCON,INTF     ; clear INT flag
       incfsz  PULSE_CNT,f     ; increase pulse counter value for each speed
sensor input
       goto    RECLAIM
       movlw   0xFF            ; max value

MAIN

       bsf     STATUS,RP0      ; select memory bank 1
       movlw   B'00000001'     ; w = 00000001 binary (RB0 input, RB1-RB7
output)
       movwf   TRISB           ; port B data direction register

       bcf     STATUS,RP0      ; select memory bank 0
       movlw   B'11111110'     ; w is all 1's for RB7-RB1, 0 for RB0
       movwf   PORTB           ; portB outputs high

       bsf     INTCON,INTE     ; set interrupt enable for RB0
       bsf     INTCON,T0IE     ; set interrupt enable for TMR0
       bsf     INTCON,GIE      ; set global interrupt enable for above

=======================

Some things could be done better. I know it isn't your code but
please don't copy the badness

Don't use tabs in code. They're annoying
BSF STATUS,RP0 eg does not necessarily select bank1. Use banksel
BCF INTCON,INTF and BCF INTCON,T0IF before setting GIE
Long sequences of in-line code like below (sample) would be easier
to read without all the repeated comments. Comments where something
is unexpected in the sequence are more helpful

xorwf   MODE_1,w        ; cal mode
btfsc   STATUS,z        ; zero if the same
goto    RPM1_MD         ; rpm1 mode
movlw   0x03            ; check which mode
xorwf   MODE_1,w        ; cal mode
btfsc   STATUS,z        ; zero if the same
goto    RPM2_MD         ; rpm2 mode
movlw   0x04            ; check which mode
xorwf   MODE_1,w        ; cal mode
btfsc   STATUS,z        ; zero if the same
goto    RPM3_MD         ; rpm3 mode

movlw   B'11111110'     ; w is all 1's for RB7-RB1, 0 for RB0
movwf   PORTB           ; portB outputs high

Well, the comments simply repeat what the instructions say. Why
is better than what any day

=======================

Because of the lack of meaningful comments and an overall description,
a 'mission statement',  THE BIG PROBLEM WITH THE CODE, as
you've discovered, is that it's quite difficult to work out what is going on

To be honest, I wouldn't even bother trying to pick the useful bits out
of that program because it's so poorly presented for someone else to
understand

It would be much quicker and you'd learn more by building a program
for yourself from scratch

So, the absolute first thing to put in writing is what you want the program
to do. The next is work out how to accomplish that

For a rev counter, you need at least two things. A timer and a capture
counter. Display is optional but you'd expect something to look at

Do you understand how to make a timer interrupt ? For example, can
you accurately time 1 second ?

Do you understand how to capture input pulses ?

Finally, do you understand how to relate time elapsed to input count to
get the rpm answer you want ?

2009\01\17@055915 by 4e fte

picon face
these 3 things are exactly what i want to understand. this is what im
having problems with to visualise and that is why i thought of turning
to code directly.

________________________________________
From: RemoveMEpiclist-bouncesTakeThisOuTspamspammit.edu [EraseMEpiclist-bouncesspamspamspamBeGonemit.edu] On Behalf Of
Jinx [RemoveMEjoecolquittKILLspamspamclear.net.nz]
Sent: Saturday, January 17, 2009 11:30 PM
To: Microcontroller discussion list - Public.
Subject: Re: [PIC]counting rpm with a 16F84A

Do you understand how to make a timer interrupt ? For example, can
you accurately time 1 second ?

Do you understand how to capture input pulses ?

Finally, do you understand how to relate time elapsed to input count to
get the rpm answer you want ?

2009\01\17@064523 by Jinx

face picon face
> these 3 things are exactly what i want to understand. this is what im
> having problems with to visualise and that is why i thought of turning
> to code directly.

Here's some absolute code that will help you understand TMR0. If
you use a 4MHz crystal and have an LED on PortB,1 you should
see it flash at 1s on, 1s off  (I hope - not used an F84 for a looong
time and this code was just put together in Notepad, and I'm tired)

E&OE (errors and omissions excepted, ie cross fingers, touch wood)

;4MHz crystal = 1MHz instruction cycle
;
;TMR0 generates an interrupt passing through 0xff -> 0x00
;
;One second takes 1,000,000 increments of TMR0
;
;1,000,000/256 = 3906 times TMR0 passes through 0xff -> 0x00
;
;ticks_hi:ticks_lo are used to count from -3906 (0x0f42) up to 0
;
;1,000,000/256 is actually 3906.25. 3906 * 256 = 999.936s

  list P=16F84
  #include "p16f84.inc"
  __config _XT_OSC & _WDT_OFF & _PWRTE_ON

;============================

         cblock 0x0c

         ticks_lo               ;TMR0 interrupt counter
         ticks_hi
         s_temp                 ;status store in ISR
         w_temp                 ;W store in ISR

         endc

;============================

#define   led     portb,1        ;LED flash output

irq_count = - d3906              ;count up to 0

;============================

        org     0x00
        goto    init

        org     0x04
        goto    tmr0_isr

;================================================
;        Main program
;================================================

init     banksel trisa

        movlw   b'00000000'     ;all output
        movwf   trisa

        movlw   b'00000000'     ;all output
;                        0        LED (don't forget a resistor, a few hundred
ohms)
        movwf   trisb

        banksel porta

        clrf    porta
        clrf    portb

        movlw   high(irq_count) ;set counter to - d3906
        movwf   ticks_hi        ;ticks high set to 0x0f
        movlw   low(irq_count)
        movwf   ticks_lo        ;ticks_lo set to 0x42

        clrf    intcon          ;clear all IRQ flags, generally

;specifically

        bcf     intcon,t0if     ;clear IF before GIE set
        bsf     intcon,t0ie     ;enable TMR0 interrupts
        clrf    tmr0            ;reset TMR0
        bsf     intcon,gie      ;enable all interrupts

wait     nop                     ;loop here forever
        goto    wait

;================================================
;        Process TMR0 interrupt
;================================================

tmr0_isr movwf   w_temp          ;store W and Status
        swapf   status,w
        movwf   s_temp

        bcf     intcon,t0if     ;must clear IF before retfie

        incfsz  ticks_lo        ;increment ticks until = 0x0000
        goto    isr_exit        ;low byte <> 0
        incfsz  ticks_hi
        goto    isr_exit        ;high byte <> 0

;count = 0x0000

        movlw   high(irq_count) ;reload counter with - 3906
        movwf   ticks_hi
        movlw   low(irq_count)
        movwf   ticks_lo

        movfw   portb           ;read port
        xorlw   b'00000010'     ;toggle b0 (LED flash)
        movwf   portb           ;write back to port

isr_exit swapf   s_temp,w        ;restore status, W, exit
        movwf   status
        swapf   w_temp
        swapf   w_temp,w
        retfie

2009\01\17@065029 by Jinx

face picon face
Error in the comments

>          movlw   high(irq_count) ;set counter to - d3906
>          movwf   ticks_hi        ;ticks high set to 0x0f
>          movlw   low(irq_count)
>          movwf   ticks_lo        ;ticks_lo set to 0x42

ticks_hi = 0xf0
ticks_lo = 0xbe

In other words, -d3906 = 0xf0be (= 0x10000 - 0x0f42)

2009\01\17@070525 by 4e fte

picon face
thanks a lot for this. i will go over this in the next few days. this
is very helpful.

On Sun, Jan 18, 2009 at 12:49 AM, Jinx <joecolquittSTOPspamspamspam_OUTclear.net.nz> wrote:
{Quote hidden}

> -

2009\01\17@072426 by Jinx

face picon face
> thanks a lot for this. i will go over this in the next few days. this
> is very helpful.

It *should* work. When I have a little time tomorrow I'll run it
through MPLAB and an F84 just to make sure. If it doesn't work
as expected I'll let you know

        xorlw   b'00000010'     ;toggle b0 (LED flash)

Comment should be b1. I wrote the code first with the LED on b0
but then thought you might want to add a capture, and that would
best on b0

As for the timer, you could make it exactly 1s if that's important. If
you remember, 1,000,000 / 256 = 3906.25

By setting TMR0, initially and at the reload, to that extra 0.25 *
256 ( = - d64) and adding 1 to the IRQs to be counted, -> d3907

2009\01\17@174509 by Jinx

face picon face
Here's working TMR0 code. I tested it this morning on a -10 F84. A
couple of minor changes so MPLAB doesn't complain

I'd forgotten about assigning the pre-scaler away from TMR0. With
PSA = 0 (default I think), TMR0 has a minimum of a 1:2 divider

The reloading of TMR0 to get exactly 1s, if that's important, which in
this application I don't think is, can be done with proper cycle counting,
not just the reload of -(0.25 * 256). Sorry for any wrong impression

Because TMR0 runs all the time, it's counting as code is being executed,
so the time that eg reloading code takes must be considered. In other
words, as you know how many cycles it takes to get to a certain point in
the code, that is the adjustment to the reload value

Have a look at the PICList section on timers

http://www.piclist.com/techref/microchip/time.htm

;4MHz crystal = 1MHz instruction cycle
;
;TMR0 generates an interrupt passing through 0xff -> 0x00
;
;One second takes 1,000,000 increments of TMR0
;
;1,000,000/256 = 3906 times TMR0 passes through 0xff -> 0x00
;
;ticks_hi:ticks_lo are used to count to 3906 (0x0f42)
;
;1,000,000/256 is actually 3906.25
;3906 * 256 = 999.936s

  list P=16F84
  #include "p16f84.inc"
  __config _XT_OSC & _WDT_OFF & _PWRTE_ON

errorlevel -305, -302, -306

;============================

         cblock 0x0c

         ticks_lo               ;interrupt counter
         ticks_hi
         s_temp                 ;status store in ISR
         w_temp                 ;W store in ISR

         endc

;============================

#define   led     portb,1        ;1Hz output

irq_count = -.3906              ;count up to 0

;============================

        org     0x00            ;start adress vector
        goto    init

        org     0x04            ;interrupt address vector
        goto    tmr0_isr

;================================================
;        Main program
;================================================

init     nop
        banksel trisa

        movlw   b'00000000'     ;all output
        movwf   trisa

        movlw   b'00000000'     ;all output
;                        0        LED
        movwf   trisb

        banksel option_reg

        movlw   b'00001000'
;                  xx
;                    0            TOCS, 0 = increment with Fosc
;                     x           TOSE
;                      1          assign pre-scaler to WDT
;                       xxx       pre-scaler
        movwf   option_reg

        banksel porta

        clrf    porta
        clrf    portb

        movlw   high(irq_count) ;set counter to - d3906
        movwf   ticks_hi        ;ticks high set to 0xf0
        movlw   low(irq_count)
        movwf   ticks_lo        ;ticks_lo set to 0xbe

        clrf    intcon          ;clear all, generally

;specifically

        bcf     intcon,t0if     ;clear IF before GIE set
        bsf     intcon,t0ie     ;enable TMR0 interrupts
        clrf    tmr0            ;reset TMR0
        bsf     intcon,gie      ;enable all interrupts

wait     nop                     ;wait here forever
        goto    wait

;================================================
;        Process TMR0 interrupt
;================================================

tmr0_isr movwf   w_temp          ;store W and Status
        swapf   status,w
        movwf   s_temp  

        bcf     intcon,t0if     ;must clear IF before retfie

        incfsz  ticks_lo        ;increment ticks until = 0x0000
        goto    isr_exit        ;low byte <> 0
        incfsz  ticks_hi
        goto    isr_exit        ;high byte <> 0

;count = 0x0000

        movlw   high(irq_count) ;reload counter
        movwf   ticks_hi
        movlw   low(irq_count)
        movwf   ticks_lo

        movfw   portb           ;read port
        xorlw   b'00000010'     ;toggle b1 (LED flash)
        movwf   portb           ;write back to port

isr_exit swapf   s_temp,w        ;restore status, W, exit
        movwf   status
        swapf   w_temp
        swapf   w_temp,w
        retfie

 end


More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...