jueves, 14 de enero de 2016

8 de Enero

Apenas corre la primera semana de este año y ya da mucho de qué hablar. Esta noche, después de un curioso suceso, me he propuesto  volver a escribir frecuentemente pues me he terminado de convencer finalmente de que olvidamos lentamente la vida de una forma silenciosa. Pequeños detalles se pierden para siempre. Un beso en al lluvia, una carta hecha pedazos o un mensaje de texto hiriente. Olvidamos, convenientemente, que también hemos sido unos hijos de puta. Pero hablemos un poco del año pasado. Inicié 2014 con expectativas en el suelo, quebrado por dentro, emocionalmente abatido. No sabía que esperar de 2015 y fuera lo que fuera sabía que no estaba listo (y tenía razón). Doce meses después esperaba la llegada de otro año sentado en un viejo sillón en la terraza de la casa mi abuela con una extraña tranquilidad. Sabía que había sido un año memorable por todo lo bueno y lo malo. Académicamente ha sido quizá mi mejor año hasta ahora, pero emocionalmente fue un año que me dejó algunas cuantas heridas de guerra. Lastimé y fui lastimado, conocí verdaderamente a la filosofía y definí mi ética personal. Veo con todo esto a 2016 como el incierto año que es pero esta vez sintiéndome listo y armado para el  mal tiempo. Si el hombre sólo puede definirse en la medida que se realiza, como decía Sartre, tengo el ánimo de ver cada día de este año como una página en blanco que no quiero dejar que pase en vano. O lo que quizá sea aún peor: olvidarlas después haberlas escrito como tantas hojas que el tiempo arranca de mi memoria.

viernes, 4 de diciembre de 2015

Implementación de un controlador PID discreto en un PIC18F2550

En esta entrada se utilizará el método desarrollado en la entrada anterior, por lo que saltarán algunos pasos durante el proceso. En esa entrada se implementó un controlador PID para una planta descrita por un doble integrador. En esta ocasión haremos una simulación de un controlador PID implementado en un PIC para controlar una planta construida con amplificadores operacionales. Si bien es posible construir un doble integrador físicamente, resulta impráctico debido a la saturación provocada por la acumulación continua. Para resolver esto, esta planta estará caracterizada por dos integradores con reset resistivo o integradores de ganancia controlada (que una forma elegante de llamar a un filtro pasa-bajas activo de un solo polo) [1].  Eligiendo los valores de resistencia y capacitancia de tal manera que cada integrador tenga ganancia unitaria, la función de transferencia de los 2 integradores nos queda:
 Para controlar esta planta utilizaremos el siguiente controlador discreto a partir de la transformación backward Euler:
Dónde:

Obteniendo transformada inversa, la salida de control descrita como ecuación de diferencias nos queda:
Hacemos la siguiente sustitución de coeficientes:

Estos coeficientes pueden encontrarse manualmente siguiendo el procedimiento descrito aquí, o ejecutando éste programa de Matlab: [PID_Proteus.m]. Teniendo estos valores podemos realizar una verificación de la ecuación en Simulink:

Algo muy importante que se debe notar es que en esta simulación se está considerando la limitación física de la saturación de la salida del controlador real. Sin esta limitación la respuesta del controlador sería más rápida y con un sobreimpulso mucho menor. Sabiendo ahora que nuestra ecuación de diferencias es correcta podemos proceder a escribir el programa en el PIC en lenguaje C con el compilador MikroC. El programa completo se adjuntará más adelante. La función de control principal queda descrita como:

void pid(void) // Función para el controlador
{
   e2=e1; e1=e0; u2=u1; u1=u0; // update de variables
   y = ADC_Read(0);   // Lectura analógica por AN0
   yd = (double) y;  // Conversión a double
   vin = (yd/1023*5);
   y = ADC_Read(1);   // Lectura analógica por AN1
   yd = (double) y;  // Conversión a double
   reff = (yd/1023*5);
   e0 = reff - vin;  // Error
   u0 = ke0*e0 + ke1*e1 + ke2*e2 - ku1*u1 - ku2*u2; // Ecuación de diferencias
   salida = (int) floor(((u0+5)/10)*1023);
   if (salida > 1023) salida = 1023;  // Saturación de DAC
   if (salida <= 0) salida = 0;
   DAC_Output(salida); // Enviar dato
}


