Sie sind auf Seite 1von 19

SENSOR DE CORRIENTE ACS712.

LECTOR DE CORRIENTE ACS712.


CREADO POR V. GARCÍA. EL 06.09.2015
INTRODUCCIÓN.

En este artículo describiré cómo conectar un sensor de


corriente ACS715 a la placa Arduino, y así leer la corriente que fluye a
través del mismo. Una vez más, recomiendo que lea las hojas de
características del fabricante. El Allegro® ACS712 proporciona soluciones
económicas y precisas para detección de CC o CA en el sector industrial,
comercial y sistemas de comunicaciones. El paquete del dispositivo
permite una fácil aplicación por parte del cliente. Las aplicaciones típicas
incluyen control del motor, detección de carga y gestión, fuentes de
alimentación conmutadas, y la protección de fallo por sobre intensidad.

EL ACS712.

El dispositivo consta de un circuito preciso, bajo offset, sensor Hall lineal


con una pista de cobre conductor ubicado cerca de la superficie de la
matriz. La corriente aplicada que fluye a través de esta pista de conducción
de cobre genera un campo magnético que es detectado por el IC integrado
Hall y convertida en una tensión proporcional. La exactitud de los
dispositivos se optimiza a través de la proximidad de la señal magnética al
transductor Hall. Una tensión precisa, proporcional es proporcionada por
el bajo offset, chopper-estabilizado IC BiCMOS Hall, que está programado
para la exactitud después del encapsulado.

Este sensor es un pequeña placa, que soporta un sensor de corriente


de Allegro, el ACS715 30A está basado en el efecto Hall lineal, que ofrece
una baja resistencia (~ 1,2 mΩ) al paso de la corriente con un aislamiento
eléctrico de hasta 2,1 kV RMS, según indica el fabricante. Esta versión
acepta una entrada de corriente continua de hasta 30 A y una salida de
tensión analógica proporcional (66 mV/A) que mide 500 mV. Cuando la
corriente de entrada es cero. El error de salida típico es de ± 1,5%. Opera
desde 4,5 V a 5,5 V y está pensado para su uso en sistemas de 5 V.

Este dispositivo es muy sencillo, como se aprecia en la imagen de abajo,


dispone de tres pines, Vcc, GND y Salida en un extremo y en el otro,
dispone de un conector con dos contactos para leer la corriente que
pretendemos medir.

Fig. 1
El espesor de la pista de cobre permite la supervivencia del dispositivo en
hasta 5 × condiciones de sobre corriente. Los terminales de la pista
conductora están eléctricamente aislados de los cables de los sensores
(pines 5 a 8 en fig. 2). Esto permite que el sensor de corriente ACS712
para ser utilizado en aplicaciones que requieren aislamiento eléctrico sin
el uso de aisladores ópticos u otras técnicas de aislamiento costosas.

Mi idea inicial era realizar un voltímetro para que lo utilice quien quiera y
pueda aplicarla a su fuente de alimentación. Pensé que con este elemento
se completaría un dispositivo importante en una fuente de laboratorio, y
por ese motivo realicé un artículo que describe como aplicar un voltímetro a
cualquier fuente de alimentación.
Una vez empecé el artículo y a medida que avanzaba me di cuenta que si
además de voltímetro midiera la corriente de consumo, estaría más
completo y de esta forma tuve que adquirir uno de estos dispositivos, y esa
es la razón de este artículo. El esquema práctico de conexionado es
sencillo y fácil de entender. Se trata de conectar el sensor en serie con la
carga que queremos conocer la corriente de consumo.
Fig. 2
Tensión de salida en reposo (Viout (Q)). La salida del sensor cuando la
corriente primaria es cero. Para una tensión de alimentación unipolar,
sigue siendo nominalmente VCC / 2. Por lo tanto, cuando no hay
corriente la tensión de salida es VCC / 2 = 5 V / 2 = 2.5V. La variación en
Viout (Q) se pueden atribuir a la resolución de la compensación de tensión
de reposo IC Allegro lineal y la deriva térmica. Parece muy complicado, lo
intentaré más sencillo.

Cuando no haya corriente de paso por el sensor, leerá CERO, pero esto
no va a dar cero en las lecturas. Me voy a explicar, los puertos analógicos
en Arduino utilizan un conversor A/D que va de 0 a 1023, donde el 0 == 0
V y el 1023 == 5 V, como el sensor es bidireccional, cuando el sensor no
detecta corriente el voltaje será de 2,5 V = (VCC / 2) y la lectura de Arduino
será algo cercano a 512. Por lo tanto, si la corriente es positiva va a
aumentar la lectura y una lectura negativa la disminuirá.

Fig. 3
Para comprender mejor esto, supongamos que este sensor mide
intensidades entre -5A y +5A (vea su modelo que alcance tiene). Ya que
la salida del sensor según la hoja de datos siempre entrega entre 0 y 5
voltios, cuyo valor de 0A se corresponde con los 2.5V en la salida, y por
cada amperio la tensión varía 185 mA. Este sensor puede medir tanto CC
como CA, si vemos una sinusoide, el punto más bajo se corresponde con
los -5A, de modo que los 2.5V de salida corresponden justo a 0A y los +5A
con los 5V, véase la imagen que sigue.
Fig. 4
Espero que haya quedado claro. El modo de conexionado se muestra
simbólicamente en la figura siguiente.

Fig. 5
DESCRIPCIÓN.

En este sensor podemos ver los siguientes puntos:

1. Sensor de corriente: ACS712 -30A.


2. Tensión de alimentación, de la placa al pin 5V del Arduino.
3. Este módulo es bidireccional, puede medir desde -30 a + 30A
(equivalente a 66mV / A)
4. Tiene una corriente de 0A cuando entrega una tensión de
salida de VCC / 2, es decir, 2,5V

¡Advertencia!:Este producto está diseñado para su uso por debajo de 30V.


Trabajar con voltajes más altos puede ser extremadamente peligroso y
sólo debe ser manipulado por personas cualificadas con el equipo
adecuado y ropa protectora.
Nota: El ACS712 Hall, utiliza el principio de detección cuando se utiliza
para evitar el impacto de campo magnético.
El dispositivo tal cual se adquiere, tiene unas prestaciones ventajosas, ya
que está totalmente aislado de la fuente bajo pruebas sin necesidad de
separadores especiales, si usted lo aplica directamente. Este es el aspecto
de una aplicación funcionando.

Fig. 6
De hecho, la aplicación en modo amperímetro se puede entender como tal
ya que se conecta en serie con la carga. Por el momento sólo lo he
probado en corriente continua y con corrientes de unos pocos amperios.

SENSOR DE CORRIENTE ACS712.

Código de ejemplo para visualizar valores del sensor de corriente, en los


terminales de salida.
1 // sensoracs712.pde
2
3 void setup () {
4 // Inicializa la comunicación serial a 9600 bits
5 Serial.begin (9600);
6 }
7
8 void loop () {
9 // Lee el pin de entrada analógica 0 muestra 0-1023:
10 int SensorValue = analogRead (A0);
11
12 // Puede hacer cambios para mostrar en Amperaje
13 // El siguiente código le dice al Arduino que el valor leído por el sensor
14 // debe estar activado de 0-1.023 entre -30 a +30.
15
16 int OutputValue = map (SensorValue, 0, 1023, -30, 30);
17 // Mostrar valor leído por el sensor:
18
19 Serial.print ("Sensor: ");
20 Serial.print (SensorValue);
21
22 // Espectáculo valor transformado en amperios:
23 Serial.print (" Valor en Amperios: ");
24 Serial.println (OutputValue);
25 retardo (100); // Tiempo entre lecturas
26 }
Con este boceto, el monitor Serial nos mostrará los valores del sensor y la corriente que
circula por el circuito. Podemos observar que las lecturas del A/D están con valores sobre
512, como se aprecia en la imagen que sigue:

Fig. 7
El próximo paso es adecuar en lo posible el código y mostrar los
resultados en una pantalla LCD numérica, la misma que nos mostrará la
tensión de salida en cada momento. Veamos algunos aspectos que
tenemos que adjuntar al código, como es la librería ‘LiquidCrystal.h‘ que
debemos descargar la última versión para evitar sorpresas. Copie y pegue
el siguiente código en su Arduino, dele el nombre amp_acs712.ino, cárgelo
y abra el monitor Serial, compruebe que el resultado es más preciso.
El esquema que vamos a utilizar es el siguiente.
Fig. 8

AMPERÍMETRO CON EL ACS712.


