Long post: Timer0, 12F509, PicBasicPro, falling penny

Thread Starter

tracecom

Joined Apr 16, 2010
3,944
I want to measure the time it takes a penny to fall a distance equal to its circumference, which is very close to .75". By my calculation, it should take about 62.3 mS if uninhibited. However, I intend to slow its fall with neodymium magnets, and I don't know how much time will be added to that 62.3 mS by the effect of the magnets, since I haven't yet built the contraption.

I do have a PIC12F509 in a circuit with an LED and a phototransistor that is recognizing the logic level shift from the phototransistor as the penny blocks the light from the LED. And, I have an LCD connected that will display the time if I can record it.

What I don't have is the code to measure the time it takes the penny to pass between the LED and the phototransistor. I had hoped to use the PULSIN command, and made some progress with it until I realized that the maximum time it can measure is 16.38 mS.

My next hope is to use Timer0, however Timer0 can only measure up to 65.5 mS (assuming a 4MHz clock, which is what I am using.) Thus, I suppose I need to use the prescaler function to measure longer times. How much longer, I really don't know, but I guess that doubling the time to 131 mS would be sufficient. I can't imagine that the small neodymium magnets that I plan to use would be more effective than that.

Any suggestions would be welcome; sample code would be wonderful. I am using PicBasicPro 3 as the compiler, and I am very green with it.

Thanks.
 

Markd77

Joined Sep 7, 2009
2,806
With TMR0 and no prescaler you actually have a maximum time of 256 microseconds (not milliseconds). With a 4MHz clock TMR0 only runs at 1MHz.
Using 256 times prescaler gets up to 65.6 milliseconds.
An easy option if you were to assume that it would be impossible for it to take less than 50ms would be to put a fixed delay of 50ms, then start/clear TMR0. Then you can measure up to 115ms without any problems.
Otherwise add another variable to use as a counter, this thread gives a good idea of how to do it with baseline PICs:
http://forum.allaboutcircuits.com/showthread.php?t=83037
 

GopherT

Joined Nov 23, 2012
8,009
Just don't use timer0, make a delay loop (loop in loop) that can delay about 1 mSec each time it is called.

Have your program wait in a pause loop when gp5 is high (no coin breaking the beam).

Then, when the sensor detects the coin, keep calling the 1 mSec delay loop until pin gp5 goes high again. Use a variable to count how many times the delay was called while the coin was breaking the beam. You will get about 65 counts for a zinc penny and something more for copper. I doubt you will get more than 256 for copper (4x zinc) so no need to worry about roll-over of your counter variable. If you do get roll-over, just make the delay longer (2 or 4 millisecond).
 
Last edited:

Thread Starter

tracecom

Joined Apr 16, 2010
3,944
Just don't use timer0, make a delay loop (loop in loop) that can delay about 1 mSec each time it is called.

Have your program wait in a pause loop when gp5 is high (no coin breaking the beam).

Then, when the sensor detects the coin, keep calling the 1 mSec delay loop until pin gp5 goes high again. Use a variable to count how many times the delay was called while the coin was breaking the beam. You will get about 65 counts for a zinc penny and something more for copper. I doubt you will get more than 256 for copper (4x zinc) so no need to worry about roll-over of your counter variable. If you do get roll-over, just make the delay longer (2 or 4 millisecond).
Thanks for the reply. I actually did something similar to your suggestion and it worked pretty well. It's covered in another thread.
 
Top