Introducción.

Esta es otra forma de utilizar nuestro Arduino para mesurar tensiones y corrientes continuas, ya se ha descrito en estas páginas un voltímetro, un sensor de corriente, sin embargo en esta ocasión veremos una forma sencilla de realizar este tipo de medidor para nuestro uso o incluso para aplicar en proyectos industriales si es el caso.

Circuito de entrada.

El circuito de entrada de datos o tomas de mesura, es bastante sencillo y tiene la particularidad de utilizar resistencias de precisión de valores bastante comunes como veremos a continuación.

panel_medir_vols_amps
Fig. 1

 Como puede apreciarse por un lado tenemos dos entradas de la tensión que queremos conocer, una es GND que es normalmente la masa común, la otra entrada corresponde al positivo y será aplicada al terminal +VCC. Además, utilizaremos una resistencia de 95KΩ y una resistencia de 10.600Ω para conformar el divisor de tensión que nos permitirá medir una tensión máxima de 30V, el punto medio del divisor lo aplicaremos al pin A0 del Arduino para leer los voltios.

 En segundo lugar tenemos una borna (+ =>) y otra borna (<=-) entre ambas debemos conectar la carga que corresponda, para medir la corriente de paso, como se aprecia en el esquema la salida se aplicará al pin A1.

panel_medir_vol_amp
Fig. 2

Observar que en esta imagen se han ‘cortado’ ciertas conexiones que sólo representan los elementos que deben ser sustituidos por los reales, en el momento de hacer las medidas. La tensión del circuito que vamos a medir se aplica entre +Vss y GND.

Para medir una corriente, normalmente qué hacemos, cortamos el cable y conectamos el amperímetro en serie, exactamente eso es lo que haremos con este montaje. Por ese motivo he cortado la carga y los terminales sólo representan donde irá conectada la carga.

cortar_cable
Fig. 3

Si necesita una ayuda para el cálculo de las resistencias del divisor, puede servirse de estos descriptivos enlaces: calculograficoresitivo y divisor de tensión.

El Voltímetro.

El siguiente código corresponde a un Voltímetro que nos mide los voltios en el pin A0.

/*
 dcvoltmeter.ino 
 Un DVM basado en el concepto divisor voltaje con Arduino
 de T.K.Hareendran
 
 Voltímetro Digital 0V to 55V con Arduino

Aquí un circuito útil para los amantes y los experimentadores Arduino. 
Es un simple voltímetro digital, que puede medir con seguridad voltajes de 
corriente continua de entrada en el rango de 0 a 30V. La placa Arduino 
puede ser alimentada por una batería estándar de 9V, como de costumbre.

Como usted bien sabe, las entradas analógicas de Arduino se puede utilizar para 
medir el voltaje DC entre 0 y 5V (cuando se utiliza la tensión de referencia 
analógica estándar 5V) y este rango se puede aumentar mediante el uso de dos  
resistencias para crear un divisor de tensión. El divisor de tensión disminuye 
la tensión medida a estar dentro del rango de las entradas analógicas de Arduino.
 
Código en el boceto Arduino se utiliza entonces para calcular la tensión real 
que se está midiendo.

El sensor analógico de la placa Arduino detecta el voltaje en el pin analógico 
y lo convierte en un formato digital que puede ser procesado por el micro-
controlador. Aquí, estamos alimentando la tensión de entrada al pin analógico 
(A0) utilizando un circuito divisor de tensión que comprende las resistencias 
R1 sencilla (100K) y R2 (10K). Con los valores utilizados en el divisor de 
tensión es posible alimentar la tensión de 0V a 55V en la placa Arduino. 
La unión en la red de divisor de tensión conectado al pin el análogo 
Arduino es equivalente a la tensión de entrada dividido por 11, por lo que 
55V ÷ 11 = 5V. En otras palabras, cuando se miden 55V, el pin analógico Arduino 
estará en su máximo voltaje de 5V. Así, en la práctica, es mejor para etiquetar 
este voltímetro como "0-30V DVM" para añadir un margen de seguridad!

Si la lectura de la pantalla no coincide cuando se comparan con su DVM 
laboratorio, utilice un multímetro digital de precisión para encontrar la 
resistencia real de R1 y R2, y reemplazar R1 = 100000 y R2 = 10000 en 
el código con el que los valores. Seguidamente compruebe la alimentación de 5V 
con el DVM laboratorio en los pines GND y 5V de la placa Arduino. Podría 
darle menos (por ejemplo 4.95V), sustituya el valor en el código 
vout = (valor * 5.0) / 1024.0 (es decir, sustituir el 5.0 a la lectura V real, 
en este caso 4.95V).  

Para ambientes industriales, conviene poner un condensador de 100nf en paralelo 
a la entrada del pin analógico, en este caso pin A0. Además, el valor de R1 y R2
se han reducido, por el mismo motivo (lea el artículo).

Trate siempre de usar las resistencias de precisión de tolerancia del 1% para 
R1 y R2. Los valores de resistencia (R1 y R2) en el diagrama del circuito 
proporcionan cierta protección contra sobretensiones al medir voltajes 
bajos. Mantenga en mente que cualquier tensión de entrada superior a 
aproximadamente 55V podría freír el Arduino. Ningún otro tipo de protección 
(por picos de tensión, tensiones inversas o voltajes más altos) se incorpora 
en este circuito!

 funciona bien 05.08.2016 
*/
#include <LiquidCrystal.h> // lib. LiquidCrystal.h
// LCD:..........RS,E,D4,D5,D6,D7)
LiquidCrystal lcd(8,7, 6, 5, 4, 3); // 

int analogInput = A0;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000;// resistance of R1 (47000) -see text!
float R2 = 10000; // resistance of R2 (9400) - see text!
int value, val = 0;

void setup(){
 Serial.begin (9600);
 Serial.println("DCVoltmeter"); 
 Serial.println("DCVoltmeter.ino");
 Serial.println("05.08.2016"); 
 pinMode(analogInput, INPUT);
 lcd.begin(20, 4);
 lcd.setCursor(0,0);
 lcd.print("DC VOLTMETER"); 
 lcd.setCursor(0,1);
 lcd.println("DCVoltmeter.ino"); 
 lcd.setCursor(0,2); 
 lcd.println("30.08.2016");
 delay(1500); 
 lcd.clear();
}
void loop(){
 float sampleBVal = 0;
 // read the value at analog input
for (int x = 0; x < 500; x++){ 
 val = analogRead(analogInput);
 sampleBVal = sampleBVal + val;
 } 
 float value = sampleBVal/500;
 float vout = ((value * 5.0)+ 12) / 1024.0; // see text
 // el +12 es un valor ajustado para compensar los valores restantes
 float vin = vout / (R2/(R1+R2)); 

 Serial.print("Volts= "); 
 Serial.println(vin);
 lcd.setCursor(0,0);
 lcd.print("DC VOLTMETER"); 
 lcd.setCursor(0, 1);
 lcd.print("OUTPUT V= ");
 lcd.setCursor(10, 1);
 lcd.print(vin, 2);
 lcd.print(" ");
 delay(500);
}

 En el anterior código se logra una lectura estable de tensión, lo cual nos indica que vamos por el buen camino. En el próximo código intentaremos añadir la opción de leer la corriente siguiendo las posibilidades del esquema de la anterior figura 2.

Parámetros del voltímetro.

Estos son los valores obtenidos de las medidas tomadas.

 Tensión de batería (INPUT)   Tensión en A0  Tensión LCD
1,00  0,16  1,01
2,00 0,33 2,04
3,00 0,49 3,05
3,50 0,57 3,54
5,50 0,90 5,58
 9,00  1,48  9,12
 10,00  1,65  10,15
 12,00  1,98  12,22
 15,00  2,47  15,27
 20,00  3,30  20,25
 24,00  3,90  24,50
