16f84 Switch counter to lcd

View: New views
5 Messages — Rating Filter:   Alert me  

16f84 Switch counter to lcd

by Paul & Lynn Tyrer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Firstly THANK YOU TO ALL.

The book i have demonstrates the Assembly language and each chapter
increases the knowledge depth. However i think i do not understand as much
as i think i do. I am Proud to say i figured the inputs and outputs and
using the data sheet assigned one of the input/output pins for the RB4
Switch and RB5 for the LED. I am currently looking at Interupts to see if i
can make head nor tail of them and hopefully the interupts would then break
into the program and do what it should do if the switch is pressed. If this
works i guess i put my increment count into the interrupt routine and then
when its finished or back to 0 or off then the rest of the program would
continue. Right now the header for the book puts A and B as outputs, do i
just change RB4 to a input or and if so how without setting bank B to all
inputs. This has stumped me for a an hour now. I have a day off and i said
to my wife i would paint but this has been taking me over all day so far.

Thanks again

Paul
























Just to update, I am hopelessly new and lost. I was a VB basic guy years ago
and remember a little of what I need to do but not a lot.
I know I will need a place to store the count, and will have a call list up
to 50 so when the count equals 10 I will have a call to put 1+0 on the
screen.
How do I :
Create a place to store the count.
Increment 1 to this count when the state changes
compare the stored count so when it equals 50 I increment the lcd by 1

I was hoping to find a piece of code out there in Google land to help me but
as of yet I have not been successful. However I do feel a sense of
achievement coming this far.

Any help is of course appreciated.

Thanks

Paul



Hi all.
I am trying to make a switch counter that would put on the lcd screen how
many times /50 the switch has been opened/closed.

I purchased the Book PIC In Practice and have been successful in building
the LCD circuit 2x20 and able to put the words I need to the screen. (after
spending hours trying to get it to work)

What I need and am hopelessly lost at this point, is to count the switch on
A0 and put the amount on to the screen. using the lcd Code in the above
book.

I beg you, this is not for any other purpose than to count the water gallon
usage in my house using a hall effect switch on the meter.

Can anyone help me with code/ suggestions etc

Thanks in advance

Paul

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist

Re: 16f84 Switch counter to lcd

by Forrest W Christian-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Paul & Lynn Tyrer wrote:
> This has stumped me for a an hour now. I have a day off and i said
> to my wife i would paint but this has been taking me over all day so far.
>
>  
Addictive isn't it?   Go paint, it will be waiting for you :)

A few things to mention... others did on both but to summarize a couple
of the big points a different way so that you can perhaps hear it in a
different way.

First of all, reading the switch and debouncing.

You will need to have some sort of way to see the switch transition from
low to high.   Assuming you have the pin set up such that you are really
reading it, the following are a couple of options that way.

But before I go there, Olin mentioned the need to debounce the switch.  
If this is a mechanical (or certain electronic) switch you will find
that it doesn't just go from off to on.   The contacts will bounce a
bit... so if you are just counting transitions you'll find that you'll
get more than one and perhaps a lot of counts per transition, depending
on the type of switch and how fast it settles.  The simplest, brute
force method to do this that I sometimes employ is to just delay a fixed
amount of time so that you don't count multiple transitions for each
actual one.  That is why Olin mentioned the need to understand the
maximum count rate - if it is counting 100 times a second, and you
ignore a second's worth of pulses, you're going to loose actual counts.  
On the other hand if you only delay 1/10,000th of a second, you might
count multiple pulses if you have a really slow switch.  I'm going to
assume that the correct debounce delay is 10ms for the code below.  I
should also note that there is like a million ways to debounce a swich,
and I'm sure if we started a how to debounce thread, we'd be talking for
days.

