This piece of code
Code C - [expand] |
1
2
3
4
| if(++blink_counter == 20) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
} |
can be moved out of the
Code:
if(led_flag == 0) {
and
if(led_flag == 1) {
This reduces code size.
- - - Updated - - -
That can be done but it will be a paid job. You can ask the question in EDA Jobs Section.
Use resistor before the bridge. You are converting 230V AC to DC and if anybody touches the output of bridge it will be dangerous.
How are you powering the PIC. If you are using power supply for PIC then you can use the output of power supply (unregulated) for measuring the mains voltage. It will be safer.
- - - Updated - - -
Here is the code.
0V input is 0V
5V input is 270V
If you scale the adc input voltage differently then change the multiplication factor in adc equation.
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
| #define ON 1
#define OFF 0
#define OK 1
#define ERROR 0
sbit SW at GP3_bit;
sbit Yellow_Led at GP5_bit;
sbit Green_Led at GP4_bit;
sbit Red_Led at GP2_bit;
unsigned char ten_seconds_delay_count = 20;
unsigned int three_minutes_delay_count = 360;
unsigned int counter = 0, blink_counter = 0;
unsigned char myFlags = 0;
unsigned int raw_adc_value = 0, previous_raw_adc_value = 0;
double mains_voltage = 0.0;
sbit led_flag at myFlags.B0;
sbit button_state at myFlags.B1;
sbit mains_status_flag at myFlags.B2;
//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;
INTCON = 0xC0;
}
void Interrupt() {
if((TMR1IE_bit) && (TMR1IF_bit)) {
//Enter your code here
if(led_flag == 0) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == ten_seconds_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
else if(led_flag == 1) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == three_minutes_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
}
}
void Turn_Off_Leds_And_Reset_Counters() {
Yellow_Led = OFF;
Green_Led = OFF;
counter = 0;
blink_counter = 0;
}
void Enable_Timer1_Interrupts() {
TMR1IE_bit = 1;
}
void main() {
CMCON = 0x07;
ANSEL = 0x51;
ADCON0 = 0x80;
TRISIO = 0x09;
GPIO = 0x00;
InitTimer1();
if(!SW) {
Delay_ms(50);
if(!SW) {
button_state = 0;
}
}
else if(SW) {
Delay_ms(50);
if(SW) {
button_state = 1;
}
}
while(1) {
raw_adc_value = ADC_Read(0);
Delay_us(15);
if(previous_raw_adc_value != raw_adc_value) {
mains_voltage = (double)raw_adc_value * 270.0 / 1023.0;
if(mains_voltage < 150.0) {
Red_Led = ON;
mains_status_flag = ERROR;
Turn_Off_Leds_And_Reset_Counters();
}
else if(mains_voltage > 240.0) {
Red_Led = ON;
mains_status_flag = ERROR;
Turn_Off_Leds_And_Reset_Counters();
}
else {
Red_Led = OFF;
mains_status_flag = OK;
}
previous_raw_adc_value = raw_adc_value;
}
if(mains_status_flag == OK) {
if((!SW) && (!button_state)){
Delay_ms(50);
if((!SW) && (!button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 0;
Enable_Timer1_Interrupts();
button_state = 1;
}
}
else if((SW) && (button_state)) {
Delay_ms(50);
if((SW) && (button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 1;
Enable_Timer1_Interrupts();
button_state = 0;
}
}
}
}
} |
- - - Updated - - -
This code is correct but it is not working in Proteus. Debugged the code for different adc values in mikroC PRO PIC Simulator and it works fine.
Use the attached Proteus file and Schematic.
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
| #define ON 1
#define OFF 0
#define OK 1
#define ERROR 0
sbit SW at GP3_bit;
sbit Yellow_Led at GP5_bit;
sbit Green_Led at GP4_bit;
sbit Red_Led at GP2_bit;
unsigned char ten_seconds_delay_count = 20;
unsigned int three_minutes_delay_count = 360;
unsigned int counter = 0, blink_counter = 0;
unsigned char myFlags = 0;
unsigned int raw_adc_value = 0, previous_raw_adc_value = 400;
double mains_voltage = 0.0;
sbit led_flag at myFlags.B0;
sbit button_state at myFlags.B1;
sbit mains_status_flag at myFlags.B2;
sbit run_once_flag at myFlags.B3;
//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;
INTCON = 0xC0;
}
void Interrupt() {
if((TMR1IE_bit) && (TMR1IF_bit)) {
//Enter your code here
if(led_flag == 0) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == ten_seconds_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
else if(led_flag == 1) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == three_minutes_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
}
}
void Turn_Off_Leds_And_Reset_Counters() {
Yellow_Led = OFF;
Green_Led = OFF;
counter = 0;
blink_counter = 0;
}
void Enable_Timer1_Interrupts() {
TMR1IE_bit = 1;
}
void main() {
asm clrwdt
OPTION_REG = 0x8F;
CMCON = 0x07;
ANSEL = 0x51;
ADCON0 = 0x80;
TRISIO = 0x09;
GPIO = 0x00;
InitTimer1();
if(!SW) {
Delay_ms(50);
if(!SW) {
button_state = 0;
}
}
else if(SW) {
Delay_ms(50);
if(SW) {
button_state = 1;
}
}
run_once_flag = 0;
while(1) {
asm clrwdt
raw_adc_value = (unsigned int)ADC_Read(0);
Delay_us(20);
if(previous_raw_adc_value != raw_adc_value) {
mains_voltage = (double)raw_adc_value * 288.5 / 1023.0;
if(mains_voltage <= 150.0) {
Red_Led = ON;
mains_status_flag = ERROR;
}
else if(mains_voltage >= 240.0) {
Red_Led = ON;
mains_status_flag = ERROR;
}
else {
Red_Led = OFF;
mains_status_flag = 1;
if(run_once_flag == 1) {
run_once_flag = 0;
}
}
if((mains_status_flag == ERROR) && (run_once_flag == 0)) {
Turn_Off_Leds_And_Reset_Counters();
run_once_flag = 1;
}
previous_raw_adc_value = raw_adc_value;
}
if(mains_status_flag == OK) {
if((!SW) && (!button_state)){
Delay_ms(50);
if((!SW) && (!button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 0;
Enable_Timer1_Interrupts();
button_state = 1;
}
}
else if((SW) && (button_state)) {
Delay_ms(50);
if((SW) && (button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 1;
Enable_Timer1_Interrupts();
button_state = 0;
}
}
}
}
} |
Fixed the code. It is working now. Mistake was in Proteus file. Had not labelled the ADC connection. Use only
PIC12F675 Based LED and Switch Project - Using Timer Interrupt - RevD.rar
Discard all previous files.
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
| #define ON 1
#define OFF 0
#define OK 1
#define ERROR 0
sbit SW at GP3_bit;
sbit Yellow_Led at GP5_bit;
sbit Green_Led at GP4_bit;
sbit Red_Led at GP2_bit;
unsigned char ten_seconds_delay_count = 20;
unsigned int three_minutes_delay_count = 360;
unsigned int counter = 0, blink_counter = 0;
unsigned char myFlags = 0;
unsigned int raw_adc_value = 0, previous_raw_adc_value = 400;
double mains_voltage = 0.0;
sbit led_flag at myFlags.B0;
sbit button_state at myFlags.B1;
sbit mains_status_flag at myFlags.B2;
sbit run_once_flag at myFlags.B3;
//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;
INTCON = 0xC0;
}
void Interrupt() {
if((TMR1IE_bit) && (TMR1IF_bit)) {
//Enter your code here
if(led_flag == 0) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == ten_seconds_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
else if(led_flag == 1) {
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
if(++counter == three_minutes_delay_count) {
counter = 0;
Green_Led = ON;
TMR1ON_bit = 0;
}
}
TMR1IF_bit = 0;
TMR1H = 0x0B;
TMR1L = 0xDC;
}
}
void Turn_Off_Leds_And_Reset_Counters() {
Yellow_Led = OFF;
Green_Led = OFF;
counter = 0;
blink_counter = 0;
}
void Enable_Timer1_Interrupts() {
TMR1IE_bit = 1;
}
void main() {
asm clrwdt
OPTION_REG = 0x8F;
CMCON = 0x07;
ANSEL = 0x51;
ADCON0 = 0x80;
TRISIO = 0x09;
GPIO = 0x00;
InitTimer1();
if(!SW) {
Delay_ms(50);
if(!SW) {
button_state = 0;
}
}
else if(SW) {
Delay_ms(50);
if(SW) {
button_state = 1;
}
}
run_once_flag = 0;
while(1) {
asm clrwdt
raw_adc_value = (unsigned int)ADC_Read(0);
Delay_us(20);
if(previous_raw_adc_value != raw_adc_value) {
mains_voltage = (double)raw_adc_value * 288.5 / 1023.0;
if(mains_voltage <= 150.0) {
Red_Led = ON;
mains_status_flag = ERROR;
}
else if(mains_voltage >= 240.0) {
Red_Led = ON;
mains_status_flag = ERROR;
}
else {
Red_Led = OFF;
mains_status_flag = OK;
if(run_once_flag == 1) {
run_once_flag = 0;
Turn_Off_Leds_And_Reset_Counters();
Enable_Timer1_Interrupts();
}
}
if((mains_status_flag == ERROR) && (run_once_flag == 0)) {
Turn_Off_Leds_And_Reset_Counters();
run_once_flag = 1;
TMR1IE_bit = 0;
}
previous_raw_adc_value = raw_adc_value;
}
if(mains_status_flag == OK) {
if((!SW) && (!button_state)){
Delay_ms(50);
if((!SW) && (!button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 0;
Enable_Timer1_Interrupts();
button_state = 1;
}
}
else if((SW) && (button_state)) {
Delay_ms(50);
if((SW) && (button_state)){
Turn_Off_Leds_And_Reset_Counters();
led_flag = 1;
Enable_Timer1_Interrupts();
button_state = 0;
}
}
}
}
} |
- - - Updated - - -
Final file. Timer Interrupt based RevD file.
- - - Updated - - -
Completed project. Tested and working.
Moved this piece of code
Code:
if(++blink_counter == 2) {
blink_counter = 0;
Yellow_Led = ~Yellow_Led;
}
outside the
conditions inside the ISR.
There is only 15% ROM free and so if you need more features then you have to change the PIC and it has to be a paid job.
- - - Updated - - -
Proteus Simulation Videos.