55,00 5,01  55,15

El amperímetro.

El siguiente código que ya vimos en sensor de corriente, con el que medir la corriente de paso de un circuito mediante el sensor ACS712 de carga.

/*
 watt_meter_lcd.ino 
 Este boceto se describe cómo conectar un Sensor de Corriente ACS715 
(http://www.pololu.com/catalog/product/1186) a un Arduino,
 y leer la corriente que fluye a través del sensor.
 
*/
#include <LiquidCrystal.h> // lib. LiquidCrystal.h

//LCD: (RS, E,D4,D5,D6,D7)
LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // mi config.
/*

Vcc a tarjeta sensora para Arduino + 5v
GND a tarjeta sensora para Arduino GND
OUT a tarjeta sensora para Arduino A0

Inserte las patillas de potencia en el circuito conductor positivo de carga,
la flecha en puntos del soporte board para cargar, otro enganche se conecta
al positivo de fuente alimentación.

Divisor de Voltage:

R1 = 47k a A2
R2 = 9400 a GND

Vin = 29,89V
Vout = 5V
Ratio 5,978

*/
int batMonPin = A2; //A2 pin entrada del divisor voltage
int batVal = 0; // variable para el valor A/D
float pinVoltage = 0; // variable que contiene la tensión calculada
float batteryVoltage = 0;

int analogInPin = A1; //A0 pin de entrada mV está conectado a Salida sensor ASC712
int sensorValue = 0; // valor leído de la tarjeta soporte ASC712
int outputValue = 0; // salida en milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;

// Estos valores para max. Vin = 30V
// R1=4700Ω; R2=943Ω. para mayor impedancia
int R1 = 47000; // Resistencia of R1 in ohms
int R2 = 9400; // Resistencia of R2 in ohms

float ratio = 0; // Calculated from R1 / R2 = 4,984

void setup() {
// inicializa comunicaciones Serial a 9600 bps:
Serial.begin(9600);
lcd.begin(20, 4);
}

void loop() {

int sampleBVal = 0; // muestra V
int avgBVal = 0; // porcentage
int sampleAmpVal = 0; // muestra A
int avgSAV = 0; // porcentage

for (int x = 0; x < 10; x++){ // ejecutar a través del bucle de 10x

// leer el valor analógico en:
sensorValue = analogRead(analogInPin); //
sampleAmpVal = sampleAmpVal + sensorValue; // añadir muestras juntas

batVal = analogRead(batMonPin); // leer el voltaje en el divisor
sampleBVal = sampleBVal + batVal; // añadir muestras juntas

delay (10); // dejar resolver ADC antes de siguiente muestra
}

avgSAV = sampleAmpVal / 10; // saca el %

// convert to milli amps
outputValue = (((long)avgSAV * 5000/ 1024) - 500) * 1000/ 66; //según sensor 66 o 133 mA

/* sensor da salida sobre 100 en reposo.
Analog read produces a value of 0-1023, equiparando de 0v a 5v.
"((long)sensorValue * 5000 / 1024)"es la tensión en la salida del sensor en milivoltios.
Hay un desplazamiento a restar 500 mv.
La unidad produce 66 mV / 133 mV por amperio de corriente, por lo
que se divide por 0.066 / 0.133 para convertir mV a mA
*/

avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading

pinVoltage = avgBVal * 0.00488; // 0,00610 Calculate the voltage on the A/D pin
/* Una lectura de 1 para el A / D = 0.00488mV
Si multiplicamos la lectura A / D por 0,00488
entonces obtenemos el voltaje en el pin.

¡NOTA! 0,00488 es ideal. Tuve que ajustar contador a 0,00610 para que coincida.

También, dependiendo de la tensión, del cableado y
donde se está leyendo, bajo voltaje, fuertes cargas
que se muestra puede ser bien bajo voltaje en el suministro. 
Supervisar la carga o la alimentación y decidir.
*/

ratio = (float)R1 / (float)R2;
batteryVoltage = pinVoltage * ratio; // Utilice la relación calculada del divisor
// de tensión para calcular la tensión de la batería
amps = (float) outputValue / 1000;
float watts = amps * batteryVoltage;

Serial.print("Volts = " );
Serial.print(batteryVoltage);
// Serial.print("\t Current (amps) = ");
Serial.print(" Current (amps) = ");
Serial.print(amps);
// Serial.print("\t Power (Watts) = ");
Serial.print(" Power (Watts) = ");
Serial.print(watts);

sample = sample + 1;
msec = millis();

time = (float) msec / 1000.0;
totalCharge = totalCharge + amps;
averageAmps = totalCharge / sample;
ampSeconds = averageAmps*time;
ampHours = ampSeconds/3600;
wattHours = batteryVoltage * ampHours;

// Serial.print("\t Time (hours) = ");
Serial.print(" Time (hours) = ");
Serial.println(time/3600);

// Serial.print("\t Amp Hours (ah) = ");
// Serial.print(ampHours);
// Serial.print("\t Watt Hours (wh) = ");
// Serial.println(wattHours);

lcd.setCursor(0,0);
lcd.print(batteryVoltage);
lcd.print(" V ");
lcd.print(amps);
lcd.print(" A ");

lcd.setCursor(0,1);
lcd.print(watts);
lcd.print(" W ");
lcd.print(time/3600);
lcd.print(" H ");

lcd.setCursor(0,2);
lcd.print(ampHours);
lcd.print(" Ah ");
lcd.print(wattHours);
lcd.print(" Wh ");

lcd.setCursor(0,3);
lcd.print(ratio, 5);
lcd.print(" ");
lcd.print(avgBVal);

// wait 10 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(10);
}

