El sensor SCT-013-30 és un element que converteix un corrent altern en una tensió alterna que podem mesurar.
[Sensorae.com]Aquest dispositiu consta d'un transformador de corrent (relació 1800:1) amb una resistència de càrrega de 62 Ω entre els borns de sortida, de manera que dona una sortida d'1 V quan el corrent d'entrada és de 30 A (valor nominal del dispositiu). Per al valor nominal (30 A) el corrent de secundari serà:

I la tensió de sortida serà:

Hem de tenir en compte que, en tractar-se d'un transformador de corrent, només serveix per a mesurar corrent altern i ens donarà un senyal en el secundari (de tensió, ja que té la resistència) proporcional a la del primari. Per tant, si el corrent del primari és altern sinusoidal, la tensió de secundari serà alterna sinusoidal.
Un senyal de tensió altern té valors tant positius com negatius. Atès que no podem connectar tensions negatives al microcontrolador, haurem de fer alguna cosa per aconseguir que els valors de tensió llegíts pel microcontrolador siguin sempre positius.
En el nostre cas tenim el sensor connectat com es mostra a la figura. Fixem-nos que un dels dos borns de sortida del sensor (S1) està connectat en el centre d'un divisor de tensió format per dues resistències iguals. Això significa que, en principi, el born S1 estarà a una tensió constant de 2,5 V (la meitat de 5 V) respecte a terra (GND).

L'altre born de sortida del sensor (S2) està connectat a l'entrada analògica AN9 del microcontrolador. Entre els dos borns de sortida del sensor tindrem, com hem comentat, un máxim d'1 V (valor nominal del sensor). Així, doncs, entre l'entrada AN9 i terra tindrem una tensió que, com a máxim, oscil·larà entre 1,5 y 3,5 V; valors perfectament compatibles amb les entrades analògiques del microcontrolador. Per a un determinat valor llegit per l'entrada analògica AN9, podem trobar el corrent real mitjançant l'expressió:

Observem que prenem la lectura de l'entrada AN9, la dividim per 1023 (valor de lectura corresponent a 5 V) i la multipliquem per 5 per obtenir la tensió corresponent a aquesta entrada. Al resultat li restem 2,5 per tenir el valor real de la tensió de sortida del sensor. Aquesta tensió la multipliquem per 30 per tenir el corrent, en ampers, que circula pel primari.
En cas que la tensió d'alimentació del microcontrolador fos diferent o si les dues resistències no fossin exactament iguals, ens trobaríem amb un cert error. Podem intentar reduir aquest error llegint la tensió del punt de referència (centre del divisor de tensió) i restant-la de la lectura de l'entrada AN9. Per aquest motiu, hem connectat el punt de referència a l'entrada AN8. Així, una forma més realista de llegir el sensor seria amb l'expressió:

Els valors llegits pel sensor corresponen a un senyal altern que fluctua, en principi en forma sinusoidal, amb un període de 20 ms (corresponent a la freqüència de 50 Hz, normalitzada per a Europa). Aquests valors, agafats individualment, no ens permeten deduir el valor del corrent mesurat. Per poder tenir uns valors més útils, podríem provar de trobar la mitjana dels valors instantanis de corrent; pero la mitjana d'una funció sinusoidal és sempre nul·la i, per tant, no ens aportaria cap informació.
El que ens interessa és trobar el valor eficaç del corrent. Podem definir el valor eficaç d'un corrent altern concret com aquell valor de corrent continu que, en un període, dissipa sobre una resistència la mateixa energia que el corrent altern. En el cas d'un corrent sinusoidal, podem calcular el valor eficaç (en anglès, root mean square, RMS) de manera senzilla. Primerament cal calcular el valor mitjà del valor absolut del corrent i multiplicar el resultat pel factor de forma.

Cal tenir en compte que aquest valor només és vàlid si l'ona és sinusoidal. El càlcul del valor eficaç també es pot fer directament a partir de les mesures; així sempre serà vàlid, encara que la forma d'ona no sigui sinusoidal. L'equació corresponent és:

El que significa anar sumant els quadrats de n valors del corrent al llarg d'un període; a l'acabar, dividir pel nombre de valors i treure l'arrel quadrada del resultat. Amb un microcontrolador com el nostre, aquest càlcul requereix força temps i memòria i, per tant, en el programa d'exemple emprarem el càlcul aproximat, fent servir el factor de forma.
Suposant que la tensió és 230 V (no disposem de cap manera de mesurar-la), podem calcular la potència aparent multiplicar la tensió i el valor eficaç del corrent.
Atès, que un endoll monofàsic sol estar limitat a 16 A, podem fer passar el cable dos cops per dins de la pinça (que correspon a tenir dues espires en el primari) per així tenir el doble de resolució. En el programa dividirem pel nombre d'espires (numEsp) per corregir el valor. Hem de tenir en compte, però, que el consum dels aparells que connectem no pot superar els 15 A, perquè el corrent que veu el sensor no superi el seu màxim de 30 A.
En el programa que posem d'exemple volem fer entre 25 i 80 mesures per cicle que, recordem, dura 20 ms. Amb la velocitat per defecte del microcontrolador, els temporitzadors s'incrementen cada 1 μs. A més, procurarem que el nombre de mesures per cicle sigui potència de dos perquè és molt més senzill dividir per valors que ho són. Si, per exemple, agafem 64 punts per cicle:
20 000 μs / 64 = 312,5 μs
Ens surt una durada que no és múltiple d'1 μs. Provem amb 32:
20 000 μs / 32 = 625 μs
Aquest valor és adequat. Farem una lectura cada 625 μs, de manera que tindrem 32 mesures per cicle.
Per mesurar el temps, farem servir el temporitzador 1 que, amb el prescalador a 1, s'incrementarà cada 1 μs. Per ajustar el temps a 625 μs, calculem quant hem de posar a TMR1.
TMR1 = 65536 - 625 = 64911 TMR1H = 64911 / 256 = 253 TMR1L = 64911 % 256 = 143
Ens cal fer una darrera comprovació. El valor de la tensió entre les dues entrades analògiques serà d'1 V. Per tant, el valor màxim de la resta de lectures (en valor absolut) serà:
1 1023 / 5 = 205
si llegim 32 valors, la suma serà, com a molt,
32 205 = 5560
valor que cap sobradament en una variable int.
Atès que el corrent no hauria de passar de dos dígits i disposem de cinc, en podem aprofitar dos per tenir un parell de decimals. El que farem és calcular el corrent multiplicat per cent i afegir-hi la coma en el moment d'enviar el valor a la pantalla.
El programa següent llegeix els 32 valors, calcula el valor eficaç i el mostra a la pantalla. Quan compta val zero és l'inici del procés, llavors llegim el valor de referència per a tota una tongada de mesures. Després llegim els 32 valors i, en acabar, calculem el corrent i tornem a començar. La funció d'interrupció, que dura uns 110 μs, és la que fa les mesures.
#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF #pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF #include <xc.h> // Carrega el fitxer de funcions #include <math.h> #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz #define numEsp 2
unsigned int refer, mesura;
int Valor;
unsigned int suma = 0;
float mitjana, RMS;
unsigned char compta = 0;
char Digits[5]; // Variable amb el número dígit a dígit
// Digits[0] són les unitats
// Definició de les funcions que farem servir void Esborra(void); // Esborra la pantalla i posa el cursor a l'inici void EnviaL(char Caracter); // Envia un caràcter
void main (void) {
// Configuració d'entrades i sortides
TRISC = 0b11110000; // Posa els bits 0 a 3 del port C com a sortida
// i els altres quatre com a entrada
TRISA = 0xFF; // Tot el port A és d'entrada
__delay_ms(2000); // Esperem que arrenqui la pantalla
// Configuració de la comunicació amb la pantalla
BRGH = 1; // Configuració de velocitat
BRG16 = 0; // Paràmetre de velocitat de 8 bits
SPBRG = 25; // Velocitat de 9600 baud
SYNC = 0; // Comunicació asíncrona
TX9 = 0; // Comunicació de 8 bits
SPEN = 1; // Activa comunicació sèrie
TXEN = 1; // Activa comunicació
// Entrades analògiques
ANSEL = 0b00000000; // Desactiva totes les entrades analògiques
ANSELH = 0b00000011; // I activa AN8 i AN9
ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
// Configuració d'interrupció
INTCON = 0b01000000; // Habilitem la interrupció per PIE
// i deshabilitem les altres
PIE1 = 0b00000001; // Activa la interrupció per Timer 1
// Configuració del Timer 1
TMR1IF = 0; // Aquest bit es posarà a 1 quan el temporitzador acabi
// cal desactivar-lo des del programa
TMR1H = 253; // Inicialitza el Timer1
TMR1L = 143;
T1CON = 0b00000000; // Configuració de Timer1
// 00 - Factor d'escala de 1
// I el posem en marxa
GIE = 1; // Habilitem les interrupcions a nivell general
while (1){ // Inici del bucle de programa
if(compta == 32){ // Quan ja tenim totes les mesures
Esborra(); // Posició a la pantalla
mitjana = (float)suma / compta; // Calculem la mitjana
RMS = (30 / numEsp) * 5 * 100 * 1.1107 * mitjana / 1023.0;
// Hem pultiplicat per 100 per tenir dos decimals
// A l'hora de mostrar-ho, posarem la coma convenientment
Valor = (int)round(RMS); // I el valor eficaç
// Preparem per mostrar el valor
// Descomposem en dígits
for (signed char j = 0; j < 5; j++){ // 5 dígits
Digits[j] = Valor % 10;
Valor = Valor / 10;
}
// Convertim a ASCII
for (signed char j = 0; j < 5; j++){ // 5 dígits
Digits[j] = Digits[j] + '0'; // Li sumem el codi ASCII de 0
}
// Eliminem zeros a l'esquerra
if(Digits[4] == '0') { // Mirem si el primer dígit és 0
Digits[4] = ' '; // Si ho és, hi posem un espai
if(Digits[3] == '0') { // Mirem si el segon dígit és 0
Digits[3] = ' '; // Si ho és, hi posem un espai
}
}
// Enviem a la pantalla
for (signed char j = 4; j >= 0; j--){ // 5 dígits
if(j == 1){
EnviaL(','); // Coma
}
EnviaL(Digits[j]); // Número
}
// Afegim les unitats
EnviaL(' '); // Espai
EnviaL('A');
compta = 0;
suma = 0;
}
if(compta == 0){ // Preparem una sèrie de mesures
// Llegim el valor de referència
ADCON0 = 0b10100001; // Activa el conversor connectat a AN8
// amb el resultat justificat per la dreta
GO_DONE = 1; // Posa en marxa el conversor
while (GO_DONE == 1) // Mentre no acabi
; // ens esperem
// Descartem la primera lectura
GO_DONE = 1; // Posa en marxa el conversor
while (GO_DONE == 1) // Mentre no acabi
; // ens esperem
refer = ADRESH;
refer = refer << 8;
refer = refer | ADRESL;
// Preparem per a les lectures
ADCON0 = 0b10100101; // Activa el conversor connectat a AN9
// amb el resultat justificat per la dreta
GO_DONE = 1; // Posa en marxa el conversor
while (GO_DONE == 1) // Mentre no acabi
; // ens esperem
// Descartem la primera lectura
__delay_ms(1000); // Esperem un segon
TMR1H = 253; // Inicialitza el Timer1
TMR1L = 143;
TMR1ON = 1; // Posa en marxa el temporitzador, per començar les mesures
}
}
}
void __interrupt() temporit(void){
// No desactivem les interrupcions perquè només en tenim una que dura poc
if(TMR1IF){ // Comprovem que hi ha interrupció per Timer 1
TMR1ON = 0; // Aturem el Timer
TMR1H = 253; // Inicialitza el Timer1
TMR1L = 143;
TMR1ON = 1; // El tornem a engegar
TMR1IF = 0; // Tornem a posar el bit a zero
// Anem a llegir el corrent
GO_DONE = 1; // Posa en marxa el conversor
while (GO_DONE == 1) // Mentre no acabi
; // ens esperem
mesura = ADRESH;
mesura = mesura << 8;
mesura = mesura | ADRESL;
if(mesura < refer){
suma = (suma + refer) - mesura; // Ho sumem
} else {
suma = (suma + mesura) - refer; // Ho sumem
}
compta++;
}
if(compta == 32){
TMR1ON = 0; // Aturem les lectures
}
}
void EnviaL(char Caracter){
TXREG = Caracter; // Agafa el caràcter i l'envia
__delay_ms(1); // Donem temps
while (TXIF == 0) // Esperem que s'acabi d'enviar
; // No fem res
}
void Esborra(void){
EnviaL(254); // Caràcter de control
EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.