Es muy importante que ésta función sea ejecutada dentro de una rutina de interrupción de manera que se tenga control del tiempo de muestreo Ts en exactamente 0.01 segundos para que el controlador funcione correctamente. Para la salida analógica del controlador se esta utilizando un DAC LTC1660 [2][3]. Compilando el programa y simulando en Proteus:


 Nota: El relay en la simulación lo único que hace es evitar que la salida bipolar del DAC envíe un voltaje de saturación negativo al inicio [ver este programa].

lunes, 16 de noviembre de 2015

Implementación de un controlador PID discreto

Supongamos que queremos controlar el mismo modelo de una masa móvil sin fricción que habíamos tratado en esta entrada cuya función de transferencia es la siguiente:

Dados las ganancias del controlador PID que se habían considerado (recomiendo utilizar el app PID Tuning de Matlab si no tienes estos valores para la planta de tu interés) :

La función de transferencia en tiempo continuo de nuestro controlador nos queda:

En la práctica es recomendable utilizar un LPF en la etapa derivativa a modo de reducir el ruido. En este caso la FT es:

Dónde N representa la frecuencia de corte del filtro que suele ser de 100 radianes/s. Teniendo la función de transferencia de nuestro controlador, el proceso de implementación de este controlador en un sistema digital (PIC, Arduino, FPGA, etc) es el siguiente:

La ecuación de diferencias es la que describirá el algoritmo que deberemos implementar en algún lenguaje de programación o un lenguaje de descripción de hardware. Para realizar la transformación entre la FT en dominio de Laplace al dominio de Z debemos considerar las siguientes aproximaciones numéricas para la derivada:


De aquí es fácil notar que podemos representar a la variable s en terminos de z (dónde Ts es el periodo de muestreo) de las siguientes maneras:


Estas 2 transformaciones de la variable s tienen propiedades distintas. Mientras la transformación backward Euler es estable siempre que la FT en tiempo continuo sea estable, la transformación forward Euler no lo es en todos los casos. (Para más detalles consultar la sección 19.2.3.1 de "Pasive, Active and Digital Filters", Wai-Kai Chen [1]). Para este ejemplo utilizaremos la transformación forward Euler, por lo que nuestro controlador queda representado en tiempo discreto por la TF:
Para este ejemplo se sabe de antemano que este controlador es estable pero si se arriesga a utilizar foward Euler se recomienda verificar estabilidad (puede usarse sisotool de Matlab).  Verificamos en Simulink que nuestro controlador funcione correctamente:


Ahora podemos proceder a la conversión de formatos de la FT. Para eso utilizamos el este programa de Matlab: PIDdiscreto.mat. Usando los datos que nos muestra el programa la FT nos queda:


Reordenando (click para agrandar):


Calculando transformada inversa:


Finalmente, verificamos que la ecuación de diferencias sea correcta en Simulink:


En una próxima entrada se implementará este controlador en un código en C para PIC y Arduino.

domingo, 15 de noviembre de 2015

Temas de actualidad

Yo que soy un derechairo-liberal declarado tengo la sospecha que el atentado en París ha sido un evento de falsa bandera. De ser verdad podría ayudarnos a nosotros, ratas de ese laboratorio sociológico llamado Facebook, a decidirnos de que lado estar en esta batalla virtual. Pero ahora, ¿hasta que punto una bandera representa al Leviatán o representa al pueblo? Aún resolviendo eso queda otro problema, ¿a que pueblo se le debe mostrar empatía? A todos en el caso ideal, por supuesto. Pero esta solución genera otro problema; por más utopías que quieran sacarse de la manga, los seres humanos no podemos vivir sin fronteras (en todos los contextos posibles). Siempre he tenido como lema personal esta frase de Huygens, "El mundo es mi país, la ciencia mi religión", pero me he dado cuenta que en un contexto no político, esto no es verdad para mí. Existen muchos grupos sociales que respeto (siendo terriblemente sincero, otros no) más no puedo identificarme. Cargo en mi mente, como todos, fronteras invisibles definidas por reglas de pertenencia social. Y aquí una triste verdad. Aunque lo correcto sea mostrar empatía por la humanidad entera, la paradoja de la elección viene a arruinaros la paz. Elegir todo no es diferente a elegir nada.

