miércoles, 4 de diciembre de 2013
Velada astronómica en Atlihuetzía
El viernes pasado estuvimos en el jardín de niños Guadalupe Bernal de Cuellar en Atlihuetzía, Tlaxcala llevando el planetario móvil y algunos telescopios. Por primera vez en los años que llevo haciendo divulgación científica con el INAOE trabajé con niños de preescolar; algo que había estado esperando porque fue durante esta época cuando creció mi gusto por la ciencia. Fue muy gratificante escuchar los comentarios de los niños después de darles una pequeña charla dentro del planetario inflable proyectando Stellarium con un espejo esférico. Me agradó mucho ver también el concurso de trajes espaciales organizado por la escuela. Felicito enormemente la labor de los profesores de este kinder, me encantaría ver a todo el país haciendo lo mismo. La etapa preescolar es muy importante para el nacimiento de una vocación científica y es la más descuidada por los divulgadores en Puebla.
Etiquetas:
Anecdotario,
Astronomía,
Divulgación
martes, 26 de noviembre de 2013
Adquisición de Señales Mioeléctricas (EMG)
La electrónica médica es un área a la que personalmente siempre he rehuido. Sin embargo esta práctica para la materia Procesamiento Digital de Señales me ha reconciliado bastante con esta ciencia. No pretendo hacer un reporte completo en esta entrada, pero si describir todo lo relevante al circuito y a la adquisición por la PC para que este interesante experimento pueda realizarse por otros estudiantes. Este es el circuito utilizado:
El amplificador de instrumentación es algo difícil de encontrar en México pero puede comprarse en linea en Newark, el envío es gratis y demora unos 4-6 días. Si viven en CDMX, pueden comprarlo en AG Electrónica. Para el filtrado posterior se considera únicamente el rango de frecuencias de 50 - 500 Hz, eliminando la componente de ruido de 60 Hz del suministro eléctrico. Para implementar los filtros se puede usar un TL084, LM348 o un LM224 aunque lo ideal es pedir dos opamp's de baja distorsión OPA2604 para reducir el ruido en la señal. V+ y V- van conectadas a 5V y -5V respectivamente. Si quieres hacer pruebas en tu casa y no cuentas con fuentes de laboratorio puedes hacer un arreglo de dos baterías de 9V reguladas con un 7805 y un 7905 (-5V).
Hay dos maneras de adquirir los datos a la PC: vía serial (Con Arduino o un PIC) o usando SoundcardScope a través de la tarjeta de audio. Si vas a utilizar esta última opción, es necesario mapear la señal de +/-5V a +/- 1V. Para esto debes usar el siguiente circuito divisor de voltaje en la salida del filtro de Notch (antes del rectificador de precisión):
Nota: la resistencia de 13K en el filtro de Notch es obligatoria, quiero decir que no puede ser sustituida por un valor comercial cercano. Será necesario utilizar un trim-pot.
Nota 2: El electródo de referencia va en en la muñeca o el codo.
Update: Este filtro de Notch funciona mucho mejor
Etiquetas:
Arduino,
Electrónica,
Instrumentación Biomédica
martes, 29 de octubre de 2013
A veces, emborrachados por los descubrimientos y logros incesantes de la ciencia moderna, de forma inconsciente, guiados por el hecho de que el conocimiento es generado cada día, nos vemos secretamente guiados a “sentir” que la realidad se fabrica en ese momento. Como si el ‘top quark’ no hubiera existido hasta su descubrimiento. Como si la curvatura del espacio-tiempo no hubiera existido en la época de Euclides. Como si la naturaleza cuántica de la fotosíntesis no hubiera sido. Un algo simplemente inexistente.
Lo maravilloso, lo sorprendente es que siempre han sido. Pero no solo ellos, sino todo conocimiento futuro. Toda base del conocimiento futuro que pueda existir alguna vez. Todo cuanto es posible expresar como tal. Todo ello, lo inimaginable, lo lejano y lo cercano, el borde mismo del Universo, existe.
viernes, 27 de septiembre de 2013
Revolución
Hace poco edité un cartel facebuquero con el título "Libros recomendados para entender cómo hacer una revolución". La corta lista de 3 libros la tomé del video Revolution: An Instruction Manual: "From Dictatoship to Democracy" de Gene Sharp, una guía corta sobre procedimientos de resistencia civil que puede leerse en una sola tarde , "The Crawl" y "The Psychology of Revolution" de Gustave Le Bon. Publiqué el cartel en una página de divulgación científica que mantengo junto con los enlaces las ediciones digitales en español de los 3 libros. Más por curiosidad de experimento social que de "sed revolucionaria" envíe un enlace al cartel con un breve texto a todas las páginas de "revos" que puede encontrar. Sólo una se interesó por la publicación y dio un share que se perdió entre memes de EPN. Más de uno me ha mirado con desaprobación al oírme decir que los adolescentes y adultos jóvenes de este país no quieren realmente un país mejor sino que disfrutan la catarsis del desprecio al símbolo opresor.
miércoles, 18 de septiembre de 2013
Interrupciones externas con PIC18f4550 en MikroC
[Update: El 4550 ya es un poco viejo. ¿No quieres echarle un ojo al 45K50?]
La mayoría de los tutoriales que hay en internet sobre interrupciones en microcontroladores parecen decirnos todo lo que ya sabemos excepto lo que realmente necesitamos. Por esta razón no vamos a tratar aquí las generalidades del proceso. El mejor consejo que puede darse para ser un buen programador de microcontroladores es confiar en la hoja de especificaciones del dispositivo más que en cualquier tutorial. Muchos de los proyectos disponibles en la web son un horrible copy & paste de segmentos de códigos que le funcionaron al programador en otros casos y le fue más sencillo adaptarlos a nuevos propósitos. Muchos de estos programas están repletos de lineas innecesarias y algoritmos innecesariamente complejos que sólo asustan a los que apenas se aventuran en el mundo de los microcontroladores. Si realmente se entiende el funcionamiento, limitaciones y ventajas del PIC en cuestión, la programación simplemente "fluirá" de las manos. Si uno se acostumbra a usar la hoja de especificaciones se podrá adaptar cualquier buen tutorial a un PIC diferente al utilizado en el tutorial. Comencemos...
Registros
Un microcontrolador es, en un sentido estricto, una computadora y hará lo que le ordenes. Los registros nos sirven para configurar la funcionalidad del dispositivo; lo que queremos que se habilite o deshabilite y como queremos que se comporte. Así mismo nos permite saber las cosas se ejecutaron como se ordenaron por medio de banderas (flags). Para el 18F4550 tenemos tres registros de control de interrupciones: INTCON, INTCON2 e INTCON3. Para más detalles pueden revisar la data. Aquí entraremos directo a un ejemplo sencillo:
Ejemplo Encender un LED con un flanco de bajada y apagarlo con un flanco de subida en INT0
Esto, por supuesto, podemos hacerlo sin utilizar interrupciones, pero el punto aquí es visualizar el funcionamiento de estas. Bien entendido, puede utilizarse este ejemplo para hacer cosas más interesantes como un frecuenciometro, medidor de rpm's o cualquier cosa por la que hayan llegado aquí.
Primero, definamos que es lo queremos hacer.
1. Queremos que haya una bandera que se active cuando INT0 se interrupa en flanco de subida.
2. Queremos que la misma bandera se limpie y se vuelva a activar pero con un flanco de bajada.
3. Finalmente queremos utilizar este proceso para hacer algo útil.
Bien, primero entonces debemos modificar los registros correspondientes. Necesitamos una línea que habilite la interrupcion externa por INT0
INTCON.INT0IE = 1; // Interrupción externa INT0 habilitada
...otra línea que habilite todas la interrupciones de manera que nuestro vector de interrupción se ejecute continuamente
INTCON.GIE = 1; // Habilita todas las interrupciones
...y otra que habilite (inicialmente) el disparo de la bandera por flanco de subida
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
Esta última linea modifica un bit del registro INTCON2. Como las 2 primeras lineas modifican bits del mismo registro, podríamos reducirlas a una sola linea igualando todo el registro al valor del byte deseado. Pero para fines didácticos lo dejaremos así. Bien, lo que sucederá hasta este punto en el programa será que cuando haya un cambio de bajo a alto en RB0 (INT0) la bandera INT0IF, que está en el registro INCON, cambiará a uno y se quedará en ese estado hasta que resetee vía software.
Rutina de interrupción
void interrupt(){
-Instrucciones-
}
Al leer esta rutina, el compilador sabrá que deberá escribir esas lineas de código en el espacio de memoria llamado vector de interrupción. Puesto que se habilitó el bit GIE del registro INCON, no será necesario llamar a "interrupt" desde "main" como normalmente se haría en lenguaje C. Para este ejemplo requerimos que nuestra rutina de interrupción envíe un '1' a RD0 después de detectar un flanco de subida y un '0' al detectar un flanco de bajada. Para esto necesitamos una variable que llamaremos flagFlanco y otra LED que contendrá el estado del puerto. El código completo nos queda:
int LED = 0;
bit flagFlanco; // Las variables de este tipo no pueden
// inicializarse (0 por default)
void interrupt(){
if(INTCON.INT0IF == 1){
flagFlanco = ~flagFlanco;
INTCON.INT0IF = 0; // Limpiar bandera de INT0
}
if( flagFlanco == 1 ){
LED = 1;
INTCON2.INTEDG0 = 0; //INT0 en flanco de bajada
}
else {
LED = 0;
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
}
}
void main() {
ADCON1 |= 0x0F;
CMCON |= 7;
INTCON.INT0IE = 1; // Interrupción externa INT0 habilitada
INTCON.GIE = 1; // Habilita todas las interrupciones
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
TRISD = 0x00; // Puerto D como salidas
//TMR0 activado, prescaler 1:2
T0CON = 0b10000000;
while(1) {
PORTD.F0 = LED;
}
}
La mayoría de los tutoriales que hay en internet sobre interrupciones en microcontroladores parecen decirnos todo lo que ya sabemos excepto lo que realmente necesitamos. Por esta razón no vamos a tratar aquí las generalidades del proceso. El mejor consejo que puede darse para ser un buen programador de microcontroladores es confiar en la hoja de especificaciones del dispositivo más que en cualquier tutorial. Muchos de los proyectos disponibles en la web son un horrible copy & paste de segmentos de códigos que le funcionaron al programador en otros casos y le fue más sencillo adaptarlos a nuevos propósitos. Muchos de estos programas están repletos de lineas innecesarias y algoritmos innecesariamente complejos que sólo asustan a los que apenas se aventuran en el mundo de los microcontroladores. Si realmente se entiende el funcionamiento, limitaciones y ventajas del PIC en cuestión, la programación simplemente "fluirá" de las manos. Si uno se acostumbra a usar la hoja de especificaciones se podrá adaptar cualquier buen tutorial a un PIC diferente al utilizado en el tutorial. Comencemos...
Registros
Un microcontrolador es, en un sentido estricto, una computadora y hará lo que le ordenes. Los registros nos sirven para configurar la funcionalidad del dispositivo; lo que queremos que se habilite o deshabilite y como queremos que se comporte. Así mismo nos permite saber las cosas se ejecutaron como se ordenaron por medio de banderas (flags). Para el 18F4550 tenemos tres registros de control de interrupciones: INTCON, INTCON2 e INTCON3. Para más detalles pueden revisar la data. Aquí entraremos directo a un ejemplo sencillo:
Ejemplo Encender un LED con un flanco de bajada y apagarlo con un flanco de subida en INT0
Esto, por supuesto, podemos hacerlo sin utilizar interrupciones, pero el punto aquí es visualizar el funcionamiento de estas. Bien entendido, puede utilizarse este ejemplo para hacer cosas más interesantes como un frecuenciometro, medidor de rpm's o cualquier cosa por la que hayan llegado aquí.
Primero, definamos que es lo queremos hacer.
1. Queremos que haya una bandera que se active cuando INT0 se interrupa en flanco de subida.
2. Queremos que la misma bandera se limpie y se vuelva a activar pero con un flanco de bajada.
3. Finalmente queremos utilizar este proceso para hacer algo útil.
Bien, primero entonces debemos modificar los registros correspondientes. Necesitamos una línea que habilite la interrupcion externa por INT0
INTCON.INT0IE = 1; // Interrupción externa INT0 habilitada
...otra línea que habilite todas la interrupciones de manera que nuestro vector de interrupción se ejecute continuamente
INTCON.GIE = 1; // Habilita todas las interrupciones
...y otra que habilite (inicialmente) el disparo de la bandera por flanco de subida
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
Esta última linea modifica un bit del registro INTCON2. Como las 2 primeras lineas modifican bits del mismo registro, podríamos reducirlas a una sola linea igualando todo el registro al valor del byte deseado. Pero para fines didácticos lo dejaremos así. Bien, lo que sucederá hasta este punto en el programa será que cuando haya un cambio de bajo a alto en RB0 (INT0) la bandera INT0IF, que está en el registro INCON, cambiará a uno y se quedará en ese estado hasta que resetee vía software.
Rutina de interrupción
void interrupt(){
-Instrucciones-
}
Al leer esta rutina, el compilador sabrá que deberá escribir esas lineas de código en el espacio de memoria llamado vector de interrupción. Puesto que se habilitó el bit GIE del registro INCON, no será necesario llamar a "interrupt" desde "main" como normalmente se haría en lenguaje C. Para este ejemplo requerimos que nuestra rutina de interrupción envíe un '1' a RD0 después de detectar un flanco de subida y un '0' al detectar un flanco de bajada. Para esto necesitamos una variable que llamaremos flagFlanco y otra LED que contendrá el estado del puerto. El código completo nos queda:
int LED = 0;
bit flagFlanco; // Las variables de este tipo no pueden
// inicializarse (0 por default)
void interrupt(){
if(INTCON.INT0IF == 1){
flagFlanco = ~flagFlanco;
INTCON.INT0IF = 0; // Limpiar bandera de INT0
}
if( flagFlanco == 1 ){
LED = 1;
INTCON2.INTEDG0 = 0; //INT0 en flanco de bajada
}
else {
LED = 0;
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
}
}
void main() {
ADCON1 |= 0x0F;
CMCON |= 7;
INTCON.INT0IE = 1; // Interrupción externa INT0 habilitada
INTCON.GIE = 1; // Habilita todas las interrupciones
INTCON2.INTEDG0 = 1; // INT0 en flanco de subida
TRISD = 0x00; // Puerto D como salidas
//TMR0 activado, prescaler 1:2
T0CON = 0b10000000;
while(1) {
PORTD.F0 = LED;
}
}
domingo, 8 de septiembre de 2013
viernes, 26 de julio de 2013
viernes, 19 de julio de 2013
Detector de similitud de imagenes
Es muy útil poder cuantificar la similitud entre dos imagines para todo sistema de visión por computadora. Uno de los algoritmos más utilizados por su sencillez y efectividad es el Coeficiente de Correlación de Pearson. Si consideremos a una imagen digital como una muestra de datos de un evento "aleatorio", podemos reescribir el coeficiente de la siguiente forma:
donde el numerador representa a la covariancia de los datos (valores de los pixeles) de la imagen A y B y el denominador es el producto de la desviación estándar de los datos de la imagen A por la desviación estándar de los de la imagen B. Podemos implementar un detector de similitud en Matlab. Antes, hay que mencionar algunas características de la función cov(). Supongamos que tenemos dos conjuntos de datos:
La función cov() dará como resultado una matriz donde la posición (1,1) es la covarianza de la primer columna consigo misma, (1,2) es la covarianza de la primera con la segunda, (2,1) la segunda con la primera y (2,2) la segunda consigo misma:
>> cov(x,y)
ans =
4.5667 0.8333
0.8333 8.5667
En este caso las únicas posiciones que nos interesan son la (1,2) o la (2,1). Conociendo este detalle podemos implementar sin problemas un algoritmo de detección de similitud de la siguiente forma:
% Carga de imagenes
I = imread('dali.jpg');
I2 = imread('dali6.jpg');
subplot(1,2,1),imshow(I),title('Imagen A')
subplot(1,2,2), imshow(I2),title('Imagen B')
% Conversion a escala de grises y escalamiento
Is = rgb2gray(I);
[n m] = size(Is);
I2 = imresize(I2,[n m]);
I = rgb2gray(I);
I = double(I);
I2 = rgb2gray(I2);
% Cambio de forma matricial a vector y cambio de formato
Ir = reshape(I, [1 numel(I)]);
Ir = double(Ir);
Ir2 = reshape(I2, [1 numel(I2)]);
Ir2 = double(Ir2);
% Cálculo del CCP
Sx = std(Ir);
Sy = std(Ir2);
Cxym = cov(Ir,Ir2);
Cxy = Cxym(2,1);
p = Cxy/(Sx*Sy)
if p > 0.7
disp('La imagen es la misma')
else
disp('Las imagenes son diferentes')
end
donde el numerador representa a la covariancia de los datos (valores de los pixeles) de la imagen A y B y el denominador es el producto de la desviación estándar de los datos de la imagen A por la desviación estándar de los de la imagen B. Podemos implementar un detector de similitud en Matlab. Antes, hay que mencionar algunas características de la función cov(). Supongamos que tenemos dos conjuntos de datos:
x = [ 1 3 4 6 7 4];
y = [ 6 7 1 4 9 8];
Si queremos obtener la covariancia entre ambos conjuntos utilzando cov(x,y), lo primero que hará la función es concatenar ambos vectores de la siguiente manera:
[x y ]
1 6
3 7
4 1
6 4
7 9
4 8
La función cov() dará como resultado una matriz donde la posición (1,1) es la covarianza de la primer columna consigo misma, (1,2) es la covarianza de la primera con la segunda, (2,1) la segunda con la primera y (2,2) la segunda consigo misma:
>> cov(x,y)
ans =
4.5667 0.8333
0.8333 8.5667
En este caso las únicas posiciones que nos interesan son la (1,2) o la (2,1). Conociendo este detalle podemos implementar sin problemas un algoritmo de detección de similitud de la siguiente forma:
% Carga de imagenes
I = imread('dali.jpg');
I2 = imread('dali6.jpg');
subplot(1,2,1),imshow(I),title('Imagen A')
subplot(1,2,2), imshow(I2),title('Imagen B')
% Conversion a escala de grises y escalamiento
Is = rgb2gray(I);
[n m] = size(Is);
I2 = imresize(I2,[n m]);
I = rgb2gray(I);
I = double(I);
I2 = rgb2gray(I2);
% Cambio de forma matricial a vector y cambio de formato
Ir = reshape(I, [1 numel(I)]);
Ir = double(Ir);
Ir2 = reshape(I2, [1 numel(I2)]);
Ir2 = double(Ir2);
% Cálculo del CCP
Sx = std(Ir);
Sy = std(Ir2);
Cxym = cov(Ir,Ir2);
Cxy = Cxym(2,1);
p = Cxy/(Sx*Sy)
if p > 0.7
disp('La imagen es la misma')
else
disp('Las imagenes son diferentes')
end
miércoles, 17 de julio de 2013
S.
Pareciera ser el caso de que últimamente sólo escribo de mi vida cuando algo anda mal o estoy enojado. ¿Por qué no estoy escribiendo cuando siento que cada cosa en la tierra me sonríe? Nunca había tenido tan cerca de mi vida a una mujer tan perfecta. Puede interpretarse la palabra “perfecta” como la ausencia de defectos. Quizá por mis inevitables analogías de ingeniería prefiero usar el adjetivo “ideal” para tal fin. Al decir perfecta, en mi contexto, no me refiero a una mujer libre de defectos, sino a una mujer que dispara y desborda mis emociones de formas inexplicables como si tuviera marcado dentro de mi mente un margen entre lo común y lo extraordinario.
domingo, 7 de abril de 2013
Contador de objetos con webcam en Matlab
El programa es muy similar al contador de objetos dibujados en un archivo JPG como el de la entrada anterior:
winvid = videoinput('winvideo',1,'YUY2_320x240'); % Probablemente tengas que ajustar esta linea a tu webcam
capt1 = getsnapshot(winvid);
img = rgb2gray(capt1);
bin = img <= min(min(img))+20;
%filtro antiruido tomado de Floydbot
magic=strel('square', 2);
binf=imerode(bin, magic);
cen = regionprops(binf,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
El archivo .fig y .m vienen en la carpeta que pueden descargar en el siguiente enlace:
sábado, 6 de abril de 2013
Visión por computadora: Contador de objetos en Matlab
Supongamos que hemos dibujado algunos objetos en Paint, por ejemplo:
Podemos implementar un programa en Matlab que cuente los objetos dibujados en una imagen como la anterior de la siguiente forma:
clear, clc
imagen = imread('objetos.jpg');
img = rgb2gray(imagen); %Conversión RGB a Escala de grises
imshow(imagen)
title('Imagen Original')
binaria = img<=20; % Binarización de la imagen
cen = regionprops(binaria,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
fprintf('Numero de objetos: %d\n',num)
Para este ejemplo he guardado la imagen en formato JPG, pero Matlab soporta además los formatos PNG, BMP, GIF, TIFF y XWD. La imagen, como deben recordar, debe encontrarse en el directorio de trabajo que estemos utilizando para que pueda ser llamada por el programa. Próximamente veremos como contar objetos dibujados en una hoja de papel utilizando una webcam.
Podemos implementar un programa en Matlab que cuente los objetos dibujados en una imagen como la anterior de la siguiente forma:
clear, clc
imagen = imread('objetos.jpg');
img = rgb2gray(imagen); %Conversión RGB a Escala de grises
imshow(imagen)
title('Imagen Original')
binaria = img<=20; % Binarización de la imagen
cen = regionprops(binaria,'centroid'); % Calculo de centroides
num = numel(cen); % Conteo de centroides
fprintf('Numero de objetos: %d\n',num)
Para este ejemplo he guardado la imagen en formato JPG, pero Matlab soporta además los formatos PNG, BMP, GIF, TIFF y XWD. La imagen, como deben recordar, debe encontrarse en el directorio de trabajo que estemos utilizando para que pueda ser llamada por el programa. Próximamente veremos como contar objetos dibujados en una hoja de papel utilizando una webcam.
sábado, 30 de marzo de 2013
Grupos de Divulgación Científica en México
Me encontré con un problema al tratar de contar los grupos de divulgación en nuestro país. ¿Cómo contactarlos a todos? Hasta ahora sólo podría mencionar a grupos activos como Hipercubo (Puebla), GUDIC (Querétaro) y Quark (Zacatecas). Supongo y confío que deben haber muchos más, especialmente en el DF, Guadalajara y Monterrey. Están también los grupos institucionales como el del INAOE (en el que trabajo) y del taller de óptica de la BUAP. Grupos de este tipo deben ser también comunes en varias universidades y centros de investigación. Sería interesante consolidar una red nacional de estos grupos como ya lo habían propuesto divulgadores del INAOE hace unos años. Sería interesante poder compartir experiencias, experimentos y organizar actividades conjuntas.
Tengo ya bastantes presentaciones y proyectos que podrían usarse por otros divulgadores. Y aquí quizá he pecado por no escribir sobre lo que hago, sobre mi experiencia como divulgador. Espero remediar esto pronto.
Tengo ya bastantes presentaciones y proyectos que podrían usarse por otros divulgadores. Y aquí quizá he pecado por no escribir sobre lo que hago, sobre mi experiencia como divulgador. Espero remediar esto pronto.
lunes, 18 de marzo de 2013
Guia para el estudiante universitario de nuevo ingreso
Este, como otros de mis escritos, es una carta más que quisiera enviarme al pasado, justo al comienzo de mi primer año en la universidad. Han pasado casi 4 años desde entonces y es han ahora cuando puedo ver de modo claro lo que debí haber hecho. Esta guía, ensayo o recopilación de consejos va orientada a estudiantes de ingeniaría y ciencias. Naturalmente deben existir consejos universales pero ya bastantes artículos pueden ser consultados en la red para ese caso. Mi labor solidaria recae en los detalles particulares que nadie te ha dado.
Existe una cuestión mental llamada disracionalidad. En pocas palabras, es la incapacidad de comportarse o resolver un problema racionalmente a pesar de tener la inteligencia adecuada. Existe la teoría de que este comportamiento existe porque para nuestros ancestros les era mejor evitar detenerse a pensar para huir rápidamente del peligro. Menciono esto porque cuando estés a mitad de carrera te darás cuenta que podías haber sabido lo que sabes en ese momento desde el principio de la carrera. Tienes toda la capacidad para aprender todo lo que necesitas en tu carrera desde un principio. Esto es un hecho y no una frase vacía de "motivación personal".
Ahora que tienes identificada la disracionalidad debes luchar contra ella. Pierde el miedo a aprender cosas que tomas por difíciles. Hasta aquí hemos hablado de capacidad (la tienes), pero el aprendizaje es como una escalera y no puedes simplemente saltar hasta el último escalón. Debes dominar los escalones más bajos. Comienza con estos:
Álgebra: Inevitablemente todo se reducirá a álgebra en algún punto así estés haciendo matemáticas complejas (desde Calculo, Ecuaciones Diferenciales, Variable Compleja hasta análisis de Fourier). No puedes sobre-confiarte en esta área. Desde un principio deberás repasar todo hasta el cansancio. Has una libreta de apuntes con todo lo relevante: métodos de localización de raíces de polinomios, fracciones parciales, etc...
Lógica*: Para lic. en física y matemáticas se verá bastante duro este punto y posiblemente sea algo completamente nuevo para muchos. No queda de otra más que tomar 3 o más libros de lógica o elementos de matemáticas de tu biblioteca. Te deben quedar claro los métodos de demostración y la lógica proposicional.
*Tal vez pueda omitirse para estudiantes de ingeniería.
Programación: No le temas. Desde el primer semestre notarás que tus compañeros que vienen de escuelas técnicas te llevarán ventaja en este punto. Algunos habrán comenzado a programar en C, Basic o Java desde la secundaria. No importa, bastan pocas semanas para alcanzarlos. Aún si eres tu el estudiante que llevó algún curso de programación no debes confiarte. Consigue Dev-C++ en este instante y empieza a repasar o a aprender. ¿Cómo empezar? Consigue todo el material que puedas en tu biblioteca. Si tienes un amigo que sepa programar muy bien, pídele ayuda.
Arduino: ¿Vas para electrónica o mecatrónica? Consigue un Arduino en tiendas de componentes electrónicos y aprende a programarlo con tutoriales en línea. Sé lo que digo. Incluso si vas para física te servirá para controlar tus propios experimentos, hacer adquisición de datos y computo físico. No hay prisa, yo también empecé haciendo un led parpadear.
Matlab: Debes entender desde un principio que WinPlot y los graficadores en linea son de lo más corriente. Sé que te parecerán más fáciles de usar, pero a la larga el dominar herramientas de software matemático como Matlab te darán muchas ventajas. Este software parece difícil de usar por su ventada de comandos, pero no lo es. Es como manejar un auto standard. Existen muchos tutoriales en español así que consiguelo cuanto antes y comienza a jugar con él.
Puedo asegurarte que estas son todas las bases que necesitas. Tómalos como un estudió extra, paralelo a tus primeras materias. El resto vendrá a su tiempo de acuerdo a tu programa de estudios. Quizá podría agregar para los estudiantes de electrónica/ mecatrónica/ ing. eléctrica comprar y leer Fundamentos de Circuitos Eléctricos de Sadiku desde el primer momento que ponen un pie en la universidad. ¿Y que hay de la parte personal y social? Me tomaría una entrada entera... o puedes leer el resto del blog...
Existe una cuestión mental llamada disracionalidad. En pocas palabras, es la incapacidad de comportarse o resolver un problema racionalmente a pesar de tener la inteligencia adecuada. Existe la teoría de que este comportamiento existe porque para nuestros ancestros les era mejor evitar detenerse a pensar para huir rápidamente del peligro. Menciono esto porque cuando estés a mitad de carrera te darás cuenta que podías haber sabido lo que sabes en ese momento desde el principio de la carrera. Tienes toda la capacidad para aprender todo lo que necesitas en tu carrera desde un principio. Esto es un hecho y no una frase vacía de "motivación personal".
Ahora que tienes identificada la disracionalidad debes luchar contra ella. Pierde el miedo a aprender cosas que tomas por difíciles. Hasta aquí hemos hablado de capacidad (la tienes), pero el aprendizaje es como una escalera y no puedes simplemente saltar hasta el último escalón. Debes dominar los escalones más bajos. Comienza con estos:
Álgebra: Inevitablemente todo se reducirá a álgebra en algún punto así estés haciendo matemáticas complejas (desde Calculo, Ecuaciones Diferenciales, Variable Compleja hasta análisis de Fourier). No puedes sobre-confiarte en esta área. Desde un principio deberás repasar todo hasta el cansancio. Has una libreta de apuntes con todo lo relevante: métodos de localización de raíces de polinomios, fracciones parciales, etc...
Lógica*: Para lic. en física y matemáticas se verá bastante duro este punto y posiblemente sea algo completamente nuevo para muchos. No queda de otra más que tomar 3 o más libros de lógica o elementos de matemáticas de tu biblioteca. Te deben quedar claro los métodos de demostración y la lógica proposicional.
*Tal vez pueda omitirse para estudiantes de ingeniería.
Programación: No le temas. Desde el primer semestre notarás que tus compañeros que vienen de escuelas técnicas te llevarán ventaja en este punto. Algunos habrán comenzado a programar en C, Basic o Java desde la secundaria. No importa, bastan pocas semanas para alcanzarlos. Aún si eres tu el estudiante que llevó algún curso de programación no debes confiarte. Consigue Dev-C++ en este instante y empieza a repasar o a aprender. ¿Cómo empezar? Consigue todo el material que puedas en tu biblioteca. Si tienes un amigo que sepa programar muy bien, pídele ayuda.
Arduino: ¿Vas para electrónica o mecatrónica? Consigue un Arduino en tiendas de componentes electrónicos y aprende a programarlo con tutoriales en línea. Sé lo que digo. Incluso si vas para física te servirá para controlar tus propios experimentos, hacer adquisición de datos y computo físico. No hay prisa, yo también empecé haciendo un led parpadear.
Matlab: Debes entender desde un principio que WinPlot y los graficadores en linea son de lo más corriente. Sé que te parecerán más fáciles de usar, pero a la larga el dominar herramientas de software matemático como Matlab te darán muchas ventajas. Este software parece difícil de usar por su ventada de comandos, pero no lo es. Es como manejar un auto standard. Existen muchos tutoriales en español así que consiguelo cuanto antes y comienza a jugar con él.
Puedo asegurarte que estas son todas las bases que necesitas. Tómalos como un estudió extra, paralelo a tus primeras materias. El resto vendrá a su tiempo de acuerdo a tu programa de estudios. Quizá podría agregar para los estudiantes de electrónica/ mecatrónica/ ing. eléctrica comprar y leer Fundamentos de Circuitos Eléctricos de Sadiku desde el primer momento que ponen un pie en la universidad. ¿Y que hay de la parte personal y social? Me tomaría una entrada entera... o puedes leer el resto del blog...
sábado, 9 de marzo de 2013
Arquitectura Maya
Algo que le pregunto a los arquitectos de México es: ¿porque no vemos oficinas de gobierno, monumentos y universidades construidos con arquitectura maya o azteca? ¿Porque no retomar este tipo de arquitectura tan imponente en todo el país? Espero esta recopilación de dibujos pueda servir para dar ideas para hoteles, restaurantes o edificios públicos. Pueden encontrar muchas más en éste enlace.
viernes, 1 de marzo de 2013
sábado, 23 de febrero de 2013
Convertidor Binario-BCD con displays en VHDL
Si consultaste Google, seguramente encontraste la función to_bcd()del blog VHDL Guru pero quizá te queden dudas sobre como implementarla en un código completo (Si, también tuve el mismo problema). Bien, en el caso del compilador ISE de Xilinx (se observará que estoy usando una tarjeta Basys 2) debe agregarse un archivo de paquete que incluya esta función. Esto puede hacerse usando la plantilla VHDL Package o creando simplemente un nuevo archivo .vhd en blanco y agregarlo al proyecto (El compilador detectará automáticamente que es un paquete al terminar de escribir el código).
El siguiente código es la correcta implementación del Paquete y Cuerpo de Paquete de manera que la función pueda ser utilizada en nuestro programa:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
package bcd is
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector;
end bcd;
package body bcd is
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable i : integer:=0;
variable bcd : std_logic_vector(11 downto 0) := (others => '0');
variable bint : std_logic_vector(7 downto 0) := bin;
begin
for i in 0 to 7 loop
bcd(11 downto 1) := bcd(10 downto 0);
bcd(0) := bint(7);
bint(7 downto 1) := bint(6 downto 0);
bint(0) :='0';
if(i < 7 and bcd(3 downto 0) > "0100") then
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 7 and bcd(7 downto 4) > "0100") then
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
if(i < 7 and bcd(11 downto 8) > "0100") then
bcd(11 downto 8) := bcd(11 downto 8) + "0011";
end if;
end loop;
return bcd;
end to_bcd;
end bcd;
Al guardar el código agregado al proyecto, la función se agregará automáticamente a la librería "work". De manera que habrá que usarla en nuestro programa:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.bcd.all; -- Aquí está nuestra función
entity display is
port ( salida : out std_logic_vector(7 downto 0);
selector: out std_logic_vector(3 downto 0);
binario : in std_logic_vector(7 downto 0);
clk : in std_logic );
end entity;
architecture mostrar of display is
signal a: std_logic_vector(1 downto 0) :=(others => '0');
signal PULSO: STD_LOGIC:='0';
constant SESENTA: integer :=99999;
signal RET: integer range 0 to SESENTA:=0;
signal BCD_out: std_logic_vector(11 downto 0);
signal bcd: std_logic_vector(3 downto 0);
begin
RETARDO: PROCESS(CLK) -- Divisor de frecuencia (de 50MHz a 50Hz)
BEGIN
IF (RISING_EDGE(CLK)) THEN
PULSO<='0';
RET<=RET+1;
IF RET=SESENTA THEN
RET<=0;
PULSO<='1';
END IF;
END IF;
END PROCESS;
process(pulso) begin -- Contador para selectores
if (pulso'event and pulso = '1') then
a <= a + 1;
end if;
end process;
BCD_out <= to_bcd(binario); -- Llamado a la función to_bcd
process (bcd) -- Decodificador BCD a 7 segmentos
begin
case bcd is
when "0000"=> salida <="00000011"; -- '0'
when "0001"=> salida <="10011111"; -- '1'
when "0010"=> salida <="00100101"; -- '2'
when "0011"=> salida <="00001101"; -- '3'
when "0100"=> salida <="10011001"; -- '4'
when "0101"=> salida <="01001001"; -- '5'
when "0110"=> salida <="01000001"; -- '6'
when "0111"=> salida <="00011111"; -- '7'
when "1000"=> salida <="00000001"; -- '8'
when "1001"=> salida <="00001001"; -- '9'
when others=> salida <="11111111"; -- 'x'
end case;
end process;
process (a) begin -- Ciclo de selectores
case a is
when "00" => bcd <= BCD_out(3 downto 0);
selector <= "0111";
when "01" => bcd <= BCD_out(7 downto 4);
selector <= "1011";
when "10" => bcd <= BCD_out(11 downto 8);
selector <= "1101";
when others => bcd <= "0000";
selector <= "1111";
end case;
end process;
end architecture;
miércoles, 13 de febrero de 2013
sábado, 2 de febrero de 2013
¿Cómo funciona el control PID?
Brian Douglas explica el funcionamiento del control PID como pocos profesores en la materia. Si no tienes problemas con el inglés, estas apunto de resumir tu curso entero de control en unos pocos minutos.
viernes, 1 de febrero de 2013
lunes, 28 de enero de 2013
St. George
Tengo una bandera de Inglaterra colgada justo arriba de la cabecera de mi cama. Si, la bandera de Saint George. La razón por la cual conseguí esta bandera y no la de Reino Unido es por los 4 espacios blancos. De otra manera la tinta negra de las firmas de mis amigos no tendrían tan buen contraste. A diferencia de muchos de mis compañeros de mi estancia en las islas británicas, les pedí a todos ellos escribir en sus lenguas maternas. Cada vez que siento que mi mundo se cae miro esa pared y recuerdo el inmenso tamaño de la Tierra. Veo entonces en un sólo cuadro las historias de la gente de todas las esquinas del mundo, separadas por la distancia pero envueltas en la misma lidia eterna con la vida. No, aunque hemos llegado a pensarlo muchas veces, nunca hemos estado realmente solos.
martes, 22 de enero de 2013
Des livres
¿Importan los autores que lea una persona a la hora de juzgarla? No, realmente. Cada quien es libre de elegir que quiere leer. Aquellos que critican a autores mainstream como Stephenie Meyer pasan por alto los cientos de miles de jóvenes que tomaron un libro por voluntad propia, quizá, por primera vez en su vida. ¿Importa el número de libros leídos en este mismo juicio? Por supuesto. Al contrario de la opinión de algunos, especialmente aquellos a los que la lectura les un placer fundamental, es un factor importante. No puedo evitar apreciar la objetividad de los números. Para explicarme mejor considera el tiempo como otra variable importante porque todas las ideas, palabras, conversaciones, tragedias, aventuras y personas con las que vamos a cruzarnos durante nuestra vida, están representadas por un número finito. El punto aquí es la posibilidad de maximizar el flujo de ideas sin limitarse a la época, el idioma o las naciones.
miércoles, 16 de enero de 2013
Generador de pulsos de 1Hz en VHDL (pulso por segundo)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity segundo is
port ( pulso : inout std_logic:='0';
clk : in std_logic);
end entity;
architecture divisor of segundo is
signal count : integer :=1;
begin
process(clk) begin
if(clk'event and clk='1') then
count <=count+1;
if(count = 50000000) then --count = frec de reloj/frec deseada
PULSO <= not PULSO;
count <=1;
end if;
end if;
end process;
end architecture;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity segundo is
port ( pulso : inout std_logic:='0';
clk : in std_logic);
end entity;
architecture divisor of segundo is
signal count : integer :=1;
begin
process(clk) begin
if(clk'event and clk='1') then
count <=count+1;
if(count = 50000000) then --count = frec de reloj/frec deseada
PULSO <= not PULSO;
count <=1;
end if;
end if;
end process;
end architecture;
Nota: Variando el valor de count, se puede utilizar el componente como divisor de frecuencia y obtener cualquier frecuencia menor a la del reloj que se esté usando.
sábado, 12 de enero de 2013
Suscribirse a:
Entradas (Atom)