arduino-sensor-corriente-sct-013

Sensor de corriente eléctrica no invasivo con Arduino y SCT-013

¿Qué es un sensor SCT-013?

La familia SCT-013 son sensores de corrientes no invasivos que permiten medir la intensidad que atraviesa un conductor sin necesidad de cortar o modificar el conductor. Podemos emplear estos sensores con un procesador como Arduino para medir la intensidad o potencia consumida por una carga

Los sensores SCT-013 son transformadores de corriente, dispositivos de instrumentación que proporcionan una medición proporcional a la intensidad que atraviesa un circuito. La medición se realiza por inducción electromagnética.

Los sensores SCT-013 disponen de un núcleo ferromagnético partido (como une pinza) que permite abrirlo para arrollar un conductor de una instalación eléctrica sin necesidad de cortarlo.

Dentro de la familia SCT-013 existen modelos que proporcionan la medición como una salida de intensidad o de tensión. Dentro de lo posible, lo normal es que prefiramos salida por tensión porque la conexión es más sencilla.

arduino-stc-013-tipos

La precisión del sensor puede ser de 1-2%, pero para ello es muy importante que el núcleo ferromagnético se cierre adecuadamente. Hasta un pequeño hueco de aire puede introducir desviaciones del 10%.

Como desventaja, al ser una carga inductiva, el SCT-013 introduce una variación del ángulo de fase cuyo valor es función de la carga que lo atraviesa, pudiendo llegar a ser de hasta 3º.

Los transformadores de intensidad son componentes frecuentes en el mundo industrial y en distribución eléctrica, permitiendo monitorizar el consumo de puntos de consumo donde sería imposible otro tipo de medición. También forman parte de múltiples instrumentos de medición, incluso en equipos portátiles como en pinzas perimétricas o analizadores de red.

En nuestros proyectos de electrónica y domótica podemos emplear los sensores de corriente SCT-013, por ejemplo, para medir el consumo eléctrico de aparato, comprobar el estado de una instalación eléctrica, y son componentes frecuentes en monitores de energía caseros para registrar el consumo de una instalación o incluso acceder a través de internet en tiempo real.

arduino-stc-013-dimensiones

Precio

Existen diversos modelos dentro de la familia SCT-013, que varían el rango de medición y en la forma de la salida. Físicamente son idénticos, aunque es posible identificarlos por el texto escrito en la carcasa.

El precio de todos ellos es similar, podemos encontrarlos por 4-4.50€, buscando en vendedores internacionales de eBay o AliExpress.

arduino-stc-013-componente

Los más frecuentes son el SCT-013-000 para una corriente máxima de 100A y salida de intensidad de 50mA (100A:50mA), y el SCT-013-030 para corrientes máximas de 30A (30A/1V) y salida en tensión de 1V.

No obstante aunque el SCT-013-000 sea muy frecuente en las tiendas online, como hemos dicho, normalmente vamos a preferir los modelos con salida en tensión.

Por último, es importante disponer un rango amplio de medición pero hay que tener en cuenta que un modelo de mayor intensidad máxima se traducirá en una menor precisión. Una intensidad de 30A a 230V corresponde con una carga de 6.900W, lo cuál es suficiente para la mayoría de usuarios domésticos.

¿Cómo funciona un SCT-013?

La familia de sensores SCT-013 son pequeños transformadores de corriente o CT (Current transformartor). Los transformadores de corriente son instrumentos ampliamente empleados como elementos de medición.

Un transformador de corriente es similar a un transformador de tensión y está basado en los mismos principios de funcionamiento (de hecho, formalmente es idéntico). Sin embargo persiguen objetivos diferentes y, en consecuencia, están diseñados y construidos de forma distinta.

arduino-stc-013-funcionamiento

Un transformador de corriente busca generar una intensidad en el secundario que sea proporcional a la intensidad que atraviesa el primario. Para ello se desea que el primario esté formado un un número de espiras reducido.

Podemos emplear esto para construir un sensor de corriente no invasivo. En un sensor se corriente el núcleo ferromagnético puede estar dividido de forma que pueda abrirse y arrollar un conductor.

De esta forma, se tenemos un transformador en el que:

  • El cable por el que circula la intensidad a medir constituye un devanado primario
  • La “pinza” es el núcleo magnético
  • El devanado secundario está integrado como parte de la sonda.

Cuando la corriente alterna circula por el conductor se genera un flujo magnético en el núcleo ferromagnético, que a su vez genera una corriente eléctrica en el devanado secundario.

La relación de transformación de intensidad depende de la relación entre el número de espiras.

El primario generalmente está formado por una única espira formada por el conductor a medir. Aunque es posible enrollar el conductor haciendo que pase más de una vez por el interior de la “pinza”. El número de espiras del secundario, integrado en la sonda, varía 1000-2000 según modelos del SCT-013.

A diferencia de los transformadores de tensión, en un transformador de intensidad el circuito secundario nunca debería estar abierto, porque las corrientes inducidas podrían llegar a dañar el componente. Por ese motivo, los sensores de SCT-130 disponen de protecciones (resistencia burden en los sensores de salida por tensión, o diodos de protección en los sensores de salida por corriente).

Esquema de montaje

Para entender la conexión del sensor SCT-013 tenemos que entender y resolver tres problemáticas,

  • Salida del sensor en intensidad
  • Adaptación de rango de tensión
  • Tensiones positivas y negativas

Salida del sensor en intensidad

El SCT-013 son transformadores de intensidad, es decir, la medición se obtiene como una señal de intensidad proporcional a la corriente que circula por el cable. Pero los procesadores solo son capaces de medir tensiones.

Este problema es sencillo de resolver. Para convertir la salida en intensidad en una salida de tensión únicamente tendremos que incluir una resistencia (resistencia burden).

Excepto el modelo SCT-013-100, todos los demás modelos tienen una resistencia de burden interna para que la salida sea una señal de tensión de 1V. Por lo cual ni siquiera tendremos que preocuparnos por ello.

Únicamente en el caso del SCT-013-100, carece de resistencia burden interna, por lo que la salida es una señal de ±50mA. Una resistencia de 33Ω en paralelo con el sensor será suficiente.

Tensiones positivas y negativas

Otro problema que tenemos que resolver es que estamos midiendo corriente alterna, y la intensidad inducida en el secundario es igualmente alterna. Tras el paso por la resistencia burden (interna o externa) la salida de tensión también es alterna.

Sin embargo, como sabemos, las entradas analógicas de la mayoría de procesados, incluidos Arduino, sólo pueden medir tensiones positivas.

Para poder medir las tensiones de la salida del transformador tenemos varias opciones, de peor a mejor.

Rectificar la señal mediante un puente de diodos, y medir la onda como valores positivos. No recomendable dado que perdemos la información de si estamos en el semiperiodo negativo o positivo, además porque tendremos la caída de tensión del diodo y, aún peor, el diodo no conduce por debajo de una tensión por lo que la señal estará distorsionada en los cruces por cero.

Añadir un offset en DC mediante el uso de dos resistencias y un condensador que proporcionen un punto medio entre GND y Vcc. Mucho mejor si además añadimos un amplificador operacional como seguidor de tensión.

Añadir un ADC con entrada diferencial, que permite realizar mediciones de tensiones positivas y negativas, como el ADS1115. Es la opción que vamos a usar nosotros.

Adaptación de rango de tensión

El último problema es que debemos adaptar el rango de tensiones en la salida del sensor. Arduino sólo puede realizar mediciones entre 0 y Vcc. Además, cuanto más pequeño sea el rango más precisión perdemos, por lo que conviene ajustarnos a este rango.

Por otro lado, debemos tener en cuenta que al hablar de tensión alterna normalmente se emplean valores RMS. Recordemos brevemente las ecuaciones de tensión pico, y pico a pico.

Por tanto, en el caso de los sensores con salida de ±1V RMS, la tensión de pico será ±1.414V, y la tensión pico a pico 2.828V.

En el caso del SCT-013-100 la salida será ±50mA. Con una resistencia burden externa de 33Ω la tensión de salida será ±1.65V RMS, y por tanto una tensión de pico de ±2.33V y una tensión de pico a pico de 4.66V.

Conexión eléctrica

Ya tenemos todos los componentes para medir la intensidad de red con un sensor SCT-013. Vamos a usar un sensor con salida de tensión ±1V RMS y resistencia burden interna, junto con un ADC como el ADS1115 en modo diferencial.

Ajustando la ganancia del ADS1115 a 2.048V estaremos dentro del rango de ±1.414V. En el caso de un sensor de 30A tendremos una precisión de 1.87mA, y 6,25 mA para un sensor de 100A.

Si usáis un SCT-013-100 con salida de ±50mA, tendremos que añadir una resistencia burden externa de 33Ω y subir la ganancia del ADS1115 a 4.096V para cumplir con el rango de ±2.33V.

arduino-stc-013-esquema

La conexión, vista desde Arduino, sería únicamente la alimentación del módulo ADS1115 como vimos en la entrada sobre el ADS1115.

arduino-stc-013-conexion

Para realizar las mediciones es importante que cojamos únicamente uno de los conductores con la “pinza”. Si cogemos más de un conductor (dos conductores en el caso de instalaciones monofásicas, tres en instalaciones trifásicas) el efecto de los conductores se anularía. Esto generando una inducción nula y, por tanto, una medición nula.

Los sensores SCT-013 disponen de un conector Jack 3.5, muy frecuente en audio, pero no el más cómodo para emplear en nuestros proyectos de electrónica. Para poder conectarlo deberemos o cortar el cable, o adquirir un conector hembra al que soldemos los cables. Afortunadamente son terminales fáciles de adquirir., aunque tampoco descartéis cortar el cable.

arduino-stc-013-jack

Si no queréis usar un ADC externo, podéis usar la solución más convencional, que es añadir un circuito que nos permita añadir un offset central.

En adelante, supondremos que usáis un Arduino de Vcc 5V. Si usáis otro procesador o un modelo de Arduino con otro Vcc (por ejemplo 3.3V) deberéis corregir el montaje en consecuencia.

arduino-stc-013-esquema-completo