Código de ejemplo para visualizar valores del sensor de corriente, en los
terminales de salida.
1 /*
2 amp_acs712.pde
3 http://www.leandroruiz.com/blog/amperimetro-con-arduino/
4 He modificado la formula de modo que ahora
5 Funciona muy bien.
6 */
7
8 #include <LiquidCrystal.h> // lib. LiquidCrystal.h
9 // inicializamos la librería con los de pines de la interface
10 //LCD: (RS,E,D4,D5,D6,D7)
11 LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // mi config.
12 int Zero = 509;
13 long Sensor = 0;
14 int Entradainte = A1; // intensidad
15
16 void setup() {
17 Serial.begin(9600);
18 // Define el número de columnas y filas del display
19 lcd.begin(20, 4);
20 lcd.setCursor(0,0);
21 lcd.print("Sensor ACS712");
22 pinMode(Entradainte, INPUT);
23 digitalWrite(Entradainte, LOW);
24 Serial.println("------------------");
25 Serial.println(" AMPERIMETRO DC");
26 Serial.println("Max. Corriente: ");
27 Serial.println("amperimetro.pde");
28 delay(2000);
29 lcd.clear();
30 }
31
32 void loop() {
33 // Preparamos el display
34 lcd.setCursor(0,0);
35 lcd.print("Current meter");
36
37 // Realizamos la medida
38 // long Sensor = 0;
39 for(int i = 0; i < 1000; i++){
40 Sensor += analogRead(Entradainte);
41 }
42 Sensor /= 1000; // promedio
43 float Intensidad = (5.0*(float)(Sensor-Zero)/1024.0)*1000/66; // la condición es
44 // que el valor de Zero sea el que lee el sensor.
45 Serial.print("Intensidad: ");
46 Serial.print(Intensidad);
47 Serial.println(" A");
48 // Escribimos el valor
49 lcd.setCursor(0,1);
50 lcd.print("I = ");
51 lcd.setCursor(4,1);
52 lcd.print(Intensidad, 3);
53 lcd.setCursor(10,1);
54 lcd.print("A");
55
56 // Esperamos un poco
57 delay(200);
58 }

Si usted ha copiado y ejecutado el anterior código, sin duda que estará


notando unos valores que a menudo cambian, unas cuentas arriba-
abajo. Tal vez piense que hay algún error y efectivamente, el tipo de error
que es muy habitual cuando no se tiene experiencia, es debido a las
matemáticas. Se produce un desbordamiento en la variable Sensor, la
suma de 1000 lecturas analógicas produce el error, la forma sencilla de
solucionar este error, es una cuestión de acoplar el número de cuentas
para evitar el desborde, es decir, el bucle for lo reducimos a 500 pasos y
en este caso, resuelto el error. Pruebelo ahora las lecturas son
homogéneas.
En la imagen de abajo se puede apreciar la respuesta en el monitor Serial
de Arduino.
Fig. 9

Estos son los datos que he extraído del código anterior. Con este código
se puede implementar el voltímetro junto con el LCD y podemos utilizarlo
de forma habitual, sin embargo, intentaremos realizar un código más
completo en el siguiente intento.

Fig. 10 Vídeo del amperímetro.


Como ya he dicho, este amperímetro está bastante logrado, en él podemos
distinguir dos partes, en una se encuentra la electrónica para el sensor
totalmente aislada de las tensiones y corriente externas que vayamos a
mesurar. Por la otra parte, se encuentran las dos tomas o bornas donde
conectaremos la carga exterior, que se consideran el amperímetro
propiamente dicho. El esquema a aplicar puede ser el mostrado en la
figura 6.

OTRO PASO MÁS.

Creo que estamos en el buen camino. Hemos logrado realizar un


voltímetro en este sitio, aquí, hemos conseguido el amperímetro y ahora es
cuestión de unificar ambos códigos y habremos logrado realizar el
dispositivo que propició el proyecto. Así que, manos a la obra, el siguiente
es el circuito que nos permitirá leer la tensión y la corriente de salida sobre
una carga.
Fig. 11

En la imagen se muestra un indicador que dice BATERIA, se refiere a la


tensión continua externa (puede se de 5V o más) que se aplicará a la
CARGA, mostrada en el otro lateral como ya he dicho, la tensión en ambas
tomas o bornas, es distinta de la tensión digital de Arduino o en micro-
controlador en uso. Se puede ver el sensor ACS712 y el divisor de tensión
implicado en la lectura de la tensión de salida, se evidencian las salidas
referidas al pin A0 para la tensión y el pin A1 para la corriente. El
condensador de 100nf es para tirar a masa las tensiones espúreas.

