sábado, 12 de abril de 2014
jueves, 27 de marzo de 2014
Comunicación SPI PIC2550 con DAC LTC1660 (MikroC)
// DAC module connections
sbit Chip_Select at RB5_bit;
sbit Chip_Select_Direction at TRISB5_bit;
// End DAC module connections
double t,valor;
void InitMain() {
Chip_Select = 1; // Libera DAC
Chip_Select_Direction = 0; // Pin CS# como salida
SPI1_Init(); // Inicializa modulo SPI
}
void DAC_Output(unsigned int valueDAC) {
char temp;
Chip_Select = 0; // Selecciona chip
//High Byte
temp = (valueDAC >> 6) & 0x0F; // Corrimiento
temp |= 0xF0; // Cargar dato al canal A
SPI1_Write(temp); // Envía parte alta del byte
//Low Byte
temp = valueDAC<< 2;
SPI1_Write(temp); // Envía parte baja del byte
Chip_Select = 1; // Libera chip
}
void main() {
int i = 0;
ADCON1 |= 0x0F; // Desactiva entradas analógicas
CMCON |= 7; // Desactiva comparadores
// Puerto B como salidas
TRISB = 0x00;
PORTB = 0X00;
//
InitMain(); // Secuencia de inicialización
while(1){
for (i=0; i < 80; i++){ // función de prueba
t = t + 0.078;
valor = (unsigned int) floor(512*sin(t)+512);
DAC_Output(valor); // Enviar dato
if (t > 2*3.14) t = 0;
}
}
}
* * *
Para que la salida de la DAC sea bipolar, es decir que tenga un rango de -5 a +5 V, se debe implementar el siguiente circuito:
domingo, 9 de marzo de 2014
Crear un archivo de texto desde un array en Matlab
Supongamos que se requiere generar una señal sinusoidal en un DSP o un FPGA a partir de un conjunto de 30 puntos de la función sin(t) dentro un solo ciclo. Si se programa el dispositivo en lenguaje C, necesitamos un array que contenga los 30 valores. Para transferir el array generado a un archivo.txt del cual se puedan copiar cómodamente (separados ya por una coma) se utiliza la función dlmwrite(). El código para generar los 30 valores en formato short es:
t = linspace(0,2*pi,30);
y = round(32767*sin(t));
dlmwrite('texto.txt',y);
t = linspace(0,2*pi,30);
y = round(32767*sin(t));
dlmwrite('texto.txt',y);
domingo, 23 de febrero de 2014
Beakman
Fue muy emocionante compartir la explanada del museo Universum con al menos 2 millares de estudiantes y jóvenes profesionales de las más diversas ciencias, todos siendo niños otra vez durante poco más de una hora. Después de mis padres, me aventuraría a decir que el personaje de Paul Zaloom terminó de encaminarme por la senda de la ciencia. Creo que soy una de las personas más indicadas para afirmar que tener carisma y una irreverencia agradable es más difícil que aprender matemáticas avanzadas. Pocos divulgadores de la ciencia han podido marcar una generación entera de un país."They always say "you must be really tired of hearing I'm a scientist because of you". But I've got to tell you friends... I will never ever get tired of hearing you people "I'm a scientist because of you"". Contuve algunas lagrimas al cierre.
Etiquetas:
90s,
Anecdotario,
Ciencia,
Divulgación,
UNAM
domingo, 16 de febrero de 2014
Arduino + DAC LTC1661 (comunicación SPI)
Algunos proyectos electrónicos requieren salidas de señales analógicas "ideales" como una señal sinusoidal o una señal de control para determinado proceso en el cual el PWM no es adecuado. Si se quiere utilizar Arduino, ya sea como tarjeta de adquisición de datos o como el cerebro de todo el proceso, es necesario utilizar un DAC o fastidiarse con un arreglo de amplificadores operacionales. Para este ejemplo estoy usando un convertidor integrado de 10-bits y 2 salidas LTC1661 de Linear Technologies. Tal vez no sea el modelo de DAC más común en muchos países pero utiliza el protocolo de comunicación SPI, por lo que el código mostrado puede ser adaptado sin mayor problema a otros modelos.
Lo primero que se debe hacer a la hora de escribir un código de comunicación SPI es revisar la hoja de especificaciones del dispositivo con el que vamos hacer la comunicación y buscar el diagrama de tiempos y la tabla de direcciones. Para el LTC1661 tenemos este diagrama:
Recordemos que aún con la librería SPI.h de Arduino sólo podemos enviar paquetes de 8 bits a la vez. Cuando visualizamos esta secuencia nos damos una buena idea de lo que tenemos que hacer en el código. En este caso habrá que dividir la "palabra" de 16 bits que deseamos enviar en dos paquetes de 8 bits cada uno. Así, la secuencia binaria de un 512 (en binario 1000000000) que se traducirá como la mitad del voltaje de referencia para la salida A es:
y debe ser divido como:
Para esto tomaremos una variable que llamaremos "valor" que representará a un dato de 10 bits como valor de voltaje. Es importante recordar que esta variable se declara como entero sin signo que en Arduino es un dato de 16 bits. Para obtener el primer byte será necesario utilizar una variable de tipo char (que es de 8 bits) que llamaremos "temp" y que igualaremos a la variable "valor" después de hacer un corrimiento de 6 bits a la derecha de manera que el entero sin signo 0000001000000000 se convierta en 0000000000001000 y finalmente en el char 00001000. Para agregar la dirección 1001 habrá que sumar simplemente 1001000 a nuestra variable "temp". Toda esta operación en lenguaje Arduino (y también en C) queda:
temp = (valor >> 6) & 0x0F; // Corrimiento a la derecha
temp = 0x90 + temp; // dirección y parte del dato
Teniendo este numero cargado en "char" queda listo para ser enviado con la fusión SPI.transfer(). Para el segundo byte lo único que falta hacer es aplicar un corrimiento de dos bits a la izquierda e igualar a "temp" y volver a enviar con SPI.transfer():
temp = valor << 2;
Como había escrito al principio, es posible que los dispositivos que estén utilizando trabajen con datos de 8 o 12 bits y no 10 como en este ejemplo. Pero en esos casos lo único que habrá que hacer es ajustar el valor de los corrimientos. Si es la primera vez que conectas un dispositivo SPI a un Arduino es importante que sepas cuales son los pines para este tipo de comunicación.
Código completo:
Lo primero que se debe hacer a la hora de escribir un código de comunicación SPI es revisar la hoja de especificaciones del dispositivo con el que vamos hacer la comunicación y buscar el diagrama de tiempos y la tabla de direcciones. Para el LTC1661 tenemos este diagrama:
Recordemos que aún con la librería SPI.h de Arduino sólo podemos enviar paquetes de 8 bits a la vez. Cuando visualizamos esta secuencia nos damos una buena idea de lo que tenemos que hacer en el código. En este caso habrá que dividir la "palabra" de 16 bits que deseamos enviar en dos paquetes de 8 bits cada uno. Así, la secuencia binaria de un 512 (en binario 1000000000) que se traducirá como la mitad del voltaje de referencia para la salida A es:
1001100000000000
(dirección, dato y bits "don't care")
y debe ser divido como:
10011000 y 00000000
Para esto tomaremos una variable que llamaremos "valor" que representará a un dato de 10 bits como valor de voltaje. Es importante recordar que esta variable se declara como entero sin signo que en Arduino es un dato de 16 bits. Para obtener el primer byte será necesario utilizar una variable de tipo char (que es de 8 bits) que llamaremos "temp" y que igualaremos a la variable "valor" después de hacer un corrimiento de 6 bits a la derecha de manera que el entero sin signo 0000001000000000 se convierta en 0000000000001000 y finalmente en el char 00001000. Para agregar la dirección 1001 habrá que sumar simplemente 1001000 a nuestra variable "temp". Toda esta operación en lenguaje Arduino (y también en C) queda:
temp = (valor >> 6) & 0x0F; // Corrimiento a la derecha
temp = 0x90 + temp; // dirección y parte del dato
Teniendo este numero cargado en "char" queda listo para ser enviado con la fusión SPI.transfer(). Para el segundo byte lo único que falta hacer es aplicar un corrimiento de dos bits a la izquierda e igualar a "temp" y volver a enviar con SPI.transfer():
temp = valor << 2;
Como había escrito al principio, es posible que los dispositivos que estén utilizando trabajen con datos de 8 o 12 bits y no 10 como en este ejemplo. Pero en esos casos lo único que habrá que hacer es ajustar el valor de los corrimientos. Si es la primera vez que conectas un dispositivo SPI a un Arduino es importante que sepas cuales son los pines para este tipo de comunicación.
Código completo:
#include <SPI.h>; #include < math.h>;
Aquí pueden encontrar el código para comunicar un PIC18F2550 con un DAC LTC1660.int ss = 10; float t; unsigned valor = 0; void setup(){ pinMode(ss, OUTPUT); SPI.begin(); } void enviar( unsigned int valor_dac){ char temp; digitalWrite(ss, LOW); // CS o SS en bajo temp = (valor_dac << 6) & 0x0F; // Corrimiento a la derecha temp = 0x90 + temp; // dirección y parte del dato SPI.transfer(temp); // envio del primer byte temp = valor_dac << 2; // Corriemiento a la izquierda SPI.transfer(temp); // envío del segundo byte digitalWrite(ss,HIGH); // CS o SS en alto } void loop(){ for (int i; i < 80; i++){ // función de prueba t = t + 0.078; valor = (unsigned int) 511*sin(t)+511; enviar(valor); delay(1); if (t > 2*3.14) t = 0; } }
lunes, 3 de febrero de 2014
Función promedio para lectura analógica desde PIC (MikroC)
Cómo muchos hemos notado, la conversión A/D en PIC es un tanto ruidosa. El método de promediación no es la solución definitiva al ruido del ADC, pero mejora considerablemente los resultados:
unsigned int promediolectura(void){
int i =0;
unsigned int a = 0;
for (i=0; i <16;i++){a+ = ADC_Read(0);}
a = a >>4;
return a;
}
unsigned int promediolectura(void){
int i =0;
unsigned int a = 0;
for (i=0; i <16;i++){a+ = ADC_Read(0);}
a = a >>4;
return a;
}
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.
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.
Suscribirse a:
Entradas (Atom)