Donde hemos añadido un punto de offset de DC de 2.5V por lo que el rango final es de 1.08V a 3.92V, dentro del rango de las entradas analógicas un Arduino alimentado a 5V.

En caso de usar el SCT-013-100 con salida de ±50mA, tendremos que añadir una resistencia burden externa de 33 Ohm y el rango final será de 0.17V a 0.483V, también dentro del rango de las entradas analógicas de un Arduino a 5V.

arduino-stc-013-esquema-completo-burden

Ejemplos de código

Montaje con ADS1115

Si habéis usado el montaje con un SCT-013 con salida de ±1V RMS y ADS1115, el código necesario es similar al que vimos en la entrada sobre el ADS1115. Necesitaréis la librería de Adafruit para el ADS1115.

Para que el ADS1115 muestree a una velocidad superior, deberemos modificar la siguiente línea del fichero ‘Adafruit_ADS1015.h’

    #define ADS1115_CONVERSIONDELAY         (8)

Por,

    #define ADS1115_CONVERSIONDELAY         (1)

Con esto conseguiremos bajar el tiempo de muestreo de unos 8-9 ms (unos 100 Hz) a 1.8 aprox (unos 500 Hz). Con eso nos alejamos de la frecuencia de Nyquist, y mejoramos el comportamiento de la medición.

#include <Wire.h>
#include <Adafruit_ADS1015.h>
 
Adafruit_ADS1115 ads;
  
const float FACTOR = 30; //30A/1V

const float multiplier = 0.0625F;
 
void setup()
{
  Serial.begin(9600);
 
  ads.setGain(GAIN_TWO);        // ±2.048V  1 bit = 0.0625mV
  ads.begin();
}

void printMeasure(String prefix, float value, String postfix)
{
 Serial.print(prefix);
 Serial.print(value, 3);
 Serial.println(postfix);
}
 
void loop()
{
 float currentRMS = getCorriente();
 float power = 230.0 * currentRMS;
 
 printMeasure("Irms: ", currentRMS, "A ,");
 printMeasure("Potencia: ", power, "W");
 delay(1000);
}
 
float getCorriente()
{
 float voltage;
 float corriente;
 float sum = 0;
 long tiempo = millis();
 int counter = 0;
 
 while (millis() - tiempo < 1000)
 {
   voltage = ads.readADC_Differential_0_1() * multiplier;
   corriente = voltage * FACTOR;
   corriente /= 1000.0;
 
   sum += sq(corriente);
   counter = counter + 1;
  }
 
 corriente = sqrt(sum / counter);
 return(corriente);
}

Otra versión es emplear el máximo y el mínimo de la medición, y calcular la medición a partir del valor de pico. Los resultados deberían ser similares a los vistos en el ejemplo con la suma al cuadrado. Para ello, podéis sustituir la función por la siguiente.

float getCorriente()
{
 long tiempo = millis();
 long rawAdc = ads.readADC_Differential_0_1();
 long minRaw = rawAdc;
 long maxRaw = rawAdc;
 while (millis() - tiempo < 1000)
 {
   rawAdc = ads.readADC_Differential_0_1();
   maxRaw = maxRaw > rawAdc ? maxRaw : rawAdc;
   minRaw = minRaw < rawAdc ? minRaw : rawAdc;
 }

  maxRaw = maxRaw > -minRaw ? maxRaw : -minRaw;
  float voltagePeak = maxRaw * multiplier / 1000;
  float voltageRMS = voltagePeak * 0.70710678118;
  float currentRMS = voltageRMS * FACTOR;
  return(currentRMS);
}

Podemos ver los resultados en el monitor del puerto serie, graficarlo con el serial plotter, o recogerlo en un proyecto mayor para mostrarlo en una página web, o registrarlo en una SD.

arduino-stc-013-resultados

Montaje con resistencias y punto medio

En este caso el ejemplo es muy sencillo, únicamente tenemos que realizar la medición mediante una entrada analógica.

const float FACTOR = 30; //30A/1V

const float VMIN = 1.08;
const float VMAX = 3.92;

const float ADCV = 5.0;  //Para Vcc
//const float ADCV = 1.1; //Para referencia interna  

void setup()
{
  Serial.begin(9600);
  //analogReference(INTERNAL);
}

void printMeasure(String prefix, float value, String postfix)
{
  Serial.print(prefix);
  Serial.print(value, 3);
  Serial.println(postfix);
}

void loop()
{
  float currentRMS = getCorriente();
  float power = 230.0 * currentRMS;

  printMeasure("Irms: ", currentRMS, "A ,");
  printMeasure("Potencia: ", power, "W");
  delay(1000);
}

float getCorriente()
{
  float voltage;
  float corriente;
  float sum = 0;
  long tiempo = millis();
  int counter = 0;

  while (millis() - tiempo < 500)
  {
    voltage = analogRead(A0) * ADCV / 1023.0;
    corriente = fmap(voltage, VMIN, VMAX, -FACTOR, FACTOR);

    sum += sq(corriente);
    counter = counter + 1;
    delay(1);
  }

  corriente = sqrt(sum / counter);
  return(corriente);
}

// cambio de escala entre floats
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full