// // Intelligent MUTE Circuit TYPE A,B,C // // version 1.0 2011-Aug-1 // // (c)h_fujiwara_1995 / 2011-July #include "16F819.H" #device ADC=10 #fuses INTRC_IO,NOWDT,PROTECT,NOMCLR,BROWNOUT,NOLVP,PUT #use delay(internal=8MHz) #use fast_io(A) #use fast_io(B) // // A/D function routine // int16 get_ad() // BASIC A/D FUNCTION { int1 done; int16 value; read_adc(ADC_START_ONLY); done = adc_done(); while(!done) done=adc_done(); value=read_adc(ADC_READ_ONLY); return(value); } int16 get_ad1(int ch) // A/D value with channel select { int16 v; set_adc_channel(ch); // select Channel delay_us(15); // wait return(get_ad());} int16 get_ad4(int ch) // Four times average with channel select { int16 v; set_adc_channel(ch); // select Channel delay_us(15); // wait v =get_ad(); v+=get_ad(); v+=get_ad(); v+=get_ad(); return(v>>2);} int16 get_ad4n() // Four times average without channel select { int16 v; v =get_ad(); v+=get_ad(); v+=get_ad(); v+=get_ad(); return(v>>2);} // // I/O Port definition // #define IMUTE_BC_RELAY PIN_B4 // relay control port (H;ON) #define IMUTE_BC_S1 PIN_B2 // select mute time 1:3sec 0:1.5sec #define IMUTE_BC_S2 PIN_B1 // select voltage drop 1:15% 0:5% #define IMUTE_BC_S3 PIN_B0 // Recovery mode 1:off 0:on #define IMUTE_BC_PIN 0 #define IMUTE_A_RELAY PIN_B7 // relay control port (H;ON) #define IMUTE_A_S1 PIN_B6 // select mute time 1:3sec 0:1.5sec #define IMUTE_A_S2 PIN_B5 // select voltage drop 1:30% 0:10% #define IMUTE_A_S3 PIN_B4 // Recovery mode 1:off 0:on #define IMUTE_A_S4 PIN_B2 // Ripple Detect 1:off 0:on #define IMUTE_A_S5 PIN_B3 // DC offset detect 1:off 0:on #define IMUTE_A_PIN 1 // Power line #define IMUTE_A_RIN 0 // ripple content #define IMUTE_A_SP1 2 // SP1 input #define IMUTE_A_SP2 3 // SP2 input #define IMUTE_A_L1 PIN_B0 // LED L1 (DC offset detection) #define IMUTE_A_L2 PIN_B1 // LED L2 (Ripple detection) int ripple; // 1: AC mode 0:DC mode int16 maxvalue; // Max power line voltage int16 cutvalue; // Mute active voltage (maxvalue*alpha) int16 revalue; // Recover voltage (mid of max and cut) int rmode; // relay mode 1:ON 0:OFF #define DELAY_SHORT (1500) // 1.5sec #define DELAY_NORMAL (3000) // 3.0sec int mode_check(int ch) { int i,j;int16 b; get_ad1(ch); j=0; for(i=0;i<20;i++){b=get_ad4n(); if(b<5) j=1;delay_ms(1);} return(j); } // // IMUTE-B,C routine // IMUTE_BC_start(){ int16 a,b,n,m; int i; // initialize I/O settting output_low(IMUTE_BC_RELAY); // mute relay off rmode=0; set_tris_b(0x07); // RB0-2 inputs port_b_pullups(1); // all pullups RB set_tris_a(0x25); // RA5,2,0 inputs setup_adc(ADC_CLOCK_DIV_32); setup_adc_ports(AN0); // Only AN0 A/D input get_ad1(IMUTE_BC_PIN); // select channel // power up procedure if(input(IMUTE_BC_S1)==0) delay_ms(DELAY_SHORT); else delay_ms(DELAY_NORMAL); ripple=mode_check(IMUTE_BC_PIN); // check AC mode or DC mode output_high(IMUTE_BC_RELAY);rmode=1; // Relay active delay_ms(100); // wait a moment maxvalue=get_ad4n(); if(input(IMUTE_BC_S2)==0){ cutvalue = maxvalue*19; cutvalue /= 20; // 95% for shutdown revalue = maxvalue*39; revalue /= 40; // 97.5% for recover } else{ cutvalue = maxvalue*17; cutvalue /= 20; // 85% for shotdown revalue = maxvalue*37; revalue /= 40; // 92.5% for recover } if(ripple==0){ // DC mode n=0; while(1){ a=get_ad4n(); if(a < cutvalue){ // check voltage drop output_low(IMUTE_BC_RELAY); rmode=0;n=0;} if(input(IMUTE_BC_S3)==0 && rmode==0){ // check recover sequence if(a > revalue) n++; else n=0; if(input(IMUTE_BC_S1)==0 && n==DELAY_SHORT) {output_high(IMUTE_BC_RELAY); rmode=1;} if(input(IMUTE_BC_S1)==1 && n==DELAY_NORMAL) {output_high(IMUTE_BC_RELAY); rmode=1;} } delay_us(730); // loop interval output_high(PIN_B5); output_low(PIN_B5); // pulse out for check running } } else{ // AC mode b=get_ad(); i=20;m=0; while(1){ a=get_ad4n(); if(a > 50 ) i=20; else if(i) i--; // AC active check(if n=0 NO-ACLINE) if(i==0){output_low(IMUTE_BC_RELAY);m=0;rmode=0;} if(input(IMUTE_BC_S3)==0 && rmode==0){ if(i) m++; else m=0; if(input(IMUTE_BC_S1)==0 && m==DELAY_SHORT) {output_high(IMUTE_BC_RELAY);rmode=1;m=0;} if(input(IMUTE_BC_S1)==1 && m==DELAY_NORMAL) {output_high(IMUTE_BC_RELAY);rmode=1;m=0;} } delay_us(730); output_low(PIN_B5);output_high(PIN_B5); // pulse out for check running } } } // // IMUTE-A routine // int16 rip2,rip1; int riploop; #define RLEVEL (5) // Ripple level ripple_check() { if(input(IMUTE_A_S4)) return(0); rip2=get_ad4(IMUTE_A_RIN); if((rip2-rip1)>RLEVEL){ riploop=22; rip1 = rip2; } else if( rip2 < rip1 ) rip1 = rip2; if(riploop) riploop--; if(riploop){ output_high(IMUTE_A_L2);return(1);} else{ output_low(IMUTE_A_L2);return(0);} } int32 sp1,sp2; // sp offset register int16 sploop; // loop counter for offset calc. #define SPOFFSETH (613) // (613-512)*5*4mV=2V #define SPOFFSETL (410) // (410-512)*5*4mV=-2V spcheck() { int16 c1,c2; sp1 += get_ad1(IMUTE_A_SP1); sp2 += get_ad1(IMUTE_A_SP2); sploop++; if(sploop==1024){ c1=(sp1 >> 10) & 0x3ff; c2= (sp2 >> 10) & 0x3ff; if(c1>SPOFFSETH || c1SPOFFSETH || c2 revalue || j) n++; else n=0; if(input(IMUTE_A_S1)==0 && n==DELAY_SHORT) {output_high(IMUTE_A_RELAY); rmode=1;} if(input(IMUTE_A_S1)==1 && n==DELAY_NORMAL) {output_high(IMUTE_A_RELAY); rmode=1;} } spcheck(); delay_us(230); output_high(PIN_A6); output_low(PIN_A6); // pulse out } } else{ // AC mode b=get_ad1(IMUTE_A_PIN); i=20;m=0; while(1){ a=get_ad4(IMUTE_A_PIN); if(a > 50 ) i=20; else if(i) i--; // AC active check(if i=0 NO-ACLINE) if(i==0){output_low(IMUTE_A_RELAY);m=0;rmode=0;} if(input(IMUTE_A_S3)==0 && rmode==0){ if(i) m++; else m=0; if(input(IMUTE_A_S1)==0 && m==DELAY_SHORT) {output_high(IMUTE_A_RELAY);rmode=1;m=0;} if(input(IMUTE_A_S1)==1 && m==DELAY_NORMAL) {output_high(IMUTE_A_RELAY);rmode=1;m=0;} } spcheck(); delay_us(543); output_low(PIN_A6);output_high(PIN_A6); // pulse out } } } main() { // IMUTE Board identification and jump to each routine set_tris_a(0xff); if(input(PIN_A2)==1 && input(PIN_A5)==0) IMUTE_BC_start(); else if(input(PIN_A4)==0 && input(PIN_A5)==1) IMUTE_A_start(); else sleep(); } // end of program