Por lo tanto, sólo nos queda añadir nuestro típico LCD de 2 o 4 líneas, en
mi caso dispongo del 2004A de 4 líneas que es el que voy a utilizar. He
mejorado el circuito y la disposición en la PCB como se puede apreciar,
especial atención a las masas resaltadas en la imagen. En este momento,
el montaje se hará con el Arduino, posteriormente debería utilizarse un
Attiny85.
Fig. 12

Un poco de teoría. Debido a que el Arduino (UNO, R3, Duemilanove,


Diecimila, etc) tiene un ADC de 10 bits, nos entrega una salida entre 0-
1023 (1024 pasos) para una entrada 0-5v. Eso es 0.00488V / paso.
Visita nuestro divisor de tensión. Para un divisor de tensión con R1 = 100kΩ y R2
= 20kΩ, con una tensión máxima de 30V de entrada, se calculará de la
siguiente manera:
1 R1 = 100kΩ
2 R2 = 20kΩ
3 Vin = 30V (CC).
4
5 Vout = (R1 / (R1 + R2)) * Vin ; Vout = (100000 / (100000 + 20000)) * 30v ;
6 Vout = (100000 / 120000) * 30v
7
8 Vout = 0.83 * 30V = 24,9V ; no se admite, por exceso, el max. es 5V
9
10 Si Vout(max) = 5V ;
11
12 Ratio = Vin / Vout ; Ratio= 30 / 5 = 6 ; luego...
13
14 Ratio = 6

Luego un divisor de tensión con R1 = 100k Ohm y R2 = 20k Ohm, una


entrada de 30V, se calculará de la siguiente manera:
Arduino
1 30v / Ratio = 4.98V en pin A0 ; es decir, 30V = 4,98 * 6 (Ratio) = 29,88V; esto sería aceptable.

Con 4,98V se ha dado un margen de seguridad.

Ahora, veamos que ve nuestro pin analógico A0, sí la lectura ADC es 615,
la tensión en pin A0 = 0.004887 * lectura ADC (615 en este caso), o sea
3,0V. Del mismo modo:
Para 1V / 0.00488 = 205 (ADC lectura – redondeando hacia arriba) … y
Para 4V / 0.00488 = 820 (ADC lectura – redondeando hacia arriba)

Entonces, voltaje de lectura o entrada del divisor = tensión pin A0 * Ratio


(o sea 4,98 * 6 = 29,88V)

El código para leer ese valor es el siguiente:


Arduino
1 ADCVal = analogRead (voltInPin); // Lee el voltaje en la salida del divisor, el pin A0
2 pinVoltage = ADCVal * 0,00488; // Calcula el voltaje en el pin A / D
3 // Una lectura de 1 para el A / D = 0.00488mV. Si multiplicamos la lectura A / D por
4 // 0,00488 a continuación obtenemos el voltaje en el pin.

Por cierto, debido a los valores de R1 y R2, la impedancia de entrada de


nuestro dispositivo sería: 100.000 + 20.000 = 120.000 Ohms, esto es muy
importante en un polímetro, sin embargo, puede que sea el causante de
interferencias en las mesuras tomadas, recordemos lo siguiente:

[El ADC en un AVR no puede medir de forma muy precisa las señales
con una alta impedancia de salida, y un divisor de tensión sin duda
cuenta con una alta impedancia. A partir de la hoja de datos
ATmega328P:

El ADC está optimizado para señales analógicas con una impedancia de


salida de aproximadamente 10 kΩ o menos. Si se utiliza una fuente de
este tipo, el tiempo de muestreo será insignificante. Si se utiliza una fuente
de mayor impedancia, el tiempo de muestreo dependerá de cuán largo
tiempo la fuente necesita para cargar el condensador S/H, que puede
variar ampliamente. Se recomienda que el usuario utilice sólo las fuentes
de baja impedancia con las señales que varían lentamente, ya que esto
minimiza la transferencia de carga requerida al condensador H/S.]
Por lo tanto, una opción es bajar en cierta medida dicha impedancia a
valores menos amplios, es decir, R1 = 47K y R2 = 9K1+330 Ohms, esto
conlleva una impedancia de alrededor de 56KΩ que podemos considerar
aceptable.

Aclarado el tema de la impedancia, parece que todo está saliendo como


se esperaba.
CÓDIGO DE PRUEBA.

