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.
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.
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á.
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.
Espero que haya quedado claro. El modo de conexionado se muestra simbólicamente en la figura siguiente.
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.
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// sensoracs712.pde void setup () { // Inicializa la comunicación serial a 9600 bits Serial.begin (9600); } void loop () { // Lee el pin de entrada analógica 0 muestra 0-1023: int SensorValue = analogRead (A0); // Puede hacer cambios para mostrar en Amperaje // El siguiente código le dice al Arduino que el valor leído por el sensor // debe estar activado de 0-1.023 entre -30 a +30. int OutputValue = map (SensorValue, 0, 1023, -30, 30); // Mostrar valor leído por el sensor: Serial.print ("Sensor: "); Serial.print (SensorValue); // Espectáculo valor transformado en amperios: Serial.print (" Valor en Amperios: "); Serial.println (OutputValue); retardo (100); // Tiempo entre lecturas } |
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:
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.
AMPERÍMETRO CON EL ACS712.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/* amp_acs712.pde http://www.leandroruiz.com/blog/amperimetro-con-arduino/ He modificado la formula de modo que ahora Funciona muy bien. */ #include <LiquidCrystal.h> // lib. LiquidCrystal.h // inicializamos la librería con los de pines de la interface //LCD: (RS,E,D4,D5,D6,D7) LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // mi config. int Zero = 509; long Sensor = 0; int Entradainte = A1; // intensidad void setup() { Serial.begin(9600); // Define el número de columnas y filas del display lcd.begin(20, 4); lcd.setCursor(0,0); lcd.print("Sensor ACS712"); pinMode(Entradainte, INPUT); digitalWrite(Entradainte, LOW); Serial.println("------------------"); Serial.println(" AMPERIMETRO DC"); Serial.println("Max. Corriente: "); Serial.println("amperimetro.pde"); delay(2000); lcd.clear(); } void loop() { // Preparamos el display lcd.setCursor(0,0); lcd.print("Current meter"); // Realizamos la medida // long Sensor = 0; for(int i = 0; i < 1000; i++){ Sensor += analogRead(Entradainte); } Sensor /= 1000; // promedio float Intensidad = (5.0*(float)(Sensor-Zero)/1024.0)*1000/66; // la condición es // que el valor de Zero sea el que lee el sensor. Serial.print("Intensidad: "); Serial.print(Intensidad); Serial.println(" A"); // Escribimos el valor lcd.setCursor(0,1); lcd.print("I = "); lcd.setCursor(4,1); lcd.print(Intensidad, 3); lcd.setCursor(10,1); lcd.print("A"); // Esperamos un poco delay(200); } |
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.
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.
En la imagen se muestra un indicador que dice BATERÍA, 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.
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 2 3 4 5 6 7 8 9 10 11 12 13 14 |
R1 = 100kΩ R2 = 20kΩ Vin = 30V (CC). Vout = (R1 / (R1 + R2)) * Vin ; Vout = (100000 / (100000 + 20000)) * 30v ; Vout = (100000 / 120000) * 30v Vout = 0.83 * 30V = 24,9V ; no se admite, por exceso, el max. es 5V Si Vout(max) = 5V ; Ratio = Vin / Vout ; Ratio= 30 / 5 = 6 ; luego... 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:
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:
1 2 3 4 |
ADCVal = analogRead (voltInPin); // Lee el voltaje en la salida del divisor, el pin A0 pinVoltage = ADCVal * 0,00488; // Calcula el voltaje en el pin A / D // Una lectura de 1 para el A / D = 0.00488mV. Si multiplicamos la lectura A / D por // 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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* * volt_amp_watt.pde * * http://arduinotronics.blogspot.com.es/2014/01/volt-amp-watt-hour-meter-shield.html * * Hace un tiempo que he diseñado un medidor de vatios hora para el seguimiento de la * energía producida por energía solar o eólica, consumida por las cargas, y la potencia * contenida en un banco de baterías. He producido una nueva versión basada en la Sparkfun * Protoshield. Éste utiliza un sensor de corriente ACS712 (5 amperios), y está diseñado * para controlar hasta 10 VDC. Diferentes sensores y resistencias actuales se pueden * instalar para otros rangos de corriente y tensión. La próxima actualización será una * cabecera de 16 pines para una pantalla LCD. Así que estad atentos. Código y esquemas de * cableado próximamente. */ #include <LiquidCrystal.h> // lib. LiquidCrystal.h //LiquidCrystal lcd(12, 11, 10, 9, 8, 7); //LCD: (RS, E,D4,D5,D6,D7) LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // mi config. const float referenceVolts = 5; // the default reference on a 5-volt board //const float referenceVolts = 3.3; // use this for a 3.3-volt board const float R1 = 47000; // value for a maximum voltage of 30 volts const float R2 = 9430; // determine by voltage divider resistors, see text const float resistorFactor = 1023.0 / (R2/(R1 + R2)); // ratio const int batteryPin = A0; // +V from battery is connected to analog pin A0 int sensorPin3 = A1; // select the input pin for the potentiometerpin input Volt int sensorValue0 = 0; // variable to store the value coming from the sensor int sensorValue3 = 0; // variable to store the value coming from the sensor void setup() { // initialize Serial communication at 9600 bits per second: Serial.begin(9600); lcd.begin(20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc. lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row) lcd.print("Volt Amp Watt"); lcd.setCursor(0,1); lcd.print("Volt_amp "); lcd.clear(); // start with a blank screen Serial.print("Volt Amp " ); Serial.println("volt_amp_watt.ino" ); delay(500); } void loop() { //int val = analogRead(batteryPin); // read the value from the sensor int val = analogRead(sensorPin3); float volts = (val / resistorFactor) * referenceVolts ; // calculate the ratio Serial.print("Volts : "); //Serial.println(volts); // print the value in volts Serial.print(volts); // print the value in volts float average = 0; for(int i = 0; i < 1000; i++) { average = average + (.0264 * analogRead(A2) -13.51) / 1000; delay(1); } Serial.print(" Amps : "); Serial.println(average); lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row) lcd.print("Volts: "); // change this text to whatever you like. keep it clean. //lcd.setCursor(0,1); // set cursor to column 0, row 1 lcd.print(volts); // if you have a 4 row LCD, uncomment these lines to write to the bottom rows // and change the lcd.begin() statement above. lcd.setCursor(0,2); // set cursor to column 0, row 2 lcd.print("Amps: "); //lcd.setCursor(0,3); // set cursor to column 0, row 3 lcd.print(average); delay(500); } |
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 2 3 4 5 6 7 8 9 10 11 12 13 |
float watts = amps * batteryVoltage; 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; |
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.
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.
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:
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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/* 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.0048; // 0,00610 Calculate the voltage on the A/D pin /* Una lectura de 1 para el A / D = 0.0048mV Si multiplicamos la lectura A / D por 0,00488 entonces obtenemos el voltaje en el pin. ¡NOTA! 0,00488 es ideal. Tuve que ajustar a 0,00610 contador 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); } |
Esto es todo por este tutorial, espero que les interese a los lectores y estoy esperando sus consultas.
Hola Vicente. Me sirvió de mucho la manera que utilizaste para medir la corriente continua, usando la función map(), pues cuando probé por primera vez este sensor, con otro sketch, las lecturas no correspondian con la realidad.
Comentarte que tuve problemas (que luego solucioné) con los 5V que alimentan al sensor, desde Arduino. Midiendo con un tester comprobé que eran 4,68V, con lo que ya no entregaba 2,5V con 0mA. Pude ajustar a 512 el valor de la entrada analógica. El siguiente problema fue el rango de mapeo. Como nunca entregará 5V en su salida, tuve que modificar el valor de 1023 por otro menor, para una corriente máxima de 5A (que es el modelo que yo tengo). Usando un motor de RC de 240mA y el tester pude calibrar ese valor de 1023 y dejarlo en unos 640. De esa forma, el mapeo lo hace desde 512 hasta 640, para valores de corriente entre 0mA y 5000mA.
Dicho de otra forma, como no recibe 5V nunca entregará ese voltaje a su salida, y por lo tanto Arduino nunca leerá 1023 en su entrada.
Espero haberme explicado.
Gracias de nuevo y saludos.
Excelente estaba buscando algo como esto para un probador de baterías estaba tratando de hacer el sensor con un shunt pero no es lo exacto que queria con esto si puedo alcanzar lo que busco muchas gracias
Hola Carlos.
Me alegra que te haya servido este trabajo como idea para tu desarrollo.
Un saludo.
Hola: me alegra ver que hay personas que se brindan a exponer sus trabajos para otros. Yo se lo agradezco, pero perdone que le diga que estoy hecho la picha un lio.
en un dibujo pone A0,y A1, en un sketch pone A1 A2 , no veo por ningun sitio los 0,66 para el ACS712, y ademas no me funciona . o yo soy muy torpe, o no me explico como se puede variar tanto las cosas, ya que se a pegado un buen rato escribiendo. si no se molesta , (que no es mi intención) podria ser mas escueto y realizar un sketch que fuese el autentico y no dar mas vueltas. se lo agradeceria mucho, pues piense que todo el mundo no somos igual de listos. gracias
No puedo ver el sketch
Hola Jorge.
Lo siento, se han cambiado algunas cosas en el servidor y nos ha dado algún problema que ya ha sido solventado.
Gracias por tu aviso.
Perdon por mi ignorancia…¿como pueden circular 30 A por esas pequeñas borneras verdes, cuando el cable que lleva 30 A tiene que ser mucho mas grueso? ¿No se sobrecalientan?
alguien probo apoyar un cable con corriente (sin cortarlo) ? mide igual?
Hello
Vincent Garcia
greetings
a question
AMMETER WITH ACS712
How would the connection be for a 2.4 NEXTION screen and an ARDUINO NANO, how would the codes be?
CIRCULATION VOLTAGE 30V 10A, I will use the ACS712ELCTR-20A-T
Cheers
Hola Daniel.
Ante todo lamento decir que desconozco la pantalla 2.4 NEXTION, aunque entiendo que dispones de su conexionado habitual. A grandes rasgos, la conexión general del ACS712 XXX, lo puedes ver en la figura 2. En cuanto a los códigos poco más puedo añadir ya que como digo desconozco esa pantalla. Entiendo que el código no debería diferir demasiado aunque debes seguir las recomendaciones del fabricante de la librería adecuada para esa pantalla.
Siento no poder ayudarte más.
Saludos y cuídate.