jueves, 29 de octubre de 2015

Existencialismo

Si me preguntaran cuales han sido los 3 libros que marcaron mi vida, simplemente diría que sólo hay un ensayo que realmente lo ha hecho, y lo ha hecho más tarde de lo que hubiera querido. Me refiero a "El Existencialismo es un Humanismo" de Sartre. Pasé casi toda mi vida culpando al mundo de mis fallas, pasando por alto una idea tan fundamental; la existencia del hombre precede a su esencia y somos nosotros mismos quienes nos definimos. Quizá en fondo lo sabemos y nos aterra la idea de haber nacido en un mundo indiferente que existe y debe definirse desde cero. Que tarde lo he conocido señor Sartre.

martes, 27 de octubre de 2015

Convertir tiempo UTC a GMST (Tiempo Sideral Medio de Greenwich) en Python

 -*- coding: utf-8 -*-
"""
Created on Tue Oct 27 18:37:49 2015

@author: Rodolfo Escobar et al
"""

from datetime import datetime
from astropy.time import Time
from numpy import floor

# Reductor de rango 0-24h
def to24(x):
 while x >= 24:
  if x < 0:   
   x = x + 24
  if x > 24:
   x = x - 24
 return x
#


# Conversor de formato de hora
def tohms(x):
 time_hours = x
 time_minutes = time_hours * 60
 time_seconds = time_minutes * 60

 horas    = int(floor(time_hours))
 minutos  = int(floor(time_minutes % 60))
 segundos = int(floor(time_seconds % 60))
 return (horas,minutos,segundos)
#

#Programa principal
ut = Time(datetime.utcnow(), scale='utc')
JD= ut.jd # Fecha Juliana
D = JD - 2451545.0
GMST = 18.697374558 + 24.06570982441908*D
GMST = to24(GMST)
(horas,minutos,segundos) = tohms(GMST)
#

print "Hora Sideral:","{h}:{m}:{s}".format(h=horas, m=minutos, s=segundos)


Referencias:
Approximate Sidereal Time, USNO
Local Sidereal Time, Durham University
Astronomy With Your Personal Computer, Peter Duffett-Smith
Astropy.org

viernes, 23 de octubre de 2015

winvid en Matlab 2014/2015

Por alguna razón no viene instalada por defecto ninguna interfaz de video en las ultimas versiones de Matlab. Para resolver esto solo hay que escribir en la consola supportPackageInstaller e instalar el siguiente paquete:


Con esto podrás adquirir la imagen de tu webcam sin problemas después de reiniciar Matlab.

jueves, 17 de septiembre de 2015

Filtro de Notch de 60 Hz

Debido a la restricción de los valores comerciales para los resistores y capacitores, este circuito tiene una frecuencia central de 58.94 Hz. Sin embargo, como se puede ver en una simulación, se tiene una atenuación de -34 dB (un factor de de 0.0004) para la componente de 60 Hz.


Para más detalles sobre este tipo de filtros pueden consultar éste artículo.

domingo, 13 de septiembre de 2015

Circuito para electrocardiografía (ECG/EKG)

Este circuito está basado en el que se puede encontrar en la hoja de datos del INA114. En el circuito original se asume que el rango de voltaje de la señal de entrada es de 1 mV ~ 5 mV más un offset de DC de 300 mV. Sin embargo, en la práctica estos valores resultan ser aún más pequeños (posiblemente por las condiciones poco controladas en un laboratorio de ingeniería universitario o el uso de caimanes y protoboard) así que es necesario incrementar la ganancia del amplificador de instrumentación. Para esta modificación se tiene una ganancia de 2501 y estos fueron los resultados:


En este video utilizan un circuito con ganancia de 100 con buenos resultados (el cual no funcionó en mi caso), lo que me hace sospechar que existen varios factores que afectan el voltaje de entrada. Posiblemente este circuito no funcionará en condiciones diferentes por lo que se deberá experimentar con diferentes valores de ganancia.

Un segundo circuito que también funciona muy bien es una modificación del que pueden encontrar en The Biosignal How-To: