Mostrando entradas con la etiqueta senor. Mostrar todas las entradas
Mostrando entradas con la etiqueta senor. Mostrar todas las entradas

lunes, 16 de septiembre de 2013

CONTROL PID CON LM35 PARA ARDUINO

CONTROL PID CON LM35 PARA ARDUINO:
ELEMENTO A CONTROLAR: CELDA PELTIER


En nuestras anteriores entradas, hemos aprendido como tomar datos de temperatura y hacer un control ON-OFF, aunque este último no debe usarse debido a su gran rango variable de estabilidad, por esta razón decidimos hacer un control mas continuo utilizando la señal PWM de la ARDUNIO la cual nos controlará la potencia suministrada de la fuente.
Para lograr este control, debemos utilizar un amplificador de señal que será incluido en la conexiones respectivas.
El programa que utilizaremos para graficar los datos se llama STAMPPLOTO PRO V3.9, aqui dejo el link para que lo puedan descargar:

http://www.parallax.com/tabid/441/Default.aspx

Aqui tambien está el manual del STAMPPLOT:

http://www.selmaware.com/downloads/StampPlot_v39_primer.pdf 



Materiales:

  • 2 transistores NPN 2n222
  • 1 Mosfet IRFZ44N
  • 1 Resistencia de 100 Ω
  • 1 Resistencia de 100 KΩ
  • 2 Resistencia de 220 KΩ

Transistor NPN 2n222:


Mosfet IRFZ44M:


Conexiones:


Código:

///////////CONTROL PID//////////////////////

//Variables del Smooting
const int numReadings = 20;
int readings[numReadings];     
int index = 0;                  
int total = 0;                 
float Tprom = 0;               

float chaloTEM= A2; //Puerto analogico de lectura del sensor

float TempR; // Temperatura actual leída
int setpoint = 17 ; // Temperatura deseada "set point"
float error_actual = 0; // Variables de ERROR
float error_anterior = 0;
float t_muestreo = 1000; //Tiempo de muestreo [ms]

//=====Constantes del control PID ================
float Kpe = 40; // Constante Proporcional
float Kie = 0.00005; //Constante de Sumatoria
float Kde = 0.7; //Constante Derivativa del Sistema
float PID = 0; //Señal
//Recordar que las constantes deben ser halladas previamente según el comportamiento del sistema en lazo abierto

//=====Variables de cálculo=====================
float prop = 0;
float inte = 0;
float deri = 0;
float acum = 0;
float area = 0;
float Ts = 0;//Tiempo de Muestreo


void setup()
{
Serial.begin(9600);
   pinMode(7, OUTPUT); // salida de la señal PWM
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0; //For para cantidad de datos promedios del smooting      
}
void loop()
{
//Operaciòn del smooting
  total= total - readings[index];        
  // lectura del sensor
  readings[index] = analogRead(chaloTEM);
  // suma la lectura al total:
  total= total + readings[index];      
  // avance a la siguiente posiciòn en el conteo
  index = index + 1;                   

  // si estamos al final del conteo...
  if (index >= numReadings)             
    // ...vuelva al principio
    index = 0;                          
        
Tprom= ( 5.0 * total * 100.0) / (1023.0 * numReadings);//se pasa de voltaje a temperature y se divide en el numero de lecturas que se quiere promediar
if (setpoint <= Tprom) //=======CELDA ON
 {
   //Serial.print(" Celda ON ");
   //Tiempo de muestreo en segundos:
   Ts = t_muestreo/1000;
   // Tomo la lectura del sensor
   TempR = Tprom; // Consigno el valor leido en esta variable 
   // Conversión lineal de la señal de entrada a temperatura en grados centígrados :
   error_actual = Tprom - setpoint ; //cálculo de error = Tdeseada -Tactual
   //error -> proporcional
   prop = error_actual*Kpe; // Error Proporcional=Kp*errror
   //error -> integral
   area = error_actual+error_anterior; // error sumatoria
   area = area*Ts;
   area = area*0.5;
   acum = acum+area;

   inte = acum*Kie;
   inte = constrain(inte, -110, 110); //filtro anti-windup, para evitar saturación del actuador
   //error -> derivada
   deri = error_actual-error_anterior;
   deri = deri*Kde;
   //PID-->>
   PID = prop + inte + deri;
   PID = constrain(PID, 0, 255); //restricción de la acción de control a rangos admisibles de PWM.
  //Almacenamiento del error actual
  error_anterior = error_actual;
  if(error_actual<1)
  {

  PID = PID;
  //condición primaria
  }
  digitalWrite(7,PID);
  //imprimo los valores deseados
  Serial.print(Tprom);
  Serial.print(",");
  Serial.println(PID);
  Serial.print(" ERROR (+) = ");
  Serial.println(error_actual);
  Serial.println(" ");
 }
 else //==CELDA APAGADA
 {
  //Serial.print(" Celda OFF ");
  PID = PID ;
  digitalWrite(7,PID);
  Serial.print(Tprom);
  Serial.print(",");
  //Serial.print(" PID = ");
  Serial.println(PID);
  Serial.print(" ERROR (-) = ");
  Serial.println(error_actual);
  Serial.println(" ");
  }
  delay(t_muestreo);

}

Recordar: El smooting en un programa ejemplo del arduino que nos enseña como promediar los datos tomados por el sensor análogamente. Si este no se aplica, los datos del sensor serán muy retirados (28.5 , 29.8 , 27.5 , ect) mientras que con el los datos serán mas cercanos (28.5 , 28.7 , 28.9 , ect).

Gráfica deseada:


Gráfica Obtenida:





Espero haya sido de su agrado el trabajo hecho

CONTROL ON-OFF DE TEMPERATURA CON EL SENSOR LM35

CONTROL ON-OFF DE TEMPERATURA CON EL SENSOR LM35 PARA ARDUINO:ELEMENTO DE CONTROL: CELDA PELTIER 

En nuestro anterior entrada hemos aprendido como sensar la temperatura, ahora aprenderemos a crear un control ON-OFF alrededor de una temperatura límite o "set point". El elemento a controlar será una CELDA PELTIER.

Celda Peltier:



Gráfica deseada:


Conexiones:


Relé Shenle JQC:


Código:


int Set_P=23 ;
float Rango=1 ;
float Temp;
int pintemperatura = 2 ;
float Lim_inf = Set_P - Rango ;
float Lim_sup = Set_P + Rango ;
int senal_celda;
void setup (void)
{
Serial.begin (9600);
pinMode(12,OUTPUT);
}
void loop ()
{
Temp=(5.0*analogRead(pintemperatura)*100.0/1024.0);
   if (Temp<Lim_inf)
{
  digitalWrite(12,HIGH);
  }
if (Temp>Lim_sup)
{
  digitalWrite(12,LOW);
  }
else if (Lim_inf < Temp < Lim_sup)
{
 digitalWrite (pintemperatura,senal_celda);  
 }
Serial.print("Temperatura(Celsius)=");Serial.println(Temp);
delay (1000);
}

Explicaremos el código línea por línea, así que tendremos en cuenta que hay 32 de ellas empezando desde la palabra Int.

Línea 1: Temperatura de control, identificada como entero.
Línea 2: Rango de la temperatura de control, identificado como decimal con entero.
Línea 3: Variable real para guardar la temperatura leída por el sensor.
Línea 4: Pin escogido para captar el valor analógico de la temperatura.
Línea 5: Límite inferior de la temperatura de control, como número real.


Línea 6: Límite inferior de la temperatura de control, como número real.
Línea 7: Señal ON-OFF de la celda para ser guardada.
Línea 11: Pin escogido como salida controlada.
Línea 13: Función para repetir indefinidamente el programa.
Línea 15: 5 = Valor analógico de tensión.
Analog read = lectura analógica de tensión.
100.0= Resolución de lectura en microsegundos.
1024.0 = 210, valor binario de 10 dígitos binarios.
Línea 17: Condicional para el rango menor.
Línea 19: Respuesta al condicional en el pin 12.
Línea 21: Condicional para el rango mayor.
Línea 23: Respuesta al condicional en el pin 12.
Línea 25: Condicional para el rango entre la temperatura máxima y mínima.
Línea 27: Indicamos que el valor a tomar es el mismo anterior a este.
Línea 29: Imprimimos el valor de la temperatura.
Línea 31: Demoramos 1s la siguiente toma de datos.


Espero hayan entendido muy bien el proceso

SENSOR DE TEMPERATURA CON LM35 EN ARDUINO

SENSOR DE TEMPERATURA CON LM35 EN ARDUINO

Cuando se instala el ARDUINO y se conecta el cable USB notaremos que los datos no se cargan o simplemente este bota errores varios de lectura y esto ocurre porque los drivers no estan instalados, por esta razón les dejo un video en youtube para que aprendan a instalar los drivers, sea cual sea la serie ARDUINO:

http://www.youtube.com/watch?v=BQArZvGSax8

Ya teniendo todas las herramientas necesarias podemos empezar a leer temperatura.

LM35:


Conexion Basica:


Código:

float pinTemperatura = 2; 
float tempValor ; 
void setup()
{
Serial.begin(9600);
}
void loop()
{
tempValor = ( 5.0 * analogRead(pinTemperatura) * 100.0) / 1024.0;
Serial.print("Temperatura (Celsius) = ");Serial.println(tempValor);
delay (1000);
}

Explicaremos el código línea por línea, así que tendremos en cuenta que hay 15 de ellas empezando desde la palabra float.

Línea 1: Utilizaremos el pin 2 y le pondremos un nombre de lectura entera incluida decimal.
Línea 2: Variable entera+decimal donde guardaremos la temperatura.
Línea 5: Iniciamos el puerto serie para poder monitorizar.
Línea 7: Función para repetir el contenido indefinidamente.
Línea 9: Transformación de la lectura analógica de tensión en temperatura.

5 = Valor analógico de tensión.
Analog read = lectura analógica de tensión.
100.0= Resolución de lectura en microsegundos.
1024.0 = 210, valor binario de 10 dígitos binarios.

Línea 12: Imprimir el valor del puerto serie donde podremos monitorizarlo.
Línea 14: Espera de 1s para cada lectura de temperatura.


Espero haya sido de su agrado este sencillo ejercicio

Recepción IR con Arduino

Hace tiempo que vengo queriendo toquetear un poco las tecnologías inalámbricas, ya que nos permiten la transmisión de datos entre dos puntos sin necesidad de utilizar cables para conectarlos, lo que es una gran ventaja en muchos proyectos.
Hoy por hoy, hay muchos tipos de tecnología inalámbrica como wifi, bluetooth, radiofrecuencia, infrarrojos, gprs, gsm, etc. Yo me voy a centrar en los infrarrojos.
Esta tecnología conocida comoIrDA (Infrared Data Association),es desarrollada por HP, IBM y SHARP allá por 1993 y está basada en rayos de luz que se mueven en el espectro infrarrojo.
(Invisible a los ojos humanos).
Se trata de mediante emisores y receptores (normalmente leds) de ondas infrarrojas, establecer comunicación desde un punto al otro. Es necesario que emisor y receptor se  ”vean”, sin obstáculos de por medio.
Existen muchos protocolos de comunicación infrarroja, ya que este tipo de tecnología inalámbrica se ha utilizado en muchos dispositivos como portátiles, móviles,  PDA’s, y los que más conocemos y seguro todos tenemos en casa, los mandos de TV.
Yo voy a utilizar el protocolo NEC, protocolo que utilizan los mandos universales de TV.
Sigue leyendo!!
 
Para empezar, necesitamos de un receptor de infrarrojos. Yo en mi caso, destrozé un TV de 28” hace tiempo para reciclaje electrónico, y uno de los componentes reciclados fue un receptor TSOP 1238. (Datasheet) .
El TSOP1238 es un receptor de señales infrarrojas, con pre-amplificador de señal incluído que puede alimentarse desde 2,5V hasta 5,5V y su encapsulado de epoxy funciona como filtro IR.
Este receptor, está preparado para ser conectado a un microcontrolador (Arduino en mi caso) y es capaz derecibir señales a 38Khz, que para mi suerte, es la misma frecuencia que utiliza el protocolo NEC de los mandos universales de TV.
Para entender el protocolo NEC me he ayudado de esta web Wiki-Altium – NEC donde está muy bien explicado y básicamente copiaré el funcionamiento.
El protocolo NEC utiliza pulsos a distancia para la transmisión de un mensaje.
Cada ráfaga de pulsos tiene una duración de 562.5 μs a una frecuencia de 38Khz.
Para transmitir los bits correspondientes al mensaje, lo hace de la siguiente manera:
- 0 lógico: Envía un pulso de 562,5 μs, seguido de un espacio de 562,5 μs de duración,  con un tiempo de transmisión de 1,125 ms.
- 1 lógico: Envía un pulso de 562,5 μs seguido de un espacio de 1.6875 ms  de duración, con un tiempo de transmisión de 2,25 ms.
Al pulsar una tecla del mando, el mensaje se compone de la siguiente cadena de pulsos:
1) Una ráfaga de pulsos de 9 ms.
2) Un espacio 4,5 ms
3) La dirección para el dispositivo receptor (8 bits)
4) El inverso lógico de la dirección (8 bits)
5) El comando (8 bits)
6) El inverso lógico del comando (8 bits)
7) Un pulso de 562.5 μs para indicar el final de la transmisión del mensaje.
La siguiente imagen ilustra perfectamente el mensaje transmitido en la pulsación de una tecla de un mando a distancia para una dirección 00000000b y un comando 10110101b.
Para mi suerte, existe una librería para Arduino que se encarga de recibir esta señal y entregarnos un código hexadecimal a partir de los 4 bytes (32 bits) enviados por el mando para poder distinguir cada una de las teclas que hemos pulsado y así poder configurar las teclas del mando a nuestro antojo.
La librería en cuestión, se llama NECIRrcv y podemos descargarla de aquí:  NECIRrcv
Aparcamos la librería un momento y procedemos al montaje del circuito, utilizando el esquema que viene en el datasheet del receptor TSOP1238 para conectarlo al Arduino.
Donde vemos que el IR Receiver (TSOP1238) se conecta por su pin Vs a una resistencia (100Ω valen) y esta a 5V. El pin GND conectado a masa. Y el pin OUT, al microcontrolador, que en nuestro caso será el Arduino.
Listo el circuito y conectado al Arduino, el siguiente paso será recibir los códigos de los botones del mando que vayamos a utilizar en nuestro proyecto,  por lo que cargamos en el entorno de Arduino el ejemplo que viene en la librería NECIRrcv y lo ejecutamos.
Este ejemplo viene preparado para mostrar por el Serial Monitor los códigos correspondientes al botón que hayamos pulsado, como vemos en la siguiente imagen:

Códigos Hexadecimales
Ya utilizando estos códigos o su correspondiente en decimal (Al mostrarlos por el serial monitor quitamos el formateo en hexadecimal de modo que quede: Serial.println(ircode);) podemos controlar cualquier tipo de elemento conectado al Arduino con un mando de TV.
Yo sin complicarme mucho, conecté un led RGB al Arduino y con el mando a distancia podemos controlar el apagado y encendido de los distintos colores del led.
Está programado para controlar el led de la siguiente manera.
- Con el botón “Power” del mando apagamos el led.
- Con el botón “1″ del mando encendemos el color ROJO.
- Con el botón “2″ del mando encendemos el color VERDE.
- Con el botón “3″ del mando encendemos el color AZUL.
El circuito:
Y con el circuito terminado, solo queda hacer las pruebas.
El código de este ejemplo lo dejo para descarga en los siguientes enlaces:
- Archivos librería protocolo NEC para Arduino: NECIRrcv- Código ejemplo de control de un led RGB con mando a distancia: LedRGBIR.pde
Y una prueba de funcionamiento!
:D