PDA

View Full Version : Timer1 & array confusion; very new to PBP programming



curian88
- 5th April 2010, 09:53
Hi guys!

I am very new to this PBP programming language as well as with the PIC microcontroller and would like to get as much advice as I can on to learning this new program. ;)

The Pic I'm using is the PIC16F88 running at 8Mhz and it will be compiled with MPELab IDE (correct me if I'm wrong, which this is using the PicBasic Pro)

What I am trying to achieve is to count the Delay between knocks (based on Steve's Secret Knock Detector system @ www.grathio.com)

So far i've read through all the clock programs that are available on this forum but i'm still confused as to how to modify the program to only count in milliseconds for the delays and then store it in an array.

I have defined an array which is set as the "main" code:

secretCode VAR word[3] 'maximum of three knock values
i var byte 'declares i as counter in bytes
'initial setup
secretCode[0] = 100 'in milliseconds
secretCode[1] = 100
secretCode[2] = 100
knockReadings VAR word[3] 'delay between knocks during input

once a knock has been detected, it goes into the loop defined:


listenToKnock:
currentKnockNumber var byte 'define new variables
startTime var byte 'define new variables
now var byte 'define new variables
myTime VAR word 'the current time
i = 0 'sets I counter as 0
for i = 0 to 2
knockReadings[i] = 0 'first value is stored for the delay

currentKnockNumber=0 'Incrementer for the array.

startTime=0 'Reference for when this knock started.

now=0 'Reference for current knock
while Knock =0 && myTime < 1200 'no knocks,
'continue counting
GoSub SetTimer 'trying to set it to end at 1200
'mS
goto EndTime
wend
knockReadings[i] = myTime 'is this correct in saving the
'delay time into this array?
next i
goto main 'returns to main loop

SetTimer:
T1CON.0 = 0 'stops Timer1
TMR1H = 0
TMR1L = 0
T1CON.0 = 1 'StartTimer
resume

EndTime:
CLEARWDT '<--- is the clearwatchdog required?
myTime.Highbyte = TMR1H 'gets high value
myTime.Lowbyte = TMR1L 'gets rest of value
If myTime < 1200 then '<--- im not sure how to define this in the
'first place so that if more than 1.2 seconds
'that the input is low, jump out of the loop
myTime = 0
endif
Resume

PS: I am not here to annoy everyone, but I am trying my best to understand how to work with PBP and the 16F88 pic. Any advice would be appreciated!

HenrikOlsson
- 5th April 2010, 11:02
Hi,
By default the TMR1 "counts" at at fOSC/4 which means that every "tick" is 0.5us when running at 8Mhz. TMR1 is 16bits wide so it will overflow every 2^16*0.5us = 3.2768ms - not very good if you want to measure 1.2s.

There are several ways of doing what you want:
* Use the TMR1 prescaler to scale down the rate at which TMR1 is incremented. Unfortunately the highest ratio is 1:8 which means that one tick now equals 4us instead of 0.5 and that the timer will overflow in ~26ms - still not good....

* Use an external clock source for the TMR1 osc. A 32.768Hz clock x-tal will give you a "tick-rate" of 1mS meaning that the value you get from the TMR1 registers are in ms and that you can measure times up to ~32 seconds.

* Use the TMR1 interrupt and count the number of interrupts it generates. If you let it free-run it will cause an interrupt every 3.2768ms but you can stop and reload it in the interrupt service routine so it that it overflows and generates the interrupt every ms if you want to.

To 'get the job done' I'd go with the second alternative. To get more used to the chip and PBP I'd go for the third alternative.

The CLEARWD is not needed, PBP adds that automatically as long as you don't tell it no to.

HTH.
/Henrik.

EDIT: Also, you do not use RESUME to return from a subroutine to which you jumped with a GOSUB as is the case with your SetTimer sub. You use RETURN. RESUME is for returning from an interrupt routine. I see that you also have a RESUME at the end of the EndTime sub to which you jump with a Goto - that won't work either....

rmteo
- 5th April 2010, 14:16
With an 8MHz clock, Timer1 overflows in 2^16*0.5us = 32.768ms - with the 1:8 prescaler it overflows in 262mS.

HenrikOlsson
- 5th April 2010, 16:10
Oops, absolutly correct. I messed that one up by a factor of 10, sorry for the confusion.

rmteo
- 5th April 2010, 16:16
Don't worry about it - I made a similar error on the MC forums this morning. Need to remember to get my morning cup of coffee first. :p:p:p

curian88
- 6th April 2010, 05:14
Thank you guys for such a quick response. And thanks for pointing out that error with the resume instead of a return, must have been out of my mind!

Also, I would like to ask, if what i posted there is the right way of storing in an array?

is it like:

"arraystore[i] = newdata?"

as for the timer base, i will still have to dig deeper into using interrupts and timer1 function..

Any extra advices or pointing out of co-existing codes that I could look up to will be appreciated!

HenrikOlsson
- 6th April 2010, 06:29
Hi,
Your array code seems OK to me, like:


myArray VAR Word[3] 'Create an array of 3 words.
i VAR byte

For i = 0 to 2
myArray[i] = 12345 'Store the value 12345 in array locations 0, 1, and 2
NEXT


The absolute easiest way to get started with interrupts is to use Darrels Instant Interrupt routines, they're available on his website (http://darreltaylor.com/DT_INTS-14/intro.html). Have a look at the "timer template" - that might be a good starting point for your application.

/Henrik.

curian88
- 8th April 2010, 05:03
thanks for your reply! Now, I'm actualling trying to use the SPI capabilities of the 16F88 that will be connected to an arduino. To my understanding, when data is transfered, it is in <binary>? but my questions is, in my programming compiler, do i use the same keywords with the values needed so that the master/slave can communicate?

I am trying to understand, how is it that I can tell pic A to send this array of information (say a Keypad Code Input of 1,2,3,4) and send it to pic B who is the slave, which then will do something else, and returns a high value or confirmation to pic A that code is verified -> please do this, this and this...

My professor just tells me about it being sent across as data on the same baud rate/frequency but i dont understand how this 2 diff pics can understand diff languages..

Any explanation at all, would be greatly appreciated! this forum definitely has really talented and helpful forumers!

mackrackit
- 8th April 2010, 07:03
My professor just tells me about it being sent across as data on the same baud rate/frequency but i dont understand how this 2 diff pics can understand diff languages..

I may not be much better than your professor but...

It is not really two different languages. Pretty much anything serial is just a series of highs and lows (0 and 1), sometimes the standard will be for a swing from a negative to a positive, still look at it as high and low.

The different Operating Systems are sending/receiving the same type of signal. The device sending converts the data into the correct format.. clock timing, and data. The receiving machine will have code to convert this back to something useful.

So the code on each machine may be in different languages, but they are doing the same thing. You might think about this in internet terms, HTML. Cross platform because the code generating the data and the code interpreting the data both "understand" the HTML.

This might help some.
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

Sorry if I confused things more. Or was not any help at all.