Esta es la parte más importante del proyecto como es el código que mide
voltios, amperios.
1 /*
2 * volt_amp_watt.pde
3 *
4 * http://arduinotronics.blogspot.com.es/2014/01/volt-amp-watt-hour-meter-shield.html
5 *
6 * Hace un tiempo que he diseñado un medidor de vatios hora para el seguimiento de la
7 * energía producida por energía solar o eólica, consumida por las cargas, y la potencia
8 * contenida en un banco de baterías. He producido una nueva versión basada en la Sparkfun
9 * Protoshield. Éste utiliza un sensor de corriente ACS712 (5 amperios), y está diseñado
10 * para controlar hasta 10 VDC. Diferentes sensores y resistencias actuales se pueden
11 * instalar para otros rangos de corriente y tensión. La próxima actualización será una
12 * cabecera de 16 pines para una pantalla LCD. Así que estad atentos. Código y esquemas de
13 * cableado próximamente.
14 */
15
16 #include <LiquidCrystal.h> // lib. LiquidCrystal.h
17
18 //LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
19 //LCD: (RS, E,D4,D5,D6,D7)
20 LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // mi config.
21
22 const float referenceVolts = 5; // the default reference on a 5-volt board
23 //const float referenceVolts = 3.3; // use this for a 3.3-volt board
24
25 const float R1 = 47000; // value for a maximum voltage of 30 volts
26 const float R2 = 9430;
27 // determine by voltage divider resistors, see text
28 const float resistorFactor = 1023.0 / (R2/(R1 + R2)); // ratio
29 const int batteryPin = A0; // +V from battery is connected to analog pin A0
30
31 int sensorPin3 = A1; // select the input pin for the potentiometerpin input Volt
32
33 int sensorValue0 = 0; // variable to store the value coming from the sensor
34 int sensorValue3 = 0; // variable to store the value coming from the sensor
35
36 void setup() {
37 // initialize Serial communication at 9600 bits per second:
38 Serial.begin(9600);
39 lcd.begin(20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
40 lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
41 lcd.print("Volt Amp Watt");
42 lcd.setCursor(0,1);
43 lcd.print("Volt_amp ");
44 lcd.clear(); // start with a blank screen
45 Serial.print("Volt Amp " );
46 Serial.println("volt_amp_watt.ino" );
47 delay(500);
48 }
49
50 void loop() {
51
52 //int val = analogRead(batteryPin); // read the value from the sensor
53 int val = analogRead(sensorPin3);
54 float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio
55 Serial.print("Volts : ");
56 //Serial.println(volts); // print the value in volts
57 Serial.print(volts); // print the value in volts
58
59 float average = 0;
60 for(int i = 0; i < 1000; i++) {
61 average = average + (.0264 * analogRead(A2) -13.51) / 1000;
62 delay(1);
63 }
64 Serial.print(" Amps : ");
65 Serial.println(average);
66
67 lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
68 lcd.print("Volts: "); // change this text to whatever you like. keep it clean.
69 //lcd.setCursor(0,1); // set cursor to column 0, row 1
70 lcd.print(volts);
71
72 // if you have a 4 row LCD, uncomment these lines to write to the bottom rows
73 // and change the lcd.begin() statement above.
74 lcd.setCursor(0,2); // set cursor to column 0, row 2
75 lcd.print("Amps: ");
76 //lcd.setCursor(0,3); // set cursor to column 0, row 3
77 lcd.print(average);
78
79 delay(500);
80 }

Para que nos calcule los vatios, el nuevo reto, es que necesitamos
contemplar una nueva variable como es el tiempo. Se han de realizar unos
cálculos que considero claves a la hora de comprender el código.

Para calcular vatios (voltios * amperios), amperios hora (amperios * horas)


y vatios hora (watts * horas) requiere el seguimiento del componente de
tiempo, y la realización de un par de cálculos más como los siguientes:
1 float watts = amps * batteryVoltage;
2
3 sample = sample + 1;
4 msec = millis();
5 time = (float) msec / 1000.0;
6
7 totalCharge = totalCharge + amps;
8
9 averageAmps = totalCharge / sample;
10 ampSeconds = averageAmps*time;
11 ampHours = ampSeconds/3600;
12
13 wattHours = batteryVoltage * ampHours;
1 float watts = amps * batteryVoltage;
2
3 sample = sample + 1;
4 msec = millis();
5 time = (float) msec / 1000.0;
6
7 totalCharge = totalCharge + amps;
8
9 averageAmps = totalCharge / sample;
10 ampSeconds = averageAmps*time;
11 ampHours = ampSeconds/3600;
12
13 wattHours = batteryVoltage * ampHours;

MEDIR VOLTIOS EN ALTERNA.

Antes de presentar el código previsto, he pensado en realizar un pequeño


añadido como es, hacer que nuestro voltímetro pueda leer tensiones
alternas hasta 30V. Esto se puede realizar al menos en teoría, mediante
la aplicación de un puente rectificador para que su salida lea la tensión una
vez rectificada naturalmente, debemos hacer un filtrado para que nuestra
lectura no se desvíe de la realidad y un divisor de tensión para que
devuelva el valor real en alterna.

Fig. 13

El esquema anterior nos sirve para medir una tensión alterna de rango
hasta 30V, la tensión a mesurar atraviesa el puente rectificador y es filtrada
por el electrolítico de 220uf/63V, luego llega al divisor de tensión como se
muestra y éste nos presenta la tensión a mesurar. Las resistencias R1 y
R2 se han calculado para que entreguen la tensión más cercana a la real
(la Vin al rectificarse y filtrarse se multiplica por √2 = 1.4142, luego la
tensión de salida del divisor debe descontar este 1.4142 para que la lectura
sea cercana a la real, después, como seguridad se ha puesto diodo zener
de 5V.1 evitando así que se deteriore el micro.

Para hacernos una idea, la siguiente imagen, es un esbozo del proyecto


volt-amperímetro para CC+AC con LCD.
Fig. 14

UN MOMENTO.

Veamos que es lo que tenemos claro hasta el momento, hemos resuelto


el voltímetro, el amperímetro y ahora hemos añadido el voltímetro en
alterna. El esquema final sería el siguiente:

Fig. 15
Sólo nos queda realizar el boceto que aúna los tres dispositivos en uno.
Veamos:

EL CÓDIGO.
En esta ocasión se interviene el tiempo para extraer los vatios/hora.
1 /*
2 watt_meter_lcd.ino
3 Este boceto se describe cómo conectar un Sensor de Corriente ACS715
4 (http://www.pololu.com/catalog/product/1186) a un Arduino,
5 y leer la corriente que fluye a través del sensor.
6
7 */
8 #include <LiquidCrystal.h> // lib. LiquidCrystal.h
9
10 //LCD: (RS, E,D4,D5,D6,D7)
11 LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // mi config.
12 /*
13
14 Vcc a tarjeta sensora para Arduino + 5v
15 GND a tarjeta sensora para Arduino GND
16 OUT a tarjeta sensora para Arduino A0
17
18 Inserte las patillas de potencia en el circuito conductor positivo de carga,
19 la flecha en puntos del soporte board para cargar, otro enganche se conecta
20 al positivo de fuente alimentación.
21
22 Divisor de Voltage:
23
24 R1 = 47k a A2
25 R2 = 9400 a GND
26
27 Vin = 29,89V
28 Vout = 5V
29 Ratio 5,978
30
31 */
32 int batMonPin = A2; //A2 pin entrada del divisor voltage
33 int batVal = 0; // variable para el valor A/D
34 float pinVoltage = 0; // variable que contiene la tensión calculada
35 float batteryVoltage = 0;
36
37 int analogInPin = A1; //A0 pin de entrada mV está conectado a Salida sensor ASC712
38 int sensorValue = 0; // valor leído de la tarjeta soporte ASC712
39 int outputValue = 0; // salida en milliamps
40 unsigned long msec = 0;
41 float time = 0.0;
42 int sample = 0;
43 float totalCharge = 0.0;
44 float averageAmps = 0.0;
45 float ampSeconds = 0.0;
46 float ampHours = 0.0;
47 float wattHours = 0.0;
48 float amps = 0.0;
49
50 // Estos valores para max. Vin = 30V
51 // R1=4700Ω; R2=943Ω. para mayor impedancia
52 int R1 = 47000; // Resistencia of R1 in ohms
53 int R2 = 9400; // Resistencia of R2 in ohms
54
55 float ratio = 0; // Calculated from R1 / R2 = 4,984
56
57 void setup() {
58 // inicializa comunicaciones Serial a 9600 bps:
59 Serial.begin(9600);
60 lcd.begin(20, 4);
61 }
62
63 void loop() {
64
65 int sampleBVal = 0; // muestra V
66 int avgBVal = 0; // porcentage
67 int sampleAmpVal = 0; // muestra A
68 int avgSAV = 0; // porcentage
69
70 for (int x = 0; x < 10; x++){ // ejecutar a través del bucle de 10x
71
72 // leer el valor analógico en:
73 sensorValue = analogRead(analogInPin); //
74 sampleAmpVal = sampleAmpVal + sensorValue; // añadir muestras juntas
75
76 batVal = analogRead(batMonPin); // leer el voltaje en el divisor
77 sampleBVal = sampleBVal + batVal; // añadir muestras juntas
78
79 delay (10); // dejar resolver ADC antes de siguiente muestra
80 }
81
82 avgSAV = sampleAmpVal / 10; // saca el %
83
84 // convert to milli amps
85 outputValue = (((long)avgSAV * 5000 / 1024) - 500 ) * 1000 / 66; // según sensor 66 o 133 mA
86
87 /* sensor da salida sobre 100 en reposo.
88 Analog read produces a value of 0-1023, equiparando de 0v a 5v.
89 "((long)sensorValue * 5000 / 1024)"es la tensión en la salida del sensor en milivoltios.
90 Hay un desplazamiento a restar 500 mv.
91 La unidad produce 66 mV / 133 mV por amperio de corriente, por lo
92 que se divide por 0.066 / 0.133 para convertir mV a mA
93 */
94
95 avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading
96
97 pinVoltage = avgBVal * 0.0048; // 0,00610 Calculate the voltage on the A/D pin
98 /* Una lectura de 1 para el A / D = 0.0048mV
99 Si multiplicamos la lectura A / D por 0,00488
100 entonces obtenemos el voltaje en el pin.
101
102 ¡NOTA! 0,00488 es ideal. Tuve que ajustar a 0,00610
103 contador para que coincida.
104
105 También, dependiendo de la tensión, del cableado y
106 donde se está leyendo, bajo voltaje fuertes cargas
107 que se muestra puede ser bien bajo voltaje en el
108 suministro. Supervisar la carga o la alimentación y decidir.
109 */
110
111 ratio = (float)R1 / (float)R2;
112 batteryVoltage = pinVoltage * ratio; // Utilice la relación calculada del divisor
113 // de tensión para calcular la tensión de la batería
114 amps = (float) outputValue / 1000;
115 float watts = amps * batteryVoltage;
116
117 Serial.print("Volts = " );
118 Serial.print(batteryVoltage);
119 // Serial.print("\t Current (amps) = ");
120 Serial.print(" Current (amps) = ");
121 Serial.print(amps);
122 // Serial.print("\t Power (Watts) = ");
123 Serial.print(" Power (Watts) = ");
124 Serial.print(watts);
125
126 sample = sample + 1;
127 msec = millis();
128
129 time = (float) msec / 1000.0;
130 totalCharge = totalCharge + amps;
131 averageAmps = totalCharge / sample;
132 ampSeconds = averageAmps*time;
133 ampHours = ampSeconds/3600;
134 wattHours = batteryVoltage * ampHours;
135
136 // Serial.print("\t Time (hours) = ");
137 Serial.print(" Time (hours) = ");
138 Serial.println(time/3600);
139
140 // Serial.print("\t Amp Hours (ah) = ");
141 // Serial.print(ampHours);
142 // Serial.print("\t Watt Hours (wh) = ");
143 // Serial.println(wattHours);
144
145 lcd.setCursor(0,0);
146 lcd.print(batteryVoltage);
147 lcd.print(" V ");
148 lcd.print(amps);
149 lcd.print(" A ");
150
151 lcd.setCursor(0,1);
152 lcd.print(watts);
153 lcd.print(" W ");
154 lcd.print(time/3600);
155 lcd.print(" H ");
156
157 lcd.setCursor(0,2);
158 lcd.print(ampHours);
159 lcd.print(" Ah ");
160 lcd.print(wattHours);
161 lcd.print(" Wh ");
162
163 lcd.setCursor(0,3);
164 lcd.print(ratio, 5);
165 lcd.print(" ");
166 lcd.print(avgBVal);
167
168 // wait 10 milliseconds before the next loop
169 // for the analog-to-digital converter to settle
170 // after the last reading:
171 delay(10);
172 }

Das könnte Ihnen auch gefallen