PDA

View Full Version : Time delay by incrementing a variable using incoming pulse



jmgelba
- 21st October 2005, 03:03
Im trying to capture the 60Hz mains signal count the pulses up to 600, then go and do the subroutine "addtenthhour", then update the display. Then return to counting the incoming pulses, hit 600 and do it all over again.
However, it aint working.
My input is RA5, I have a 0-4.5v square wave coming into the pin. Its robust and is clean on the scope.
What the heck am I missing here??

MainLoop:
A0 = 0
IF PORTA.5 = 1 THEN A0 = A0 + 1
A1 = A0
IF A1 = 600 THEN AddHourTenth
Gosub DisplayRefresh
Goto MainLoop


AddHourTenth:
HoursL = HoursL + 1
IF HoursL = 0 THEN HoursH = HoursH + 1
IF (HoursH = $F) and (HoursL = $4240) then ; Roll over at 1,000,000
HoursH = 0 ; 99999.9 + .1
HoursL = 0
endif
GOSUB WriteHours_EE
A1 = 0
Return

Ron Marcus
- 21st October 2005, 04:18
MainLoop:
A0 = 0
IF PORTA.5 = 1 THEN A0 = A0 + 1
A1 = A0
IF A1 = 600 THEN AddHourTenth
Gosub DisplayRefresh
Goto MainLoop

It looks like every time you hit MainLoop, you reset A0 to zero. Subsequently, you put the A0 value into A1. This gets repeated every loop. The most A1 can increment to is 1. Also you have a goto statement to a sub loop, with a return at the end. Either have a gosub with a return or a goto with a follow up goto. Otherwise there will be stack problems.

Ron

jmgelba
- 21st October 2005, 17:30
Ok, so if I make A0 = 0 before mainloop to initilize the count at zero. I change the line:
IF A1 = 600 THEN AddHourTenth
into
IF A1 = 600 THEN Gosub AddHourTenth

I end up with this...

A0 = 0
MainLoop:
IF PORTA.5 = 1 THEN A0 = A0 + 1
A1 = A0
IF A1 > 600 THEN A1 = 0
IF A1 = 600 THEN Gosub AddHourTenth 'adds increment of value to be displayed
Gosub DisplayRefresh 'places new value on the 7 segment displays
Goto MainLoop

Does this take care of the issues?


Or should I be doing it like this?

IF A1 = 600 THEN
Gosub AddHourTenth
ELSE
Goto Mainloop
ENDIF

Charles Linquis
- 22nd October 2005, 21:50
Curious: If you are trying to implement a "power on hours" counter, I can think of a better way - one that doesn't use so much processor time.

mister_e
- 22nd October 2005, 22:27
i had the same feeling too. Using Timer interrupt by example. Look in your datasheet. There's at least one pin that can be assign as clock source for an internal timer. In many case it's RA.4

Wich PIC are you using?

Charles Linquis
- 23rd October 2005, 00:04
And if you aren't comfortable with interrupts, you can sit in a loop and watch for a timer overflow, reload the timer, run your main program and go back to the loop. As long as your main program takes less time to execute than the timer overflow period (extremely likely), everything works perfectly.

I do this all the time for run-time counters. If you are using 18F devices, you can easily get a 2 second period, even if you are running at 20Mhz. I count the jumps to MAIN. After 30 jumps, I increment the minutes counter.

mister_e
- 23rd October 2005, 02:13
you should find some hints in the following
http://www.picbasic.co.uk/forum/showpost.php?p=12544&postcount=2

look the 2 lasts examples

HTH

jmgelba
- 23rd October 2005, 18:10
Thanks for the ideas guys. I'm using a 16F818. It is a run time hourmeter application. I wanted to use the 60 Hz cycle to maintain accuracy over the lifetime of the product. I figured if I counted the pulse and only executed the rest of the program when the correct count had been achieved, this would give me the best accuracy.
The processor is doing a fair amount of work. Its multiplexing through 6, seven segment displays. Its running at 8Mhz using the internal oscillator as I need all the pins.
I currently have RA4 used as an output, and RA5 is the pulse in. The reason is that RA5 is input only and therefore cant be used to drive a segment. I have a spare pin, RA7, which I was intending to use to detect mains power fail, so that I can write to EE before the power fails, as currently, it only writes as it increments a digit.
I will check the datasheet, and if I can set RA5 as an interupt pin I will try it.
Otherwise I will have to shift my power fail detect to RA5 and have RA7 as an output. This will free up RA4.

jmgelba
- 28th October 2005, 03:50
I finally got some time to play with this today. The timer is working. After playing with the code I managed to get the numbers to display all the time. The reason they were not is that the program did not display anything while waiting for the timer flag to be set.
Two small problems I hope to fix shortly. One is that each time the display increments, it goes blank for maybe 100ms. I've tried several things to fix this but they only make the blank period longer or slightly shorter.
The second thing to fix is the pulse count. I need to count 72000 pulses before incrementing the display. Problem is, timer0 is 8bit and limited to 256 pulses before rolling over. I need to have timer0 rolloever and each time the flag is set, but it into a register and increment it until there is the equivilant of 72000 pulses.
If I preload the counter with 5, and have it rollover after 250 pulses, and do this 288 times, I get 72000 pulses which equals 1/10th of an hour. Would that work?