//** ******************************************************************************************************************** **// //** Scritto da Corrado Bevilacqua www.myelectronichome.altervista.org **// //** ******************************************************************************************************************** **// //** **// //** Interrompe la corrente in caso di assorbimento eccessivo Stops the current in case of excessive absorption **// //** **// //** Utilizza: Un sensore di corrente SCT-013-020 o SCT-013-030; Use: A current sensor SCT-SCT-013-020 or 013-030; **// //** un modulo relé; a relay module **// //** tre led; three LEDs **// //** un pulsante; a button **// //** **// //** ******************************************************************************************************************** **// //** Software liberamente copiabile a patto morale di citare Free software to copy and use in moral condition of **// //** l'autore nei commenti del vostro programma quoting the author in the comments of your program **// //** ******************************************************************************************************************** **// //** Written by Corrado Bevilacqua (C) myelectronichome.altervista.org **// //** ******************************************************************************************************************** **// //** ******************************************************************************************************************** **// //** Variabili per il sensore di corrente Variables for the current sensor **// //** ******************************************************************************************************************** **// int valmedio[5]; //average value - Valore Medio int analogPin = 1; //pin to SCT 013 020 sensor - Pin per collegarci il sensore SCT 013 020 int zerovolt=0; //to calculate the zerovolt value - Per calcolare il valore zero int Quantospunto=1200*5; //time required to overcoming the inrush current - Tempo richiesto per superare le correnti di spunto int Corrente=0; int StaccaTutto=0; long TempoPresenzaDiCorrente=0; //Currente presence starting time - Memorizza l'inizio del momento in cui c'e assorbimento di corrente int CorrenteMIN = 5 ; //Under this value i consider no current. - Sotto a questa soglia si considera assenza di corrente int CorrenteMAX = 10; //Upper this value i cut off the current - Corrente Massima. Sopra questa soglia il sistema stacca la corrente void setup() { digitalWrite(5, LOW); //relay off - Relè disattivato Serial.begin(19200); Serial.println("Sketch: HightCurrentSwitch"); delay(500); //**************// CalcolaZeroVolt(); //**************// pinMode(13, OUTPUT); //Currente presence - Green led - Presenza corrente - led verde pinMode(12,OUTPUT); //High Current - Red led - Corrente eccessiva - led rosso pinMode(5, OUTPUT); //Relay ON - Yellow led - Rele' attivato - led gialllo pinMode(3, INPUT); //Button - Pulsante digitalWrite(5, LOW); zerovolt=502; lampeggia(12,5, 500); lampeggia(13,5, 500); digitalWrite(5, HIGH); //Activate Relay - Attiva il relè StaccaTutto=0; } // end setup void loop() { Corrente = QuantaCorrente(); Serial.print("Corrente rilevata = "); Serial.println(Corrente); if (StaccaTutto==0) { if (Corrente < CorrenteMIN) { //Led OFF digitalWrite(13, LOW); digitalWrite(12, LOW); TempoPresenzaDiCorrente=millis(); } if (Corrente >= CorrenteMIN) { digitalWrite(13, HIGH); //Current presence - presenza di corrente digitalWrite(12, LOW); } if (Corrente > CorrenteMAX) { //High Current digitalWrite(12, HIGH); //Red Led ON - Attiva il Led rosso if (TempoPresenzaDiCorrente + Quantospunto <= millis()) { //STOP Current StaccaTutto=1; digitalWrite(5, LOW); //Relay OFF - Diseccita il rele digitalWrite(13, LOW); //Green led OFF - spegni il led verde digitalWrite(12, HIGH); //Red led ON - Accendi il led rosso } } } if (StaccaTutto==1) { if (digitalRead(3)==1) { lampeggia(12,5, 200); //Blink RED led for a while - Lampeggia il rosso per un poco digitalWrite(5, HIGH); //Relay ON - Riattiva il rele StaccaTutto=0; //Attention, press the reset button reactivates the current and starts the counter which inhibits the system for the inrush time. //Attenzione, premere il tasto reset riattiva la corrente e riparte il contatore che inibisce il sistema per il tempo di spunto. TempoPresenzaDiCorrente=millis(); } } } void CalcolaZeroVolt() { //** **************************************************************** **// //** Calculate ZeroVolt **// //** **************************************************************** **// int max2 =0; int min2 =9999; valmedio[0]=analogRead(analogPin); valmedio[1]=analogRead(analogPin); valmedio[2]=analogRead(analogPin); valmedio[3]=analogRead(analogPin); valmedio[4]=analogRead(analogPin); int punta=0; int mediato=0; long oldtime1; oldtime1=millis(); while (millis()-oldtime1<=85) { valmedio[punta]=analogRead(analogPin); if (punta<4) {punta=punta+1;} else {punta=0;} mediato=(valmedio[0]+valmedio[1]+valmedio[2]+valmedio[3]+valmedio[4])/5; if (max2mediato) {min2=mediato;} } zerovolt = (max2+min2)/2; Serial.print("Valore per zerovolt = " ); //In italiano //Serial.print("ZeroVolt Value = " ); //In english language Serial.println(zerovolt); } //end zerovolt int QuantaCorrente() { long somma=0; int ritorna=0; long conta=0; int punta=0; int mediato=0; int i=0; int PerZeroOk=0; int tante = 10; //Indica quante mezze onde leggere. Con 10 semionde (5 periodi) ci mette 100ms. //It indicates how many half-wave reading. With 10 half-waves (5 periods) it takes 100ms. //assegna queste variabili per costruire la prima media //assign this variables to build the average initial valmedio[0]=analogRead(analogPin); valmedio[1]=analogRead(analogPin); valmedio[2]=analogRead(analogPin); valmedio[3]=analogRead(analogPin); valmedio[4]=analogRead(analogPin); mediato=(valmedio[0]+valmedio[1]+valmedio[2]+valmedio[3]+valmedio[4])/5; boolean onda=0; if (mediato-zerovolt>0 ) //Se maggiore di uno allora per onda metto 1 altrimenti zero, Dice se l'onda è sopra o sotto lo zero {onda=1;} //If greater than one then in the wave variable I put one otherwise zero. It means that the wave is above or below zero. long TempoStart; //variabile per calcolare quanto tempo ci mette //Variable to calculate how long it takes TempoStart=millis(); while (PerZeroOk<=tante && abs(millis()-TempoStart) < (tante+4)*20) { //Mediamo i valori letti per contenere gli spikes valmedio[punta]=analogRead(analogPin); if (punta<4) {punta=punta+1;} else {punta=0;} mediato=(valmedio[0]+valmedio[1]+valmedio[2]+valmedio[3]+valmedio[4])/5; mediato=mediato-zerovolt; // L'IF seguente Rileva il passaggio per zero e conseguentemente riesce a contare le semionde. // Tuttavia per bassi assorbimenti di corrente non riesce a contarle bene e quindi fornisce un // valore più basso di quello dovuto. E' un problema che si presenta solo per basse correnti // e quindi non inficia il funzionamento del programma perchè lavora sulla fascia dei forti // assorbimenti di corrente. // The following IF detects the passage by zero and consequently is able to count the half waves. // However for low current consumption it can not count them well and therefore provides a lower // value. It 'a problem that occurs only for low currents and therefore does not affect the // operation of the program, because it works on the band of the strong current absorption. if ((onda==1 && mediato <0) || (onda==0 && mediato >0)) { PerZeroOk=PerZeroOk+1; onda=onda^B1; //Cambia lo stato da 0 a 1 e viceversa } // In PerZeroOK=0 siamo in un punto a caso della prima semionda per cui ignoriamone i valori. Dobbiamo prendere sempre semionde intere. // In PerZeroOK=0 we are in a random point of the first half-wave for which we ignore values. We must always take whole half waves. if (PerZeroOk>=1) { somma=somma+abs(mediato); conta=conta+1; } } TempoStart=millis()-TempoStart; //Per evitare divisioni con uno dei due numeri uguale a zero - To avoid divisions with one of the two numbers equal to zero if (somma==0 || conta ==0 ) {somma=0;} else {somma=somma/conta;} // Serial.print("Corrente rilevata = "); //in italiano // // Serial.print("Current detected = "); //in english langage // Serial.println(somma); return somma; } //end QuantaCorrente void lampeggia(int pin,int volte, int periodo) { //fa lampeggiare un pin e il suo led collegato. //Flashes a pin and its LED connected. int h=0; for (h=1; h<=volte ; h++) { digitalWrite(pin, HIGH); delay(periodo); digitalWrite(pin, LOW); delay(periodo); } }