You may think that I’m obsessed with clocks. When I build my first clock, everybody at home needed clocks (except my kid of course but he really enjoys looking at blinking LEDs). Mother-in-law needed one in the kitchen and an alarm clock in her bedroom; wife needed a clock in our bedroom and one in the living room and so on. The main reason is, these clocks show time even in dark which they find very useful at night.
The demand for the alarm clock is satisfied finally. It is the same circuit and the same program as before. Only difference is that it stores alarm settings in EEPROM and having a buzzer. Unfortunately, the buzzer was not loud enough. So I’m thinking of having something louder. I’ll be able to find something from my kid’s toys collection since he’s got all types of music cars, broken and lying around.
Wednesday, October 22, 2008
PIC CLOCK - MATRIX DISPLAY
Ever since we moved to our home (in late 2003) we couldn't have a permanent wall clock in the living room. We tried putting several clocks but they stopped after running several weeks even though the clock and the battery is good. Some of them are still working in other places. So we didn’t try to put any more. After I build two small scale clocks, I wanted to build a bigger one for the living room. Here are some pictures of the clock. Still it is too early to say that the same thing will happen to this as well.
The display is created using a LED matrix. This is because I couldn’t find a suitable size seven segments in the market. Display comprises of four 4x7 matrices with a colon and a decimal point which is driven by two MAX7221. RTC is DS1307 with DS32KHz crystal. Temperature sensor is DS18S20. The brain of the clock is gigantic 40 pin PIC16F877A with 8k code space. Everything is assembled inside a plastic box file. Working with the two display drivers (MAX7221) was not that difficult but they didn’t work without the two 0.1uF capacitors close by. Program was slightly modified to accommodate two display drivers with the new numeric font. I designed several fonts and finally settled with the one shown.
The display is created using a LED matrix. This is because I couldn’t find a suitable size seven segments in the market. Display comprises of four 4x7 matrices with a colon and a decimal point which is driven by two MAX7221. RTC is DS1307 with DS32KHz crystal. Temperature sensor is DS18S20. The brain of the clock is gigantic 40 pin PIC16F877A with 8k code space. Everything is assembled inside a plastic box file. Working with the two display drivers (MAX7221) was not that difficult but they didn’t work without the two 0.1uF capacitors close by. Program was slightly modified to accommodate two display drivers with the new numeric font. I designed several fonts and finally settled with the one shown.
Friday, September 12, 2008
PIC CLOCK FINAL VERSION
As promised in the earlier post, here comes the photos and a video of the PIC CLOCK using the DS1307. The features of the clock are;
1. Displaying the Time, date, month and year
2. Displaying the Temperature
3. Display Time, Date & Month and Temperature Alternatively
4. Battery backup
5. Display illumination reduced at night (From 10pm to 6am)
6. Highly accurate. (DS1307 RTC and temperature compensated crystal DS32kHz)
The following video shows how the clock is in action. It displays Time, date and temperature alternatively. All the parameters (hour, minute, second, date, month, year etc.) can be set by selecting the appropriate mode and increment buttons. Display blinks when entered into the change mode. There are modes to display Time, Seconds, Date , Year and Temperature continuously. Everything is fixed inside a floppy disk box. I'm gonna wrap it with something to hide the internals, may be with a dark sticker.
Some pictures of the clock in different angles;
Parts List
1. Displaying the Time, date, month and year
2. Displaying the Temperature
3. Display Time, Date & Month and Temperature Alternatively
4. Battery backup
5. Display illumination reduced at night (From 10pm to 6am)
6. Highly accurate. (DS1307 RTC and temperature compensated crystal DS32kHz)
The following video shows how the clock is in action. It displays Time, date and temperature alternatively. All the parameters (hour, minute, second, date, month, year etc.) can be set by selecting the appropriate mode and increment buttons. Display blinks when entered into the change mode. There are modes to display Time, Seconds, Date , Year and Temperature continuously. Everything is fixed inside a floppy disk box. I'm gonna wrap it with something to hide the internals, may be with a dark sticker.
Some pictures of the clock in different angles;
Parts List
PIC16F628A microcontroller
DS1307 Real Time Clock IC
DS32kHZ Crystal
MAX7219/21 Display Driver
DS18S20 Temperature Sensor
4 Seven Segment LED Displays
2 AA Battery Holder (3v)
7805 5v regulator
9v ac power pack
IC holders, wire, vero board and lots of patience
Code snippets I used for the project;
Defining the SPI & I2C connection in PORTB. Display driver MAX7221 uses SPI while DS1307 RTC uses I2C.
Initializing the RTC.
Initialize MAX7221
Display the values using MAX7221
Reading & writing to the RTC
Read Temperature (DS18S20) & Display
To display time, date and to edit the parameters, I wrote separate modules using the above basic building blocks. If somebody needs the schematic and the complete source / hex, drop me an email or leave a comment with the email address. I used Mikroelektronika forum (http://www.mikroe.com/forum/) heavily and almost all the above coding segments are taken from the forum. Therefore, full credit goes to all the people who contributed to the forum.
Defining the SPI & I2C connection in PORTB. Display driver MAX7221 uses SPI while DS1307 RTC uses I2C.
void InitMain() {
Soft_Spi_Config(&PORTB, 4, 5, 3);
Soft_I2C_Config(&PORTB, 0, 1);
}//~
Initializing the RTC.
void ds1307_init(){
char seconds=0;
Soft_I2C_Start();
Soft_I2C_Write(0xD0); // WR to RTC
Soft_I2C_Write(0x00); // REG 0
Soft_I2C_Start();
Soft_I2C_Write(0xD1); // RD from RTC
seconds = Bcd2Dec(Soft_I2C_Read(1)& 0x7F); // Read current "seconds" in DS1307
Soft_I2C_Stop();
Delay_us(3);
Soft_I2C_Start();
Soft_I2C_Write(0xD0); // WR to RTC
Soft_I2C_Write(0x00); // REG 0
Soft_I2C_Write(Dec2Bcd(seconds)); // Start oscillator with current "seconds value
Soft_I2C_Start();
Soft_I2C_Write(0xD0); // WR to RTC
Soft_I2C_Write(0x07); // Control Register
Soft_I2C_Write(0x80); // Disable squarewave output pin
Soft_I2C_Stop();
}//~end of function
Initialize MAX7221
void max7219_init1() {
PORTA &= 0xFD; // SELECT MAX
Soft_SPI_write(0x09); // BCD mode for digit decoding
Soft_SPI_write(0xFF);
PORTA |= 2; // DESELECT MAX
PORTA &= 0xFD; // SELECT MAX
Soft_SPI_write(0x0A);
Soft_SPI_write(0x03); // Segment luminosity intensity
PORTA |= 2; // DESELECT MAX
PORTA &= 0xFD; // SELECT MAX
Soft_SPI_write(0x0B);
Soft_SPI_write(0x03); // Display refresh
PORTA |= 2; // DESELECT MAX
PORTA &= 0xFD; // SELECT MAX
Soft_SPI_write(0x0C);
Soft_SPI_write(0x01); // Turn on the display
PORTA |= 2; // DESELECT MAX
PORTA &= 0xFD; // SELECT MAX
Soft_SPI_write(0x00);
Soft_SPI_write(0xFF); // No test
PORTA |= 2; // DESELECT MAX
}
Display the values using MAX7221
void Write_7219(int x, int y) {
PORTA &= 0xFD;
Soft_SPI_write(x); // send i to max7219 (digit place)
Soft_SPI_write(y);
PORTA |=2;
}
Reading & writing to the RTC
unsigned short read_ds1307(unsigned short address)
{
Soft_I2C_Start();
Soft_I2C_Write(0xd0);
Soft_I2C_Write(address);
Soft_I2C_Start();
Soft_I2C_Write(0xd1);
data=BCD2DEC(Soft_I2C_Read(0));
Soft_I2C_Stop();
return(data);
}
void Write_DS1307(unsigned short Address, unsigned short _Data) {
Soft_I2C_Start(); // start a serial transfer
Soft_I2C_Write(0xD0); // which device, 1101000 = DS1307, + direction bit (R=1,W=0)
// thus 11010000 = 0xD0 ie write to DS1307
// need to tell the DS1307 which address is to be written to
Soft_I2C_Write(Address); // send the address to be written to the DS1307
Soft_I2C_Write(_Data); // send actual data to be written into Address on the DS1307
Soft_I2C_Stop(); // finished serial transfer (and release the I2C bus)
}
Read Temperature (DS18S20) & Display
void Read_temp()
{
ow_reset(&PORTB,2); // onewire reset signal
ow_write(&PORTB,2,0xCC); // issue command to DS1820
ow_write(&PORTB,2,0x44) ;
delay_us(120);
ow_reset(&PORTB,2);
ow_write(&PORTB,2,0xCC); // issue command to DS1820
ow_write(&PORTB,2,0xBE);
delay_ms(500);
j1 = ow_read(&PORTB,2); // get result
_Decimal = j1 & 0x01 ;
j1 = j1 >> 1 ;
}
void display_temp()
{
Read_temp();
j = j1%10;
j = j+0x80;
Write_7219(2,j);
j = j1/10 ;
Write_7219(1,j);
if (_decimal==0)
Write_7219(3,0x00);
else
Write_7219(3,0x05);
Write_7219(4,0x0F);
}
To display time, date and to edit the parameters, I wrote separate modules using the above basic building blocks. If somebody needs the schematic and the complete source / hex, drop me an email or leave a comment with the email address. I used Mikroelektronika forum (http://www.mikroe.com/forum/) heavily and almost all the above coding segments are taken from the forum. Therefore, full credit goes to all the people who contributed to the forum.
Wednesday, August 27, 2008
PIC Clock - with DS1307
After so many sleepless nights I managed to run a clock using a PIC, this time using the Maxim RTC chip, DS1307. This time I didn't use multiplexing to drive the four seven segments, instead I used another Maxim product, MAX7221 display driver. It has SPI interface and can drive upto 8 seven segments with display brightness control and that is cool... Since I'm using the PIC16F628 at the moment, I had to use Sotware SPI to drive the display. It worked without giving much problems but later came the most difficult part, DS1307. Oh boy, what a mess... It gave me thousand and one problems and took nearly a month to get it worked. But truly speaking I leaned a lot and mastered the DS1307. This fellow is really great and extremely easy to communicate via the I2C interface. I had problems because I used Software I2C routines in MikroC. I think SOFT_I2C has a problem with PORTA and after so many trial and error attempts it worked when I moved the DS1307 to PORTB. Now both DS1307 (I2C) and MAX7221 (SPI) are in PORTB and work without any trouble. DS1307 needs an external crystal (32.768kHz) to operate and again Maxim has another great product DS32KHZ, a temperature compensated 32.768kHz crystal which I found extremely accurate. So far the clock is running smoothly and accurately, which needs lot of other things, a way to set time, view calendar, set alarm etc. And I'm thinking of attaching a Temperature sensor too. Pictures, videos, schematic and code segments will appear shortly.
Wednesday, July 30, 2008
LED (OIL) LAMP
This time I am using another PIC, 16F628, which is better than 16F84 in number of ways. It has internal Oscillator, more IO pins, PWM, more space (twice) etc. As my first program with 16F628, I wrote this quick and dirty code segment to simulate an oil lamp. It uses the built in PWM to change the duty cycle of the LED.
Here is the video
Here is the code in MikroC
Here is the video
Here is the code in MikroC
unsigned short j, oj,i;
void InitMain() {
PORTB = 0x0; // set PORTB to 0
TRISB = 0; // designate PORTBpins as output
PWM_Init(5000); // initialize PWM module
}//~
void main() {
CMCON=7;
initMain();
j = 127; // initial value for j
oj = 0; // oj will keep the 'old j' value
PWM_Start(); // start PWM
while (1) { // endless loop
j=rand(); // Generate Random Number
if (j>=255)
j=254;
if (j==0)
j=1;
if (j>oj)
{
for (i=oj;i<=j;i++)
PWM_Change_Duty(i); //Smoothen the level change
}
else
if (j{
for (i=oj;i>=j;i--)
PWM_Change_Duty(i);
}
else
PWM_Change_Duty(j); // set new duty ratio,
oj = j; // memorize it
PORTB = oj; // and display on PORTB
Vdelay_ms(200+j); // slow down change pace a little
}
}//~!
PIC Clock - Final Version
My PIC clock is almost done. Only thing remaining is that to give it a nice look. (at the moment, it is inside an ice cream box and it deserves a better place than that). It has following functionalities;
• 12H/24H mode; when in 12H mode, a PM indicator is used.• Battery backup; when the mains power is not available, it automatically gets power from the batteries and keeps the clock ticking.
• Ability to work totally on batteries. i.e. When the mains power is not available, it automatically switches into battery mode and the display goes blank. But if you want to see the time, you can get back the normal display manually.
Here are some pics
(Video quality is not that great but clear enough to see that the clock is running :-) )
Thursday, June 26, 2008
Convocation
Yesterday, I got my MBA in IT at the General Convocation of University of Moratuwa. I started my MBA early 2006 and continued it through 2006 and 2007, occupying every single free time slot. Still I cant believe that I completed it having 3.76 GPA and 'A' pass for the Research Project. I had the opportunity to publish and present a paper at International Conference of Business Management held at University of Jayawardanapura (ICBM 2008). I was thrilled to see most of my colleagues got their MBA titles yesterday, but there were several who aren't that fortunate. I missed the accompany of my beloved wife (she too graduated in the convocation) since she was out of the country. She went to present a paper in an IEEE conference in Canada.
Friday, May 23, 2008
PIC Clock
Finally I managed to build the initial version of the Desktop clock using PIC16F84. Still its in the vero board as you see in below video.
It shows Time (Hour, Minute) and Seconds alternatively. It has two buttons to advance hours and minutes. An Interrupt routine is used to calculate the base time and to multiplex the four seven segments. The program is written in C and compiled using MikroC compiler. I got lot of ideas from so many people and used code samples from various resources. Specially the MikroC comes with very useful code samples. Here is the program listing. It is not optimized yet. You'll find unused variables here and there. Comments and suggestions are welcome.
Display_utils.h file
It shows Time (Hour, Minute) and Seconds alternatively. It has two buttons to advance hours and minutes. An Interrupt routine is used to calculate the base time and to multiplex the four seven segments. The program is written in C and compiled using MikroC compiler. I got lot of ideas from so many people and used code samples from various resources. Specially the MikroC comes with very useful code samples. Here is the program listing. It is not optimized yet. You'll find unused variables here and there. Comments and suggestions are welcome.
#include "Display_utils.h"
char kraj;
unsigned short zz, v, j, countsec,displaysec;
//unsigned int i;
unsigned short por[4];
unsigned char sec, mins, hrs, ticks, correction;
char oldstate_min, oldstate_hr;
void interrupt() {
if(INTCON.T0IF)
{
ticks++;
correction++;
TMR0=101; //96; //102
if (correction==180) // Correction routine
{
ticks--;
correction=0;
}
}
PORTA = ~0;
PORTB = por[v];
PORTA = ~zz; // turn on appropriate 7seg. display
zz <<= 1;
if (zz > 8u)
zz = 1; // prepare mask for digit
v++ ;
if (v > 3u)
v = 0; // turn on 1st, turn off 2nd 7seg.
//Delay_ms(1);
//TMR0 = 0;
INTCON = 0x20;
}//~
void main() {
OPTION_REG = 0x84;
j = 0;
v = 0;
zz = 1;
TMR0 = 101;
INTCON = 0xA0; // Disable PEIE,INTE,RBIE,T0IE
PORTA = ~0;
TRISA = 0;
PORTB = 0;
TRISB = 0;
sec=0;
mins=0;
ticks=0;
correction=0;
hrs=0;
oldstate_min=0;
oldstate_hr=0;
do {
if (ticks==200)
{
sec++;
countsec++;
ticks=0;
//if (PORTB.F7==1)
// {
// PORTB.F7=1;
// }
// else
// {
// PORTB.F7=0;
// }
//}
if (sec>59)
{
mins++;
sec=0;
//}
if (mins>59)
{
hrs++;
mins=0;
//}
if (hrs>23)
{
hrs=0;
}
}
}
}
TRISB=0b00000011;
if (Button(&PORTB, 0, 1, 1))
oldstate_min = 1;
if (oldstate_min && Button(&PORTB, 0, 1, 0)) {
mins++;
if (mins>59)
mins=0;
oldstate_min = 0;
}
if (Button(&PORTB, 1, 1, 1))
oldstate_hr = 1;
if (oldstate_hr && Button(&PORTB, 1, 1, 0)) {
hrs++;
if (hrs>23)
hrs=0;
oldstate_hr = 0;
}
TRISB=0b00000000;
if (countsec==5)
{
countsec=0;
if (displaysec==1)
{
displaysec=0;
}
else
{
displaysec=1;
}
}
if (displaysec==0)
{
por[0]=mask(hrs/10u);
j=(char)(hrs%10u);
por[1]=mask(j);
por[3]=mask(mins/10u);
j=(char)(mins%10u);
por[2]=mask(j);
}
else
{
por[0]=mask(5);
//j=(char)(mins%10u);
por[1]=mask(11);
por[3]=mask(sec/10u);
j=(char)(sec%10u);
por[2]=mask(j);
}
} while(1); // endless loop
}//~
Display_utils.h file
//-------------- Returns mask for common cathode 7-seg. display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x3F;
case 1 : return 0x06;
case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
case 11 : return 0x79;
} //case end
}//~
Thursday, February 21, 2008
PIC Programming
Programming a micro controller has been in my mind for nearly a decade. I have done micro controller programming when I was an under graduate. That was for the 8080 processor. It is too big for small projects. I was looking for a suitable type of micro since there are couple of good ones PICs and AVRs. But I couldn't find any AVRs in the market but PICs are available for an affordable price. I bought two PICs, 16F877A and 16F84A, for Rs. 460/- and Rs. 320/- respectively.
The first step was to build a programmer (burner). I saw different types of programmers but thought of building a JDM type one. It has the advantage of operating without an external power supply and is much simpler to build. It takes power from the PC serial port. The disadvantage is, modern laptops cannot provide the required voltage level. Since most of the laptops (including mine) do not have a serial port, it has no effect.
Found the following circuit and built it on a vero board. It can program PICs upto 40 pins so there wont be any problem for a long time. (Full credit goes to the designer of the circuit, I just build his circuit)
This is how the final one looks like;
Then needed the software to connect the hardware to the PC. After reading many comments, I wanted to settle with IC-Prog. It is a great software which supports many types of programmers including the JDM. It also has a hardware test option to verify the hardware. Initially it didn't verify my hardware correctly and after so many sleepless nights, I found the bug. I have connected the Serial port incorrectly; more precisely, I have swapped the left hand side and the right hand side of the port. After rearranging, it worked like a charm.
I tested the programmer and the PIC using the famous "hello world" LED blinking program which ended quite successfully. Then I wrote a counting program using two seven segment LEDs with 16F84. Two segments are in multiplexed mode. The following video shows it in action.
These are my future plans with PICs.
- Build a clock with small digits (desktop clock)
- Build a wall clock with a big display
- Include the stealth mode to the clocks. i.e. it will retain its time when there is no mains power. I hope to use a real time clock IC like DS1307 or DS1302 with a battery backup.
- Include a thermometer function to the clock to display the room temperature. For this, I will use DS1820 IC.
Although I already have necessary hardware i.e PICs, clock ICs, temperature ICs (I got them from Dallas Semiconductors as samples), writing software takes a lot of time. Therefore it is impossible to figure out how long it will take to complete the above things. May be before next Christmas... :-)
The first step was to build a programmer (burner). I saw different types of programmers but thought of building a JDM type one. It has the advantage of operating without an external power supply and is much simpler to build. It takes power from the PC serial port. The disadvantage is, modern laptops cannot provide the required voltage level. Since most of the laptops (including mine) do not have a serial port, it has no effect.
Found the following circuit and built it on a vero board. It can program PICs upto 40 pins so there wont be any problem for a long time. (Full credit goes to the designer of the circuit, I just build his circuit)
This is how the final one looks like;
Then needed the software to connect the hardware to the PC. After reading many comments, I wanted to settle with IC-Prog. It is a great software which supports many types of programmers including the JDM. It also has a hardware test option to verify the hardware. Initially it didn't verify my hardware correctly and after so many sleepless nights, I found the bug. I have connected the Serial port incorrectly; more precisely, I have swapped the left hand side and the right hand side of the port. After rearranging, it worked like a charm.
I tested the programmer and the PIC using the famous "hello world" LED blinking program which ended quite successfully. Then I wrote a counting program using two seven segment LEDs with 16F84. Two segments are in multiplexed mode. The following video shows it in action.
These are my future plans with PICs.
- Build a clock with small digits (desktop clock)
- Build a wall clock with a big display
- Include the stealth mode to the clocks. i.e. it will retain its time when there is no mains power. I hope to use a real time clock IC like DS1307 or DS1302 with a battery backup.
- Include a thermometer function to the clock to display the room temperature. For this, I will use DS1820 IC.
Although I already have necessary hardware i.e PICs, clock ICs, temperature ICs (I got them from Dallas Semiconductors as samples), writing software takes a lot of time. Therefore it is impossible to figure out how long it will take to complete the above things. May be before next Christmas... :-)
Subscribe to:
Posts (Atom)