Este código nos sirve para implementar con el código que necesitamos.

Volt-amperímetro.

El siguiente código es el compendio de los anteriores con el que podremos medir los distintos valores de tensión y corriente, y mediante las oportunas operaciones obtendremos los vatios.

/* 
 watimetro_lcd.ino
This sketch describes how to connect a ACS715 Current Sense Carrier 
(http://www.pololu.com/catalog/product/1186) to the Arduino, 
and read current flowing through the sensor.
 
*/
#include <LiquidCrystal.h> // #include LiquidCrystal.h

// LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
//LCD:...........(RS, E,D4,D5,D6,D7)
 LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // mi config. 


/*

Vcc on carrier board to Arduino +5v
GND on carrier board to Arduino GND
OUT on carrier board to Arduino A0

Insert the power lugs into the loads positive lead circuit, 
arrow on carrier board points to load, other lug connects to 
power supply positive

Voltage Divider

11.66 from + to A4
4.62k from A4 to Gnd
Ratio 2.5238


*/
int batMonPin = A4; // input pin for the voltage divider
int batVal = 0; // variable for the A/D value
float pinVoltage = 0; // variable to hold the calculated voltage
float batteryVoltage = 0;

int analogInPin = A0; // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0; // value read from the carrier board
int outputValue = 0; // output in milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;

int R1 = 11660; // Resistance of R1 in ohms
int R2 = 4620; // Resistance of R2 in ohms

float ratio = 0; // Calculated from R1 / R2

void setup() {
 // initialize serial communications at 9600 bps:
 Serial.begin(9600); 
 lcd.begin(20, 4);
 lcd.println(" watt_meter_lcd2.ino "); 
 delay(500);
 lcd.clear();
}

void loop() {
 
int sampleBVal = 0;
int avgBVal = 0; 
int sampleAmpVal = 0;
int avgSAV = 0;
 
 for (int x = 0; x < 50; x++){ // run through loop 10x
 
 // read the analog in value:
 sensorValue = analogRead(analogInPin); 
 sampleAmpVal = sampleAmpVal + sensorValue; // add samples together

 batVal = analogRead(batMonPin); // read the voltage on the divider 
 sampleBVal = sampleBVal + batVal; // add samples together
 
 delay (10); // let ADC settle before next sample

 }
 
 avgSAV = sampleAmpVal / 50;
 
 // convert to milli amps
 outputValue = (((long)avgSAV * 5000 / 1024) - 500 ) * 1000 / 66; // 133
 
/* sensor outputs about 100 at rest. 
Analog read produces a value of 0-1023, equating to 0v to 5v.
"((long)sensorValue * 5000 / 1024)" is the voltage on the sensor's output in millivolts.
There's a 500mv offset to subtract. 
The unit produces 133mv per amp of current, so
divide by 0.133 to convert mv to ma 
*/
 
 avgBVal = sampleBVal / 50; //divide by 10 (number of samples) to get a steady reading
 
 pinVoltage = avgBVal * 0.00610; // Calculate the voltage on the A/D pin
 /* A reading of 1 for the A/D = 0.0048mV
 if we multiply the A/D reading by 0.00488 then 
 we get the voltage on the pin. 
 
 NOTE! .00488 is ideal. I had to adjust 
 to .00610 to match fluke meter.
 
 Also, depending on wiring and 
 where voltage is being read, under 
 heavy loads voltage displayed can be 
 well under voltage at supply. monitor 
 at load or supply and decide.
*/

 ratio = (float)R1 / (float)R2;
 batteryVoltage = pinVoltage * ratio; // Use the ratio calculated for the voltage divider
 // to calculate the battery voltage 
 
 amps = (float) outputValue / 1000;
 float watts = amps * batteryVoltage;
 
 Serial.print("Volts = " ); 
 Serial.print(batteryVoltage); 
 Serial.print("\t Current (amps) = "); 
 Serial.print(amps); 
 Serial.print("\t Power (Watts) = "); 
 Serial.print(watts);  
 
 sample = sample + 1; 
 msec = millis(); 
 
 time = (float) msec / 1000.0; 
 totalCharge = totalCharge + amps; 
 averageAmps = totalCharge / sample; 
 ampSeconds = averageAmps*time;
 ampHours = ampSeconds/3600; 
 wattHours = batteryVoltage * ampHours; 

 Serial.print("\t Time (hours) = ");
 Serial.print(time/3600); 
 Serial.print("\t Amp Hours (ah) = ");
 Serial.print(ampHours);
 Serial.print("\t Watt Hours (wh) = ");
 Serial.println(wattHours); 

 lcd.setCursor(0,0);
 lcd.print(batteryVoltage);
 lcd.print(" V ");
 lcd.print(amps);
 lcd.print(" A ");
 
 lcd.setCursor(0,1);
 lcd.print(watts);
 lcd.print(" W ");
 lcd.print(time/3600);
 lcd.print(" H ");
 
 lcd.setCursor(0,2);
 lcd.print(ampHours);
 lcd.print(" Ah ");
 lcd.print(wattHours);
 lcd.print(" Wh ");
 
 lcd.setCursor(0,3);
 lcd.print(ratio, 5);
 lcd.print(" ");
 lcd.print(avgBVal);
 
 // wait 10 milliseconds before the next loop
 // for the analog-to-digital converter to settle
 // after the last reading:
 delay(10); 
}

Desde mi experiencia, hay un aspecto que debo aclarar; puesto que la tensión de trabajo de nuestro Arduino no siempre es de 5V, hay que corregir la formula, debemos medir con nuestro mejor voltímetro dicha tensión, que será la tensión de referencia, eso dará una precisión mayor a nuestro voltímetro. Algunos han incluido valores aleatorios ajustándolos para mejorar la lectura.

He tratado de utilizar valores razonados, de modo que, he modificado la formula que quedará así:
vout = ((valor * 5.0)/0.0488)/1024.

Si usted que lee esto, pruebe esta formula y si considera que estoy en un error, por favor, muéstreme el motivo.

Medir voltios y amperios.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.