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.

clap switch with PIC16F876A

Status
Not open for further replies.
If you clap once the LED turns ON after 2 sec. If clapped twice within 2 sec then LED turns OFF.


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
#include <16f877a.h> 
 
#device adc=10
  
#fuses HS,NOWDT,NOLVP,NOCPD,NODEBUG
 
#use delay(clock=4M)  
 
#define useTimer1
//#define useTimer2  
 
float volt, oldval, volt1; 
int count = 0;
unsigned int8 time = 0, clap = 0;
 
#ifdef useTimer1
#INT_TIMER1
void TIMER1_isr(void)
{    
   if(interrupt_active(int_timer1)) 
   {
          time++;            
   }
   
   set_timer1(0x0BDB);
   clear_interrupt(int_timer1);
} 
#elif useTimer2
 
#int_timer2 
void timer2_isr(void)  
{ 
    ;
}    
#endif
 
void clear(){
    clap = 0;
    time = 0;
    diaable_interrupts(INT_TIMER1);
}
 
void main() 
{ 
    set_tris_a(0xff); 
    set_tris_b(0x00); 
    set_tris_c(0x00); 
    set_tris_d(0x00); 
     
    //Analog module configuration for reading the voltage from the PIN_AN0 
    setup_comparator(NC_NC_NC_NC); 
    setup_adc(ADC_CLOCK_INTERNAL); 
    setup_adc_ports(AN0); 
    set_adc_channel(0);  
    setup_vref(FALSE);
    
    //Timer Configuration
    #ifdef useTimer1
        //Timer1
        //Prescaler 1:8; TMR1 Preload = 3035; Actual Interrupt Time : 500 ms
        setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
        set_timer1(0x0BDB);
    #elif
        //Code for Timer2 configuration
        
    #endif
    
    enable_interrupts(GLOBAL); 
         
    while(1) 
    { 
        delay_us(20); 
        read_adc(adc_start_only); 
        delay_us(100); 
        volt = read_adc(adc_read_only); 
        volt = volt * 30.0/ 1023.0; 
                 
        if((volt > 5) && (clap == 0){
              clap++;
              enable_interrupts(INT_TIMER1);
        }
        
        
        if((volt > 5) && (clap == 1){
                if(time < 4){ 
                        clap++;
                        output_low(PIN_C2);
                        clear();
            }           
        }
        
        if((clap == 1) && (time > 4)){
                output_high(PIN_C2);
                clear();                
        }
    }     
}

 

Hello ,in the above codes
PHP:
 if((volt > 5) && (clap == 0))
that 5 means what? and also for the following sentence
PHP:
if((clap == 1) && (time > 4))
what does means that 1 where you written (clap==1).

Also the conversion formula used is wrong because I am reading few voltages on AN0,
PHP:
volt = volt * 5.0/ 1023.0; //I think 30.0 has to be replaced by 5.0
;

I tried to test the codes but they are not working even makig on the load is not possible.

can you please help me?


Thanks.
 
Last edited:

I think there is only one thing missing


Code C - [expand]
1
2
3
4
5
f((volt > 5) && (clap == 0){
    clap++;
    enable_interrupts(INT_TIMER1);
    time = 0 // to clear and start the time variable
    }



the time variable will increment for every 500ms >4 means 2sec
 

where may I put those codes,on which line?Why are you using
PHP:
if((volt > 5) && (clap == 0){
with volt >5 and this volt can not exceeds 1.4 volts?

The system has to be when clapping the first time I think the codes you are using are the following:
PHP:
	if((clap ==1) && (time > 4)){
                output_high(PIN_D3);
                clear();                
        }
;is this means that if you clap the load has to be on only after 2 seconds because when (clap==1)//means you clap the first time and also (time > 4);means that the time is greater than 2 seconds.

Is my assumption right??Why don't we use the volt as a variable for testing and then write
PHP:
if((volt>1) && (time > 4)){
                output_high(PIN_D3);
                clear();                
        }

Note:I replaced C2 by D3 and 5 by 1 where you are writing volt>5,I replaced that 5 by 1.

Thanks.
 
Last edited:

where may I put those codes,on which line?Why are you using
PHP:
if((volt > 5) && (clap == 0){
with volt >5 and this volt can not exceeds 1.4 volts?

Thanks.

time is multiples of 0.5 sec at the same time volt is multiple of (5*30/1024).. so you can change it according to your clap magnitude....
I have added the time = 0 line in the if statement which already exists.....
 

time is multiples of 0.5 sec at the same time volt is multiple of (5*30/1024).. so you can change it according to your clap magnitude....
I have added the time = 0 line in the if statement which already exists.....

Hello,consider this project,now the codes are helping me to switch on but switch off is impossible.

Please help.

Thanks
 

Attachments

  • clapp.zip
    55.3 KB · Views: 42

The problem is i don having ccs compiler why did reduced adc values to multiply with 5 instead of 30 and voltage to 1??

and also make the RD3 pin 0 in starting....
 

Use an amplifier and comparator and INT0 pin to detect clap. It will be better than using ADC. After the first clap Timer will be running and timer interrupt will be occuring every 0.5 sec (500 ms) and if you make second clap and the uC is servicing timer interrupt at that moment then adc will not read. So the second clap will not be detected properly.
 

Use an amplifier and comparator and INT0 pin to detect clap. It will be better than using ADC. After the first clap Timer will be running and timer interrupt will be occuring every 0.5 sec (500 ms) and if you make second clap and the uC is servicing timer interrupt at that moment then adc will not read. So the second clap will not be detected properly.

I don think so, the timer interrupt can not take that much cpu usage, it is some simple routine.....
 

I reduced because I don't understand why using the multiplication of six,while we have to converter the voltage reads in decimal values and use it only for clap detection, I changed C2 to D3 because is how my circuit is constructed on the baord.

Please help.
 

What I said is if a timer interrupt happens at t = t2 and at the same time second clap occurs then if uC is incrementing the time variable and adc is not read.

Try this code.


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
#include <16f876a.h> 
 
#device adc=10
  
#fuses HS,NOWDT,NOLVP,NOCPD,NODEBUG
 
#use delay(clock=4M)  
 
//#define useTimer1
//#define useTimer2  
 
float volt, oldval, volt1; 
int count = 0;
unsigned int8 time = 0, clap = 0;
 
//#ifdef useTimer1
#INT_TIMER1
void TIMER1_isr(void)
{    
   if(interrupt_active(int_timer1)) 
   {
          time++;            
   }
   
   set_timer1(0x0BDB);
   clear_interrupt(int_timer1);
} 
//#elif useTimer2
 
//#int_timer2 
//void timer2_isr(void)  
//{ 
//   ;
//}    
//#endif
 
void clear(){
   clap = 0;
   time = 0;
   disable_interrupts(INT_TIMER1);
}
 
void main() 
{ 
    set_tris_a(0xff); 
    set_tris_b(0x00); 
    set_tris_c(0x00); 
        
    //Analog module configuration for reading the voltage from the PIN_AN0 
    setup_comparator(NC_NC_NC_NC); 
    setup_adc(ADC_CLOCK_INTERNAL); 
    setup_adc_ports(AN0); 
    set_adc_channel(0);  
    setup_vref(FALSE);
    
    //Timer Configuration
    //#ifdef useTimer1
      //Timer1
      //Prescaler 1:8; TMR1 Preload = 3035; Actual Interrupt Time : 500 ms
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(0x0BDB);
    //#elif
      //Code for Timer2 configuration
      
    //#endif
    
   enable_interrupts(GLOBAL); 
        
    while(1) 
    { 
        delay_us(20); 
        read_adc(adc_start_only); 
        delay_us(100); 
        volt = read_adc(adc_read_only); 
        //volt = volt * 10.0/ 1023.0; 
      
        if((volt > 10) && (clap == 1)){
            if(time < 4){ 
                  clap++;
                  output_low(PIN_C2);
                  clear();
            }         
        }
            
        if((volt > 10) && (clap == 0)){
               clap++;
               enable_interrupts(INT_TIMER1);
         }      
      
         if((clap == 1) && (time > 4)){
               output_high(PIN_C2);
               clear();            
         }
      
      volt = 0;
   }     
}

 

Yes. I know that but ADC reading and conversion will take so time in ms and even during this process there will be timer interrupt occuring and if time value becomes more than 4 (2 sec) then the if() condition will not be executed. He can check that be using


Code C - [expand]
1
if(time == 10)



in the isr code.
 

you know what is the problem, for a single clap with in the time period it will count number of claps in the first program if you correct it by taking the positive edge only then it will itself working........

- - - Updated - - -

Yes. I know that but ADC reading and conversion will take so time in ms and even during this process there will be timer interrupt occuring and if time value becomes more than 4 (2 sec) then the if() condition will not be executed. He can check that be using

in the isr code.
yeah its ok because you are stopping the timer, I told that for continuously running timer.......

but surely the ADC will take at least one successful reading before the clap vanishes.....
 

So what would the goods codes look like?What will be the codes??

- - - Updated - - -

Hello jayanth.devarayanadurga,are the codes be reduced when using an amplifier?
Tell me!!
 

Code will not have adc related code.

Use am Op Amp to amplify the Mic voltage to around 3V and then use a comparator with 2.5V ref and if there is a clap then o/p of Comparator should become low from high. Use INT0 to detect this high to low transistion by setting INTEDG bit properly. Set INT0 interrupt priority higher than Timer interrupt priority.

At first clap clear the interrupt ans start Timer for 2 sec and increment clap (clap will be 1, time will be 0).
If there is another clap then clear the interrupt and stop the timer and then check if time is <= 2 sec. If true then clap is 2 (no need to increment clap), so turn OFF LED.
If time was > 2 sec then discard (discard clap) operation and reset variables and stop timer and Turn ON LED (means only one clap).

This way due to INT0 the LED turns OFF immediately on detecting the two claps and Turns ON LED 2 sec after first clap.
 

just help with codes,I understand the logic but with interrupts I have complications.

Please help,Thanks
 

I don't use CCS C, so I don't know how to use INT0 in CCS C. Look in the device header file. You will see the functions used for interrupts. Looking at it you will get a idea about how to write code for INT0.
 

even with MikroC or assembly you can help,no problem.

Thanks.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top