Oh, and one more thing.  I agree with others about perhaps considering
something like a Basic or C compiler for this..  but on the other hand,
you typically need some understanding at the level you are dealing
with.  I hate to push you that way if you are enjoying the assembly
language learning.  On the other hand, if you're more goal oriented and
want to take some of the assembly-language nightmare out of this
project, I would recommend that you download a copy of either
mikro-basic or mikro-c from mikro-e (search for mikro basic will get you
to the site).   The nice thing about the mikro compilers is that it has
a lot of hobbiest friendly libraries - for instance the LCD library (not
spi-lcd or GLCD) makes LCD work really easy, etc.  Plus, you don't have
to deal with a lot of stuff you're dealing with.   Also, the free
version (just download the regular version and don't register) should
generate programs larger than the PIC you're using is capable of (or if
not, it's close).   I personally use C, but I seem to recall you are a
VB guy so the Basic might be easier for you.

But back to the pseudo code.. this is c-like but you should get the gist...

To 'read' a port:

Set up port and LCD one-time.
Print Welcome on LCD if appropriate.

while (1)
{
  //read the pin
   pinvaluethisloop=read_pin(A0);

   //see if the pin changed, and if so, if it went from low to high
(i.e. it is now high)
   if ((lastpinread!=pinvaluethisloop) && (pinvaluethisloop))
   {
        delay_ms(10);  // delay to prevent multiple readings.
         divisioncount=divisioncount+1;
         if (divisioncount>=50)
         {
             actualcount++;
             update_lcd();  // function you wrote to take actualcount
and put on lcd.
           }
    }
    lastpinread=pinvaluethisloop;
}


That's the whole program basically.    It checks to see if the pin
changed each loop, and if so, delays a bit to debounce, then handles the
counter.    This is what most people called 'polled'... you are checking
status each time through the loop.   If you have other things to do, you
can add it to the while(1) loop.

The only caveat is that you should be mindful that if your other things
take long enough, you may miss pulses... I.E. if your pulses come 100
times a second, and your LCD takes 1 second to update, then you have a
problem.   That is where the interrupt options make things more
reliable, but also more complex to write... here's some pseudocode for
writing an interrupt version;

First, two interrupt routines.

//The following should be assigned to the external interrupt RB0/INT
interrupt
void interrupt external_int()
{
   
    // Ignore any switch bounces.
    if (debouncecounter>0)
    {
        return;
     }
     divisioncount=divisioncount+1;
     if (divisioncount>=50)
     {
         actualcount=actualcount+1;
       }
       debouncecounter=100;  // assuming the timer ticks every 1/10th of
a ms.
}

//And then the timer interrupt, this should be set to get called every
1/10th of a ms.

void interrupt timer_interrupt()
{
    if (debouncecount>0)
    {
       debouncecount=debouncecount-1;
    }
}

Ok, then what you would do is set the timer up to tick every 1/10th of a
ms and turn on the timer interrupt... (may need some adjustment if the
timer can't be set to tick that fast or for that value)..  And set the
port change or interrupt pin interrupt to call the interrupt routine
each time the pin changes from low to high - RB0/INT can be set that
way.   Or you can use the port change interrupt  if you can't use rb0
for some reason but will need to check to see if the pin is high first
(more code)...

So, whenever your pin changes, the interrupt routine is called, your
counter gets incremented, and the debouncecount value gets set to 100 so
that the input is ignored for 100 ticks.  Each timer tick interrupt
de-increments the value by one...   I haven't looked in detail at the
'f84 datasheet so I'm not sure if you can set the timer to tick every
1/10th of a ms or not - so you may need to adjust.   Your main program
will look like:

1) set up all pins and rb0/int for the interrupt.
2) set up timer
3)  turn on interrupts

while (1)
{
    if (lastcount != actualcount)
    {
         lastcount=actualcount;  // so we have a stable value, that the
interrupt won't change.
         update_lcd(lastcount);  
      }
      Do other stuff here if needed
}

Hopefully that helps.

And to echo others...  the 'f84 is widely used in training materials,
but really isn't used a lot for new designs... not that it's a bad chip,
just not what most of us work with daily.

I will also mention that if you're really into playing, you might want
to look at the mikro-e easypic board with some of the options... might
make what you are doing more fun.

-forrest
--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist

Re: 16f84 Switch counter to lcd

by ivp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Paul, just out of curiosity, what is it on the water meter that you're
affecting the Hall Effect switch with ? And what is the switch part
number ? I've found Hall Effect switches to be generally "clean"
and less prone to bounce than mechanical switches, although that
can depend on what you're using to cause the device to change its
output. An iron cog with a magnet to concentrate the flux is a reliable
influence for the linear or Schmitt Trigger devices, especially if it's
mounted solidly, ie no mechanical slop which changes the field strength

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist

Re: 16f84 Switch counter to lcd

by ivp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> I am currently looking at Interupts

Paul, if you don't need to use an interrupt then I think it would be
an unnecessary complication at this stage if you're unsure. My
inclination would be to get it done without an interrupt so you've
got (a) the satisfaction and relief of having got something working
and (b) a fall-back point to build on if you want to tackle interrupts

However, it would be quite straight-forward to do this with the
INT0 interrupt

You can also use T0CKI as a counter input (see the Option_Register
and Timer0 sections in the datasheet). If you load TMR0 with "255 -
count" (ie for you, 255 - 50), when 50 pulses have been entered into
T0CKI then TMR0 will increment from 255 (or -1) to 0 and TMR0IF
will be set. You can either poll for this or use it to generate an interrupt

wbr

PS in my /10 code posted the 'loop can be moved one line down as
W hasn't changed

     movlw   0x0a
loop     subwf   temp      ;subtract 10

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist

Re: 16f84 Switch counter to lcd

by ivp :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> "255 - count" (ie for you, 255 - 50)

Beg pardon, 256 - count

wbr

--
http://www.piclist.com PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist