Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Automatic school bell with PIC16F877A

Status
Not open for further replies.

jean12

Advanced Member level 2
Joined
Aug 27, 2013
Messages
529
Helped
5
Reputation
12
Reaction score
6
Trophy points
18
Activity points
5,497
Hello,I would ike to make a school bell which might be set to be automatic or manual using push buttons,could you advice on the usage of timer 1 of PIC16F877A in Microc(unfortunately I am not familiar with Microc).
I have seven period: Of 50minutes and one period on 20minutes.
could anyone help me on the implementation of this?

Thank you!!
 

Yes, I can help you with making the School bell but you have to mention the Compiler you will be using and the crystal frequency. Explain how the school bell should work in manual and auto modes.
 

Yes, I can help you with making the School bell but you have to mention the Compiler you will be using and the crystal frequency. Explain how the school bell should work in manual and auto modes.
Hey,thank you I am using a quartz of 4MHZ and a PIC16F877A,I have three push button
*The first push button is for making the school bell in manual operation by activating the siren at the output of the PIC
*The second Push button is pushed at the starting and ending of operation of the eight periods we have which are:

1.8:00-8:50 :50minutes
2.8:50-9:40:50 minutes
3.9:40-10:30:50minutes

4.10:00-10:50:20minutes
5.10:50-11:40:50minutes
6.11:40-12:30:50minutes
7.12:30-13:20:50minutes
8.13:20-14:10:50minutes

*The last push button,the third one is for setting the time just minutes.

I also have LCD for displaying at which hour we are and some customizable text.

Thx
 

Ok. Should I design the circuit or do you have it ? Which Compiler to be used ?
 

To me this sounds like it is half automatic when it could be fully automatic.

Jean12, why not just make a real time clock with those times programmed in to it? In other words, have buttons to set the time of day and an 'override' to operate the bell manually and then make it ring at each of the times in your list. It's quite easy to do without having to manually start each period.

Brian.
 

Hello pic.rogrammer I am using Microc,I have a circuit which I use for simulation in proteus.
The circuit is here attached!!

Thx

- - - Updated - - -

Hello,I have never used those DSO1307 or other RTC,that is why I want the simplest and then in the future I should run how those RTC are interfaced to pic.I want simple codes.
 
Last edited:

You misunderstand me. You don't need to interface an external RTC device, just make the PIC keep time for itself. The technique I usually use is to make Timer 1 cause an interrupt every 100mS (1/10 second), then on every tenth interrupt, a seconds variable is incremented. This is a snippet of code from one of my products:
Code:
	// RTC timekeeping (based on TMR1 interrupt)
	if(SecondElapsed)
	{
		SecondElapsed = 0;
		Se++;		
		if(Se == 60)
		{
			Se = 0;
			Mi++;
			if(Mi == 60)
			{
				Mi = 0;
				Hr++;
				if(Hr == 24)
				{
					Hr = 0;
					Da++;
					if(Da > DaysInMonth)
					{
						Da = 1;
						Mo++;
						{
							if(Mo > 12)
							{
								Mo = 1;
								Yr++;
							}
						} 
					} 
				} 
			} 
		}
It keeps not only the time but the date as well. It isn't the full code but you can see how easy it is to keep track of time using only software.

Brian.
 

could you please help me to set those,I might understand it very well but I know using timers in assembly only ,I am trying to learn it in Microc which looks understandable to many persons,so could you please help me to set that school bell with those period I defined above?

Thank you!!
 

I don't use MikroC, I find it a terrible program! This is the way I would do it though:

1. set up Timer 1 to overflow at 100mS intervals and enable the Timer1 interrupt
2. create an ISR to service Timer1 interrupts, in it count a variable from 9 to 0 (10 counts), reset the interrupt and timer value then set a flag if the variable is zero.
3. in your main program loop, look for that flag being set and use it to 'tick' the real time clock like I showed in my example code.
4. multiply the hour value by 60 and add the minutes value to it, this gives you a number of minutes since midnight.
5. calculate the minutes past midnight of each of your 'bell' events
6. if the real time minutes value is equal to the event minutes value, ring the bell.

So essentially, you have a 'live' minutes count from zero at midnight to 1439 at 23:59 and a set of numbers representing the times of your events. For example your first bell at 8:00 has a value of (8 * 60) + 0 = 480 so when the calculated minutes from midnight is also equal to 480 it means it's time for the 8:00 bell to operate.

Brian.
 

For designs which have clock function, I usually prefer embed external IC RTCs to work with the microcontroller, due to its ability to keep operating after equipment got powered off, as well the better accuracy that can often achieve if compared to that obtained by the 16-bits uC timer. Rare were the cases that I could fine-tune the timer reload with the prescaler without having to either sacrifice some core processing to fit the maximum resolution, or suffer to find supplier to the suited crystal for the built-in oscillator.
 

My code would be same as betwixt's code but there is one issue. If power fails then even if you store the time before power failure in eeprom you would not know how much time you have to add to the time after power is restored. Power failure might not be a problem at your place but it is here. Here there will be 4 to 6 hours power cut daily. If your device is battery operated then Timer Interrupt can be used to increment sec, min, hr variables and the code can be made.

In post #6 I don't see the circuit you attached. Please zip and post the Proteus file.
 

View attachment circuit.rar
My code would be same as betwixt's code but there is one issue. If power fails then even if you store the time before power failure in eeprom you would not know how much time you have to add to the time after power is restored. Power failure might not be a problem at your place but it is here. Here there will be 4 to 6 hours power cut daily. If your device is battery operated then Timer Interrupt can be used to increment sec, min, hr variables and the code can be made.

In post #6 I don't see the circuit you attached. Please zip and post the Proteus file.

Hi,find the circuit in attachment,the complete school bell will be working being supplied by a battery so the use of Timer 1 is the best.

Thank you for helping
 

Hello,betwixt,whatever you use could you code a little bit for me?I don`t know how to set up ISR and interrupt in microc,in any C language you may use could you help?Pls

Thx
 

Have you write some code of your own for your project?
You can post it here so we can edit/extend as required for you.
 

I can help but first, tell me what crystal frequency you plan to use, it needs to be known so the timing intervals can be set.

Brian.
 

I am using 4MHZ quartz with PIC16F877A.

Thx

- - - Updated - - -

View attachment circuit.rarHello,find the codes I am trying here;unfortunately they are not working,find the circuit also.

Code:
sbit LCD_RS at RC4_bit;
sbit LCD_EN at RC5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
       unsigned short count=0;
       int i=0;


void main()
{
      TRISD=0x00;
      TRISC=0b00111000;
      PIE1.TMR1IE=1;
      INTCON=0XC0;
      T1CON=0X01;

     while(1)
      {
          if(PORTC.F3==0)       //use manual button to activate the siren
          {
           delay_us(5);         //delay for study state establishment
           PORTC.F7=1;        //output high on siren
           delay_ms(2000);
           PORTC.F7=0;
          }
     if(PORTC.F4==0) //set Timer values for automatic mode operation
            {
            for (i=0;i<=7;i++)
            {
          void interrupt();
            {
              if(PIR1.TMR1IF==1)
               {
               count++;
               T1CON.TMR1IF=0;
               if(count==10)
    PORTC.F7=1;
    delay_ms(1000);
    PORTC.F7=0;
    TMR1H    = 0x00;
    TMR1L    = 0x00;
     }
     }
        }
        }
       }
}
 

The best solution is used RTC chip.
If you only used PIC,you can create a soft timer based on TIMER 1 or other Timers,
then,you can Create some Variable to count time by add 1 in soft timer,
you must have a function to manage those Variable in main().
 

hello,can you help to manage those functions?

thx
 

Hello,can any body help me to collect this,with my school bell I found 7 periods as follows:
1.8h00-8h40:Learning time
2.8h40-9h20:Learning time
3.9h20-10h00:Learning time
4.10h00-10h20:Break time
5.10h20-11h40:Learning time
6.11h40-12h20:Learning Time
7.12h20-13h00:Learning time
8.13h00-13h40:Learning time

Except the 4th(break time) which has 20minutes others has 40 minutes,could you please help with the timer usage below ti find out why it is not working?

Find the codes here below,in place of siren I am using a LED on PORTC.F7 of PIC16F877A,I am using Microc comi
Code:
int count,minute,t=0;
void main(void)
 {
  T1CON=1;
  TRISC.F7=0X00;
  TRISD.F1=0X00;
  TRISD.F2=0X00;
  PORTD.F2=0;
  PORTD.F1=0;
  PORTC.F7=0;
  while(1)
  {
  while(PIR1.TMR1IF==0) ;
    PIR1.TMR1IF=0;
      count++;
      if(count==150)    //1s=15  I am using low value for just testing purposes 150=10s
      {
      count=0;
            minute++;
            if(minute==6)   //if minute=6,we now have 1minute=60seconds I assumed one period=60seconds or 1 minute
            {
             t++;
              PORTC.F7=1;
              delay_ms(2000);
              PORTC.F7=0;
            }
               if((t==5)&&(minute==2))
              {
               PORTD.F2==1;

              }
              }
              }
              }
 

Hi

I still have not understood how your buttons work in manual and auto modes. Explain in detail how they work so that I can write a code for you.

Here I am posting a code which is not complete. Auto mode code is implemented and you have to start the system at 12:00 Am that is 00:00:00 and keep it running and then the alarm will sound for 10 seconds when the different alarm times occur. Manual mode have to be coded. You had used two buttons for manual and auto modes. I have made changes. I have only used one button with one LED (RD3) to select between manual and auto modes. The LED will indicate if it is manual or auto mode. If RD3 LED is ON than it is auto mode.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// Lcd pinout settings
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RC6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;
 
// Pin direction
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
 
sbit MODE_SWITCH at RC3_bit;
sbit MODE_LED at RD3_bit;
 
struct schoolTime {
    unsigned char second;
    unsigned char minute;
    unsigned char hour;
}alarmTime, startTime, periodOneTime, periodTwoTime, periodThreeTime, breakTime, periodFourTime, periodFiveTime, periodSixTime, periodSevenTime;
 
unsigned char myFlags = 0, halfSecondCounter = 0, alarmDelayCounter = 0;
char msg[22];
 
const char msg1[] = "School Bell";
 
sbit updateTimeFlag at myFlags.B0;
sbit modeFlag at myFlags.B1;
sbit alarmFlag at myFlags.B2;
 
#define ON 1
#define OFF 0
 
#define ENABLE 1
#define DISABLE 0
 
#define TRUE 1
#define FALSE 0
 
#define SET 1
#define CLEAR 0
 
#define UPDATE_TIME_FLAG_IS_SET (updateTimeFlag == 1)
#define CLEAR_UPDATE_TIME_FLAG {updateTimeFlag = 0;}
 
#define ENABLE_WATCHDOG_TIMER {OPTION_REG = 0xCF;}
 
#define MANUAL_MODE (modeFlag == 0)
#define AUTO_MODE (modeFlag == 1)
 
#define MODE_SWITCH_PRESSED (!RC3_bit)
#define MODE_SWITCH_NOT_YET_RELEASED (!RC3_bit)
 
#define START_OF_CLASSES ((alarmTime.hour == startTime.hour) && (alarmTime.minute == startTime.minute))
#define PERIOD_ONE_OVER ((alarmTime.hour == periodOneTime.hour) && (alarmTime.minute == periodOneTime.minute))
#define PERIOD_TWO_OVER ((alarmTime.hour == periodTwoTime.hour) && (alarmTime.minute == periodTwoTime.minute))
#define PERIOD_THREE_OVER ((alarmTime.hour == periodThreeTime.hour) && (alarmTime.minute == periodThreeTime.minute))
#define BREAK_OVER ((alarmTime.hour == breakTime.hour) && (alarmTime.minute == breakTime.minute))
#define PERIOD_FOUR_OVER ((alarmTime.hour == periodFourTime.hour) && (alarmTime.minute == periodFourTime.minute))
#define PERIOD_FIVE_OVER ((alarmTime.hour == periodFiveTime.hour) && (alarmTime.minute == periodFiveTime.minute))
#define PERIOD_SIX_OVER ((alarmTime.hour == periodSixTime.hour) && (alarmTime.minute == periodSixTime.minute))
#define PERIOD_SEVEN_OVER ((alarmTime.hour == periodSevenTime.hour) && (alarmTime.minute == periodSevenTime.minute))
 
#define SET_ALARM_FLAG {alarmFlag = 1;}
#define CLEAR_ALARM_FLAG {alarmFlag = 0;}
 
#define ALARM_FLAG_IS_SET (alarmFlag == 1)
#define ALARM_FLAG_IS_NOT_SET (alarmFlag == 0)
 
//Timer1
//Prescaler 1:8; TMR1 Preload = 3036; Actual Interrupt Time : 500 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x31;
    TMR1IF_bit = 0;
    TMR1H = 0x0B;
    TMR1L = 0xDC;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}
 
//copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
    char *d;
 
    asm clrwdt
    d = dest;
    for(;*dest++ = *src++;);
    asm clrwdt
    return d;
}
 
void DebounceSwitch() {
    Delay_ms(50);
}
 
void StartAlarm() {
    PWM1_Start();
}
 
void StopAlarm() {
    PWM1_Stop();
}
 
void Interrupt() {
    if(TMR1IF_bit) {
        TMR1IF_bit = 0;
        TMR1H = 0x0B;
        TMR1L = 0xDC;
        //Enter your code here
        if(++halfSecondCounter == 2) {
                halfSecondCounter = 0;
                updateTimeFlag = 1;
        }
        
        if(ALARM_FLAG_IS_SET) {
            ++alarmDelayCounter;
            if(alarmDelayCounter == 20) {
                     StopAlarm();
            }
            else if(alarmDelayCounter == 130) {
                     CLEAR_ALARM_FLAG
                     alarmDelayCounter = 0;
            }
        }
    }
}
 
void SetTime() {
     startTime.second = 0;
     startTime.minute = 0;
     startTime.hour = 8;
     
     periodOneTime.second = 0;
     periodOneTime.minute = 40;
     periodOneTime.hour = 8;
     
     periodTwoTime.second = 0;
     periodTwoTime.minute = 20;
     periodTwoTime.hour = 9;
     
     periodThreeTime.second = 0;
     periodThreeTime.minute = 0;
     periodThreeTime.hour = 10;
     
     breakTime.second = 0;
     breakTime.minute = 20;
     breakTime.hour = 10;
     
     periodFourTime.second = 0;
     periodFourTime.minute = 0;
     periodFourTime.hour = 11;
     
     periodFiveTime.second = 0;
     periodFiveTime.minute = 40;
     periodFiveTime.hour = 11;
     
     periodSixTime.second = 0;
     periodSixTime.minute = 20;
     periodSixTime.hour = 12;
     
     periodSevenTime.second = 0;
     periodSevenTime.minute = 0;
     periodSevenTime.hour = 13;
}
 
void main() {
 
     ENABLE_WATCHDOG_TIMER
     
     asm clrwdt
     
     CMCON = 0x07;
     CVRCON = 0x00;
     
     ADCON1 = 0x87;
     
     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x38;
     TRISD = 0x00;
     TRISE = 0x00;
     
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     PORTE = 0x00;
     
     asm clrwdt
     
     Delay_ms(200);
     
     asm clrwdt
     
     LCD_Init();
     Delay_ms(100);
     asm clrwdt
     
     LCD_Cmd(_LCD_CURSOR_OFF);
     LCD_Cmd(_LCD_CLEAR);
     
     LCD_Out(1,1,CopyConst2Ram(msg, msg1));
 
     asm clrwdt
     
     PWM1_Init(1500);
     PWM1_Set_Duty(127);
     PWM1_Stop();
     
     asm clrwdt
     
     SetTime();
 
     InitTimer1();
     
     asm clrwdt
     
     while(1) {
     
            asm clrwdt
            
            if(UPDATE_TIME_FLAG_IS_SET) {
                 asm clrwdt
                 
                 if(++alarmTime.second == 60) {
                         alarmTime.second = 0;
                         if(++alarmTime.minute == 60) {
                               alarmTime.minute = 0;
                               if(++alarmTime.hour == 24) {
                                      alarmTime.second = 0;
                                      alarmTime.minute = 0;
                                      alarmTime.hour = 0;
                               }
                         }
                 }
 
                 asm clrwdt
                 LCD_Chr(2,1,(alarmTime.hour / 10) + 48);
                 LCD_Chr(2,2,(alarmTime.hour % 10) + 48);
                 asm clrwdt
                 LCD_Chr(2,3,':');
                 asm clrwdt
                 LCD_Chr(2,4,(alarmTime.minute / 10) + 48);
                 LCD_Chr(2,5,(alarmTime.minute % 10) + 48);
                 asm clrwdt
                 LCD_Chr(2,6,':');
                 asm clrwdt
                 LCD_Chr(2,7,(alarmTime.second / 10) + 48);
                 LCD_Chr(2,8,(alarmTime.second % 10) + 48);
                 asm clrwdt
                 CLEAR_UPDATE_TIME_FLAG
            }
            
            if(MODE_SWITCH_PRESSED) {
                 DebounceSwitch();
                 while(MODE_SWITCH_NOT_YET_RELEASED)asm clrwdt;
                 
                 modeFlag = ~modeFlag;
                 RD3_bit = modeFlag;
            }
            
            if(MANUAL_MODE) {
            
            }
            else if(AUTO_MODE) {
                if(ALARM_FLAG_IS_NOT_SET) {
                    if((START_OF_CLASSES) || (PERIOD_ONE_OVER) || (PERIOD_TWO_OVER) || (PERIOD_THREE_OVER) 
                      || (BREAK_OVER) || (PERIOD_FOUR_OVER) || (PERIOD_FIVE_OVER) || (PERIOD_SIX_OVER) 
                      || (PERIOD_SEVEN_OVER)) {
                                  SET_ALARM_FLAG
                                  StartAlarm();
                    }
                }
            }
     }
}

 

Attachments

  • School Bell incomplete.rar
    77.1 KB · Views: 155

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top