Buenas, estoy con este proyecto donde necesito leer un sensor de presion Wika A10 8-30V 4-20ma 0-6Bar con un Arduino Mega 2560. El sensor lo alimento con una fuente de 12V y utilizo una fuente de 5V para arduino con USB. Despues de ver varios posts de otras personas llegue a este circuito y este codigo pero tengo muchas dudas y el output no es lo que esperaba. Cuando el sensor esta sin presion (presion atmosferica) el ADC lee valores entre 495 y 505 y si mi codigo no esta mal (probablemente lo este) a un voltaje de 5.83 aprox y el mismo valor en la presion.
El output es
497 (varía hasta valores maximos de 510)
5.83 (varía)
0.03 Bar (varía)
Asi es como tengo conectado todo, estoy utilizando el tierra al lado del pin Vin
En un primer vistazo al circuito parece todo ok, pero el valor de la resistencia es un poco alto para mi gusto. Si aplicas la ley de Ohm, cuando el sensor te de 4mA tendrás una caida de 2.4V en la entrada del ADC. Si la salida es de 20mA en el ADC tendrás 12V, fuera de los 5V que el Arduino puede leer.
Para poder leer rangos de 0 a 5 voltios el valor de la resistencia deberia ser de 250 Ohms.
float adc[10];
float average;
...
for(int i=0; i<10; i++){
adc[i] = analogRead(sensor);
}
float average =0;
for(int i=0; i<10; i++){
average = average + adc[i];
}
average = average/10;
Yo no utilizaria floats tan a la ligera. El array adc y la variable average las
declararia como int, siempre y cuando el número de muestras sea relativamente
pequeño.
De todas formas, para ese uso no veo necesario el uso de un array. Basta con hacer lo siguiente:
int average;
float voltaje;
average = 0;
for (int i=0; i<10; i++) {
average = average + analogRead(sensor);
}
average = average/10;
voltaje = (average * 5.0)/1023.0;
Ahora he visto como calculas el voltaje y veo que utilizas 12V!!!. Eso es una aberración, Arduino solo trabaja con 5V. Mas de eso puedes quemar el pin.
Si. El ADC del Arduino no mide 12V y si lo hiciste corres el riesgo de haber dañado su entrada. Tal vez no haya pasado nada pero no repitas ese mal conexionado.
De hecho siempre se protegen las entradas del ADC para no superar los 5V y se usan un zener de 5.1V precisamente.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define sensor A0
int average;
float voltaje;
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
}
void loop() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
average = 0;
for (int i=0; i<10; i++) {
average = average + analogRead(sensor);
}
average = average/10;
voltaje = (average * 5.0)/1023.0;
display.println(average);
delay(10);
display.print(voltaje);
display.println(" Bar");
display.display();
delay(200);
}
Este es el nuevo codigo y cambie la resistencia de 600Ohm por una de 250. En el display tengo 2 outputs
197 (varía entre 196 y 200)
0.96 Bar (varía entre 0.95 y 0.97)
Bueno, primero ver que tan buena es tu fuente de 12V.
Coloca el medidor de tensión y observa como se comporta. Luego si no es buena mejora tu fuente con un capacitor electrolítico de al menos 220uF en adelante.
Tambien puede poner algo similar no tan grande en la entrada del ADC, algo de 10uF 6.3V minimo.
Por ultimo, puedes calcular la mediana (no promedio) que te dará muy buenos resulados.
Busca Arduino mediana, hay librerías muy buenas.
Es una fuente switching 12V 20A comercial del trabajo, desconozco marca y calidad. Mi multimetro lee a la salida de la fuente entre 12.63 y 12.65V, capaz esa es la oscilacion que veo en el output del display? Ahora esta mas estable, modifique el promedio a 100 lecturas con intervalos de 1ms entre lectura pero le voy a dar una mirada a lo la mediana.
Hice pruebas con un piston hidraulico y un manometro patron para encontrar el valor del adc a 6 bares (maximo del sensor) y encontre que cuando llego a 0.5 bar el output del display se pasa a negativo y a partir de ahi el valor del adc comienza a descender. El valor es de 365 que en volts es 1.6V tanto en el output del display como en las mediciones con mi multimetro sobre las conecciones. Alguna idea de porque pasado ese valor se convierte en negativo y empieza a disminuir el valor?
Ejemplo de valores en Volts segun display: 1.58 1.59 1.6 -1.6 -1.59 -1.58... y el valor del adc empieza a disminuir de la misma forma y en negativo
Lo primero que debes hacer es delimitar el problema porque estas abarcando muchas cosas.
Una fuente de switching de 12V 20A es porque la tenias a mano o además alimientas otra cosa? Porque usar eso para instrumentación no es adecuado. Si la usas no le pidas peras al olmo como dice el refrán.
Supongamos que el problema fuente esta delimitado.
Ahora olvida el arduino y coloca el tester en bornes de la R de 250 ohms y lee.
El tester que marca? Lo hace con estabilidad o fluctúa.
Busca ese problema de valores negativos, también.
Los problemas de la linea hidráulica no los translades al Arduino. Circunscríbelos hasta el sensor y una posible fuga en tu sistema hidráulico. Establece presiones y mide y tambien si quieres comprueba con el Arduino simultáneamente, cosa que seguramente harás.
Pero siempre necesitas saber a qué atenerte sin creer que todo lo anterior esta bien.
Es porque la tenia a mano y por ahora es la unica fuente 12V de la que dispongo.
En 0 Bar lee 0.96V y a medida que aumento la presion con el piston hidraulico de pruebas con manometro patron aumenta el voltaje, no llegue a 6 bares porque me detuve cuando detecte el error de los numeros en negativo, lo maximo que llegue fue 2.24V sin fluctuacion en 2 Bar segun manometro patron, el ADC marca -190 y -0.93V en el display de Arduino.
En 4 Bar Patron R250 lee 3.56V, ADC 84 y 0.41V display
La lectura en la R250 parece estar correcta, el sensor se que funciona bien porque lo probe en otro dispositivo y funciona correctamente. Por esto es que dudo sobre el codigo y/o Arduino.
Alguna idea de que pueda ser o que otra prueba podria realizar?
No termino de entender esto.
Entiendo que hasta 2 bares no tienes fluctuaciones y todo funciona dentro de lo esperable.
Ahora bien cuando leiste 2.24V eso correspondería a 2Bares y acá viene lo que no entiendo, el ADC marca -190 y -0.93V en el display?
Veamos esa parte entonces.
Denota una falla en cuentas.
Saqué la ecuación de tu recta Y(bar) = 1.5*X -1.5
Donde Y esta en Bar y X en volts.
para 2.24V corresponden 1.86 bares.
O sea hasta ese valor tienes lecturas estables y luego te da el valor negativo.
Pense que sería por usar int average pero solo calculas 10 valores asi que no es posible.
Si la suma de valores supera los 32768 comienzas a tener valores negativos pero 10 valores no son suficientes porque 1023 x 10 = 10230 y esta dentro de la capacidad de un entero.
No se porque tienes valores negativos por ahora.
Perdon capaz me exprese mal, cuando hablo de fluctuaciones es que las mediciones no varian es decir se quedan fijas en el valor que estoy midiendo.
Ahi esta mi problema, lo hice con 100 valores. Acabo de probar con long int y no mas negativos. Ademas lleve el manometro patron a 6 Bar y el ADC marco 1012 y 4.95V
Ahora solo me queda traducir el ADC a Bar o los Volts a Bar
Se ve que no lees lo que se te escribe
Saqué la ecuación de tu recta
Y(bar) = 1.5X -1.5
Donde
Y esta en Bar y X en volts.
Si X = 1V entonces Y = 1.51-1.5 = 0 Bar
Si X = 5V entonces Y = 1.5*5-1.5 = 7.5-1.5= 6.0 Bar
Ahora bien.. debes delimitar las lecturas a 1 y 5V
Si introduces 0.97V te dará negativo obviamente.
Disculpa, lei rapido y se me paso.
Hice la conversion con el ADC. Primero vi el valor minimo en 0 Bar y luego el valor en 6Bar y utilice un map modificado para flotantes y comparado con el manometro patron calibrado los valores dan exactos e implemente el calculo de la mediana en lugar de promedio.
El codigo quedo asi:
Me quedaria implementar un boton que calibre el ADC para 0 Bar. Segun la fuente que use arduino por USB note cambios en el valor del ADC, creo haber leido un post de alguien que utilizaba un voltaje de referencia de 1.1v interno de arduino que era mas estable pero tendria que volver a buscarlo.
Otro elemento útil es el valor medio móvil, en el los terminos inicial y final se modifican en cada iteracción. Cuando el ADC lee un nuevo valor se descarta el mas viejo y se introduce el nuevo como último. Se calcula el valor medio para esa longitud finita de elementos del array y asi logras que salvo el momento inicial en el que se llena el array luego solo demoras una conversión del ADC mas las cuentas en tener valores promediados. Una mejora muy importante en cálculo.
Estuve leyendo un poco al respecto y es bastante interesante la verdad. Tendria que implementarlo y hacerle un bench de tiempo de ejecucion y compararlo con el codigo actual con multiples sensores al mismo tiempo. Aun asi el uso final tiene tiempos de respuesta de 10 segundos en el mejor de los casos asi que con que cada sensor se actualice unas 2 o 3 veces por segundo es suficiente y actualmente estoy en 0.19 segundos por loop con 10 sensores tomando 100 mediciones de cada uno y calculando la mediana y haciendo los demas calculos y display de datos.
No lo hagas, primero ya esta hecho, busca promedio movil de Luis llamas y listo.
Y ganas mucho tiempo si realmente lo necesitaras la mejora es notable.
Imagina 100 valores x 100use = 10000 useg = 10 mseg no es gran cosa no?
Ahora de la otra manera tienes 100useg mas un extra para mover y quitar 2 valores.
Cual es la mejora? 10000 useg a 120 useg o sea casi 83 (minimo) veces o x ahi?
Si llegue a Luis llamas mientras leia al respecto. Si se ganan esos tiempos como decis es bastante buena la verdad, capaz en unos dias cuando termine con otras partes del proyecto implemente la libreria a ver que tal pero con los tiempos actuales con 16 sensores tengo 0.27s por ciclo lo cual ya es muy bueno para la aplicacion ya que es una persona la que tiene que reaccionar segun los valores.