The LOLex Update 7: It has a Button!
You may be wondering why I haven't been posting in awhile. That can be explained by the fact that I started my senior year at CP SLO about a week and half ago. I'm taking some cool classes that should greatly benefit me in my project shenanigans. They are Intro to Mechatronics, Controls, Senior Project, Thermal Science Lab and Music Theory. Enough about school, time for the LOLex.
Over the past 2 weeks I have been trying to get the uC to keep accurate time so that the watch will actually be useful. Here are the various revisions I went through until I ended up where I am now.
1) The internal oscillator of the uC. This worked alright to get the basic code working but blew as a way to keep the time. It was fast by almost 2 minutes and 40 seconds every hour. When I found this out I knew I had to move on to a ceramic resonator or crystal oscillator.
2) A ceramic resonator I pulled out of a broken stereo system that I use for parts. At least I think it was a resonator. I did some research and there are two types of these ceramic device, filters and resonators. I couldn't find out if they were the same device but functioned differently based on the circuitry and application. Anyway I used it. It's value was 4.00Mhz so I didn't have to change my timer code at all but I did have to change the configuration bits for the PIC, from internal osc to external osc. After testing, it preformed much much better than the internal osc. However it still wasn't perfect. This time it was slow about 10 seconds every 12 hours.
3) I also pulled out a 4.500 MHz and a 16.**** MHz crystal oscillator from the stereo. Using a crystal oscillator was my next logical step. I used the 4.500 crystal since I pulled off its loading capacitors too. The loading capacitors help stabilize the crystal. I had to do a little modification to the timer code because of the crystals new value. I guess I should also mention that when I moved to the external oscillator I had to swap a couple connections since the oscillator takes up 2 pins on the uC, so I can't light up the decimal point on the display. After testing this, I found that it was still a little slow. To compensate this I gradually decreased the timer compare value so that the second increment would be triggered faster.
4) This is what I'm planning on doing. The weekend before I left for school, a near by neighborhood had a massive block sale. I scoured the place for super cheap digital watches. My goal was to find on with a 32 kHz watch crystal that I could use. Well I found one but I have yet to do anything with it. The PIC has a input for a crystal of that size for use with the timer1 module. I am going to use it so I can put the uC to sleep and still have the timer running and keeping track of the time. When I press the button (which I will be covering shortly) it wakes up and displays the time then goes back to sleep. This will greatly increase battery life, which is last the last challenge I'll need to tackle for this project to be finished.
button yeah!
I introduced a button to my uC so that they could set the time together. Since I was very limited pins I used something I saw on this site. I connected the button to one of the output pins for the display so that it multiplexed with it. So I have to change that pin from output to input whenever I'm polling the button. I don't know it thats the right way to do it but it seems to work. This was also the first time in any of my projects that I have used a button so I had to learn about debouncing and everything else that goes a long with buttons.
Here how my set routine works. First to get into set mode the button is held down for a short while. If you just press the button then the time is displayed for like 2 seconds. Once in set mode it sets the hours by incrementing them and then the user presses the button to stop the incrementing and set the hours. The same is done for the minutes. Here's my horrible code. Again I'm always looking for suggestions on my code and whatnot.
Well I've basically been testing this version since Sunday, so 3 days and it hasn't lost/gained a minute. The watch crystal will probably get integrated this weekend. After that stage goes through testing I should be getting VERY close to putting everything in the case.
Over the past 2 weeks I have been trying to get the uC to keep accurate time so that the watch will actually be useful. Here are the various revisions I went through until I ended up where I am now.
1) The internal oscillator of the uC. This worked alright to get the basic code working but blew as a way to keep the time. It was fast by almost 2 minutes and 40 seconds every hour. When I found this out I knew I had to move on to a ceramic resonator or crystal oscillator.
![]() |
| Mine says 4.00M |
3) I also pulled out a 4.500 MHz and a 16.**** MHz crystal oscillator from the stereo. Using a crystal oscillator was my next logical step. I used the 4.500 crystal since I pulled off its loading capacitors too. The loading capacitors help stabilize the crystal. I had to do a little modification to the timer code because of the crystals new value. I guess I should also mention that when I moved to the external oscillator I had to swap a couple connections since the oscillator takes up 2 pins on the uC, so I can't light up the decimal point on the display. After testing this, I found that it was still a little slow. To compensate this I gradually decreased the timer compare value so that the second increment would be triggered faster.
4) This is what I'm planning on doing. The weekend before I left for school, a near by neighborhood had a massive block sale. I scoured the place for super cheap digital watches. My goal was to find on with a 32 kHz watch crystal that I could use. Well I found one but I have yet to do anything with it. The PIC has a input for a crystal of that size for use with the timer1 module. I am going to use it so I can put the uC to sleep and still have the timer running and keeping track of the time. When I press the button (which I will be covering shortly) it wakes up and displays the time then goes back to sleep. This will greatly increase battery life, which is last the last challenge I'll need to tackle for this project to be finished.
button yeah!
I introduced a button to my uC so that they could set the time together. Since I was very limited pins I used something I saw on this site. I connected the button to one of the output pins for the display so that it multiplexed with it. So I have to change that pin from output to input whenever I'm polling the button. I don't know it thats the right way to do it but it seems to work. This was also the first time in any of my projects that I have used a button so I had to learn about debouncing and everything else that goes a long with buttons.
Here how my set routine works. First to get into set mode the button is held down for a short while. If you just press the button then the time is displayed for like 2 seconds. Once in set mode it sets the hours by incrementing them and then the user presses the button to stop the incrementing and set the hours. The same is done for the minutes. Here's my horrible code. Again I'm always looking for suggestions on my code and whatnot.
void set(void)
{
char hour = 0, min = 0;
char setCount = 0;
/*Ill display SET or something when it comes into this mode
so that one doesn't automatically set the time*/
for(setCount =0;setCount<500;setCount++){
PORTB = 0b10100010;
delay(100);
PORTB = 0x00;
}
setCount = 0;
while(hour == 0){
if(setCount == 100){
setCount = 0;
hh++;
}
if(hh == 13){
hh = 1;
}
display(hh/10,hh%10,mn/10,mn%10);
if(RA1==1){
delay(1200);
if(RA1==0){
hour = 1;
}
}
setCount++;
}
while(min==0){
if(setCount == 100){
setCount = 0;
mn++;
}
if(mn == 60){
mn = 0;
}
display(hh/10,hh%10,mn/10,mn%10);
if(RA1==1){
delay(1200);
if(RA1==0){
min = 1;
}
}
setCount++;
}
}And here's the part where you enter into the set routine. while(1) /*run forever. Idles if button not pressed. if button held goes into setup*/
{
TRISA = 0xF2;
if(RA1 == 1){ //is button pressed
hold = 1;
counter = longCount;
while(hold == 1){
delay(700); //delay 10ms
if(RA1 == 1){ //is button still pressed
counter--; //decrease counter
if(counter==0){ //if zero it was a long hold
GIE = 0;
set();
GIE = 1;
hold = 0;
}
}
else if(RA1 == 0){ //button wasnt held
counter = 100;
TRISA = 0xF0;
while(counter != 0){
display(hh/10,hh%10,mn/10,mn%10);
counter-=1;
}
hold=0;
}
}
}
}To make this better I am thinking about implementing something similar to this. That should make the code somewhat nicer and less confusing.Well I've basically been testing this version since Sunday, so 3 days and it hasn't lost/gained a minute. The watch crystal will probably get integrated this weekend. After that stage goes through testing I should be getting VERY close to putting everything in the case.




