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

jueves, 20 de agosto de 2020

Instalación de VCS + PlatformIO en Debian/Ubuntu

Estoy aprendiendo a usar la familia de microcontroladores STM32 y ha sido todo un mundo nuevo para mi. Hay bastante información pero me ha parecido algo dispersa (seguramente eso cambiará en el futuro). Quiero hacer una aportación con una nota sobre el setup del entorno de desarrollo multiplataforma PlatformIO que en entradas futuras usaremos para programar un STM32F103C8T6 (Blue Pill).

1. Instalar VSC

Lo primero que hay que hacer es instalar Visual Studio Code. Descarguen el fichero .deb desde aquí e instalen desde el mismo directorio donde está el instalador con:

$ sudo apt install ./<file>.deb

2. Instalar el complemento PlatformIO IDE

Una vez instalado VSC, ábranlo y muévanse a la pestaña de extensiones con Cntrl+Shilf+x o dando click en la pestaña:


Den click en instalar en la opción correspondiente y esperen a que termine.

3. Instalar reglas udev 

Debemos movernos ahora al directorio /etc/udev/rules.d y descargar el archivo con las reglas necesarias con la siguiente serie de comandos:

$ curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules

Después de hacer esto deben reiniciar su computadora. Si no instalan estas reglas les dará el error: Error: libusb_open() failed with LIBUSB_ERROR_ACCESS al intentar cargar un programa a su dispositivo.  

En principio es todo. PlatformIO instalará automáticamente los drivers y bibliotecas necesarias sobre la marcha. Es una maravilla.  


viernes, 26 de junio de 2020

Renombrar archivos automaticamente en Linux

El comando rename permite renombrar archivos utilizando la versatilidad de las expresiones regulares de perl. Recomiendo hacer un respaldo de la carpeta con los archivos a renombrar porque los errores de renombramiento pueden ser difíciles de revertir. Pueden utilizar el argumento '-n' o crear una nueva carpeta con las copias de algunos archivos para practicar primero.

Las expresiones de sustitución tiene la forma general:

's/PATRON/REMPLAZO/'modificador

dónde algunos de los modificadores más usados son:
  • i :  Patrón insensible a las mayúsculas.
  • x : Permitir uso de espacios para mayor claridad.
  • g : Remplaza todas las ocurrencias del patrón.

Cuando estaba haciendo mi tesis de licenciatura ocurrió que generé desde Linux cientos de archivos con la hora en el nombre dejando el simbolo ':' como separador. En Linux no es un problema pero en Windows se vuelven inaccesibles. No iba renombrar manualmente esos cientos de archivos, por supuesto. Tomaré este caso como primer ejemplo. Supongamos que tenemos montones de archivos con esta forma:

datos_10:34:01.txt 

Lo que necesitamos hacer es sustituir todas las ocurrencias de ':' por '_'. Por lo tanto el comando para renombrar es:

$ rename -v -- 's/\:/\_/'g *.txt

Notese que si no colocamos el modificador 'g' al final de la expresión entonces solo se sustituirá la primera ocurrencia del patrón e ignorará a las posteriores. Los caracteres ':' y '_' pueden ir sin la barra '\' pero es buena costumbre colocar la barra para distinguir los caracteres del patrón con los operadores de las expresiones regulares.

La expresiones regulares son lo que necesitamos para realizar renombramientos más complejos. Si nunca habían escuchado ese concepto recomiendo ver este video. En pocas palabras es un sub-lenguaje de descripción de patrones de cadenas de símbolos. He aquí una referencia rápida:

.        : carácter único.
\s      : espacio en blanco.
\S     : carácter diferente a espacio en blanco.
\d     : dígito (0-9).
\D     : no-dígito.
\w     : caracter de palabra (a-z, A-Z, 0-9,_)
\W     : no caracter de palabra
[aeiou] : Identifica sólo un carácter del conjunto entre bracetes.
[^aeiou] : Identifica sólo un caracter fuera del conjunto entre bracetes.
(foo|bar|baz) : operador or. Identifica cualquiera de las expresiones dadas.
^   : principio de cadena.
$   : final de cadena.

Cuantificadores
*         : cero o más apariciones de la expresión o símbolo previo.
+        : una o mas apariciones de la expresión o símbolo previo.
{5}    : 5 o más apariciones...
{3,7} : entre 3 y 7 apariciones.
{6,}    : 6 o más apariciones.

 Aprender a escribir expresiones regulares complejas requiere de práctica. Al principio puede ser frustrante pero después de muchos ejercicios se entiende la idea general.

El ejemplo final de esta nota será una demostración del uso de variables. Supongamos que tenemos un directorio con miles de archivos con nombres con la siguiente estructura:

resultados_Rodolfo_Escobar.txt

y se quiere modificar a la forma:

Escobar_Rodolfo_resultados.txt

De nuevo, nadie quiere pasar por la pesadilla de renombrar los archivos a mano. Para crear una expresión de sustitución debemos tener claro el patrón que necesitamos. Tenemos 3 campos separados por _'s. No podemos saber de antemano cuantas letras tendrá cada campo pero si sabemos que contendrán caracteres de palabra, así que debemos describir el patrón como (\w+)_(\w+)_(\w+). Los paréntesis permiten manejar subpatrones de cadenas. Para reutilizar estos supatrones (moverlos de lugar), podemos manejarlos como $n dónde n es el orden en el que aparecen de izquierda a derecha. El comando completo es:

$ rename -v -- 's/(\w+)_(\w+)_(\w+)/$3_$2_$1/' *.txt



sábado, 21 de septiembre de 2019

Instalar OpenCV-Python con SIFT y SURF habilitados

Quiero ahorrarles algunas horas y frustración con esto. Estas notas están hechas para Linux (uso Debian) pero posiblemente funcione también en Windows (no lo garantizo). Voy asumir que ya tienen instalado Anaconda... Primero tienen que crear un nuevo entorno virtual (esto es por seguridad y no dañar su entorno principal de Python por si algo malo ocurre). Para crear un nuevo entorno:

$ conda create --name mi_entorno_OpenCV -y

Pueden nombrar su entrono como quieran pero es buena idea ponerle un nombre que haga referencia a su modulo. Si trabajan con IA seguramente necesitarán un nuevo para Tensorflow. Ahora, si es la primera vez que crean un entorno virtual tendrán que configurar su terminal para permitir que conda administre los entornos virtuales:

$ conda init bash

Si no usan bash debe poner la shell que utilicen. Bien, una vez que hayan hecho esto pueden activar su entorno con:

$ conda activate mi_entorno_OpenCV

Notarán que habra cambiado la etiqueta antes del promp y deberá aparecer el nombre de su entorno. Deberán instalar ahora matplotlib (su nuevo entorno solo tendrá numpy y scipy [si no, deberán instalarlos también]):

$ conda install -c conda-forge matplotlib

Spyder tampoco estará instalado en su nuevo entorno así que deberan instalarlo también:

$ conda install -c anaconda spyder

Recomiendo leer Managing enviroments de la documentación de conda. Ahora si, para instalar una versión de OpenCV que permita utilizar los algoritmos SIFT y SURF deberán instalar específicamente esta:

$ pip install opencv-contrib-python==3.4.2.16 

Listo. Terminada la instalación pueden hacer una prueba con los códigos de ejemplo de la documentación de OpenCV. Recuerden que deben mandar a llamar a Spyder desde la terminal con el entorno virtual que crearon para OpenCV. para salir del entorno utilicen:

$ conda deactivate

 En la próxima entrada pondré un ejemplo utilizando el algoritmo SIFT.

lunes, 15 de julio de 2019

Gráficas de Maplotlib en Tkinter

He estado aprendiendo usar el módulo TKinter para hacer interfaces gráficas en Python y me está encantando. A pesar de no tener un asistente gráfico como pyQT, se me ha hecho bastante fácil de usar. Para incrustar gráficos de Matplotlib en un GUI de Tkinter pongo el siguiente ejemplo en donde cada botón manda a graficar una función diferente:

  

viernes, 7 de junio de 2019

Generar imagenes PNG de ecuaciones en LaTeX

El archivo que pueden usar como plantilla es el siguiente:

Para poder generar el PNG deben colocar --shell-escape como opciones para el compilador. En Texmaker/TeXstudio pueden hacerlo yendo a Opciones->Configurar Texmaker/TeXstudio:
Yo utilicé esta función para hacer en Gimp stickers matemáticos impresos en papel couché adhesivo:

Nota: Si usas Windows es un poco más complicado: LaTeX to PNG on Windows.

martes, 7 de mayo de 2019

Mecanografía y terminal

El primer paso que debe darse para el dominio natural de la terminal de Linux es tener la habilidad de escribir rápido en el teclado sin mirarlo. Creo que el no ser capaz de hacerlo es el impedimento más grande para enamorase de la terminal y de los editores de texto de consola como Vim o EMACS. La imagen que he puesto en esta entrada es una modificación que hice en GIMP de la asignación de teclas para cada dedo en un teclado latinoamericano. La posición de las manos debe ser la siguiente:
Tomar cursos de mecanografía es recomendable, pero es posible aprender por cuenta propia únicamente practicando con las imágenes anteriores. Pueden intentar con este ejercicio en un bloc de notas o editor de texto sencillo como calentamiento:

mop map mop map mop map
mop map mop map mop map
mop map mop map mop map
 ...
dec sec dec sec dec sec dec 
dec sec dec sec dec sec dec
dec sec dec sec dec sec dec 

 Deben mantener la vista fija en la pantalla sin voltear hacia los dedos y respetando la asignación de teclas de cada dedo. Si nunca lo han hecho antes será bastante difícil. Notarán que una de las cosas más difíciles es retomar la misma posición después de borrar o después de cada nueva linea (enter). Lo importante es tener mucha paciencia hacerlo muy muy lento al principio. Los resultados los verán poco a poco y les aseguro que valdrán la pena, en especial si siempre han querido escribir como hackers en frente de una terminal.

Una buena herramienta de práctica la pueden encontrar en esta página:


Insisto, no se fijen en los errores ni en las palabras por minuto de sus primeras prácticas. Comiencen lento. Tal vez pasen días antes de sentirse fluidos. La cosas en nunca dejar de practicar. 

lunes, 25 de marzo de 2019

Gráfica de lecturas de un DHT11 en Python

Esta nota corta será para no olvidar como hacer una gráfica en Python de un conjunto de mediciones de temperatura a lo largo del tiempo. El sensor utilizado en un DHT11 (que muy tardé me di cuenta que tenía muy baja resolución y que es mejor el DHT22). Generé un archivo de texto a partir de comunicación serial entre un PIC y una Raspberry Pi dónde cada linea tiene la siguiente estructura:

2019-03-22 23:11:33,22,46
fecha, temperatura, humedad relativa 

Algo muy útilil que aprendí a hacer es trasferir archivos entre un host local y la Raspberry a través de la red con un solo comando de consola. El comando es scp y su sintaxis es la siguiente para copiar del host local a la Raspberry :

$ scp /un/dir/local/archivo usuario@ipremota:/un/dir/remoto/archivo

Y de la Raspberri al host local:

$ scp usuario@ipremota:/un/dir/remoto/archivo /un/dir/local/archivo

Ya con el archivo en mi computadora, utilicé el módulo Pandas para leer el archivo .txt dónde registre cerca de dos dias y medio de datos de temperatura y humedad relativa. Aplique un filtro de mediana con el modulo scipy.signal para quitar los picos abruptos en los datos. Finalmente realice los ajustes necesarios para mostrar únicamente la hora en el eje x. El programa completo es el siguiente:

Gráfica:

miércoles, 12 de septiembre de 2018

Instalar MPLAB X en Debian 9 (64 bits)

Primero deben activar el soporte multi-arquitectura agregando la arquitectura i386

 $ sudo dpkg --add-architecture i386 

Luego instalar librerias de compatibilidad para i386:

$ sudo apt-get update 
$ sudo apt-get upgrade
$ sudo apt-get install libc6:i386 libx11-6:i386 libxext6:i386 libstdc++6:i386 libexpat1:i386 

Finalmente se ejecuta el instalador descargado de aquí:

$ sudo ./MPLABX-v5.05-linux-installer.sh

Si la instalación se realiza correctamente podemos iniciar MPLAB X buscándolo en las aplicaciones:


NOTA: Deben tener ya instalado Java Runtime Enviroment en su sistema. Aquí hay una guía de instalación en español.

jueves, 13 de julio de 2017

Ejemplo de programación multithread en Python

Como anexo a la entrada anterior, pongo un ejemplo del mismo programa pero en Python utilizando el módulo threadings. En este programa hago un cambio importante, estoy utilizando un producto punto del módulo numpy, una operación que está optimizada y escrita en C lo que me da tiempos de ejecución menores que los del programa anterior [Ref]:

Ejecutamos y medimos el tiempo de ejecución con:

time (python MatMulThreads.py)

Estos fueron los tiempos de ejecución en una Raspberry Pi 3 para matrices de 2000x2000:

Debe tomarse en cuenta que a pesar de que ambos programas son semanticamente iguales, su implementación no lo es. Es de notarse que en este caso no hay tanta mejoría entre 2 y 4 threads.

miércoles, 12 de julio de 2017

Programación multithread en C (pthread.h)

Un thread o hilo de ejecución es el subconjunto mínimo de instrucciones dentro de un programa que pueden ser ejecutadas secuencialmente [existe el caso particular en el que un solo hilo de ejecución representa al programa entero]. Este subconjunto de instrucciones viene asociado con los registros y locaciones de memoria que son usados durante su ejecución. Si un programa está divido en varios hilos de ejecución, cada uno de ellos puede ejecutarse de forma concurrente (o de forma paralela si se cuenta con múltiples procesadores). Es importante tener claros los conceptos de proceso e hilo de ejecución cuando se va hacer programación paralela. Recomiendo ver los videos sobre hilos de ejecución y gestión de procesos de la UCAM dónde resumen muy bien los temas en menos de 10 minutos (español). De manera conceptual, podemos representar la relación entre los hilos de ejecución (threads) y un proceso de la siguiente manera:
Se conoce como Pthreads o POSIX threads a un modelo de ejecución estandar (independiente del lenguaje de programación) para sistemas Unix. Esta definido como un conjunto de rutinas y tipos en C implementados en el header: pthread.h.

Si un programa en C/C++ no crea nuevos hilos explícitamente, será ejecutado como un proceso de hilo único. Para la crear un nuevo thread con la librería pthreads utilizamos la función pthread_create:

int pthread_create(thread_ID,att,rutina_concurrente,argumento) 

thread_ID: apuntador al identificador de hilo (tipo pthread_t)
att: apuntador a la estructura que contiene los atributos del hilo. NULL para atributos por defecto.
rutina_concurrente: puntero a la función que contiene la rutina que va a ejecutar el hilo.
argumento: argumento opcional a pasar hacia rutina_concurrente (tipo void*). NULL si ninguno es requerido.

Pueden encontrar una descripción más detalla del resto de las funciones de la librería aquí.

Ejemplo: Multiplicación matricial 

En esta entrada quiero hacer énfasis en la creación de hilos y ejecución. Como ejemplo de esto, probaremos un programa que realice una multiplicación de matrices cuadradas de forma paralela. Consideremos el algoritmo general para la multiplicación de matrices:
 Una forma de paralelizar el producto matricial es dividir las operaciones entre filas y columnas entre los hilos (no es la forma más eficiente pero será muy útil para aprender a dividir un programa en hilos independientes). El número total de productos punto entre n filas y  m columnas es igual a n*m. Si usamos matrices de 16x16, el total de operaciones entre filas y columnas sería de 256. Si dividimos estas operaciones en partes iguales entre 4 hilos de ejecución, cada hilo llevará a cabo 64 operaciones. Podemos hacer esto dividiendo las filas de la matriz A a lo largo del índice 'i'. Un ejemplo para matrices 8x8 repartido en dos hilos:
Cada hilo en este caso realiza 8 operaciones de dot(fila,columna) del total de 16. Con 4 hilos, cada uno accedería a una única fila de la matriz A realizado 4 operaciones. La rutina que pasaremos como argumento a la función pthread_create() es la siguiente:

void *matmul(void* id_arg){
  int i,j,k;
  long  id = (long) id_arg;
  int rows_per_thr = col/num_of_threads;
  int start_index = id*rows_per_thr;
  int final_index = (id+1)*rows_per_thr;

  for(i=start_index;i
< final_index;i++){
   for(j=0;j
< col;j++){
    for(k=0;k
< row;k++){
      C[i][j] += A[i][k]*B[k][j]; 

    }
   }
  }
}


Todos los hilos ejecutarán exactamente la misma rutina pero los datos a los que accederán (elementos de 'A','B' y 'C') dependieran del identificador de cada hilo. Ya que los hilos tienen acceso a la memoria compartida del proceso principal podrán leer directamente las locaciones de memoria de las variables globales del programa. Sólo un identificador de hilo será pasado como argumento para la rutina paralela. La creación de threads se hace dentro de main() de la siguiente manera:

  pthread_t tid[num_of_threads];
  long rank;

  //Creación de threads
  for (rank = 0; rank < num_of_threads; rank++)
     pthread_create(&tid[rank], NULL,matmul , (void*) rank);


En este punto del código los hilos comienzan a ejecutar independiente la rutina que se les ha asignado. Sin embargo aquí hay un problema: el programa principal continuara con su ejecución sin esperar a que los hilos terminen sus tareas. Para resolver esto es necesario indicarle explícitamente al programa principal esperar a cada uno de los hilos con la función pthread_join():

  //Unión de threads
  for (rank = 0; rank < num_of_threads; rank++)
      pthread_join(tid[rank], NULL);


Nota: en este ejemplo se considera que la mayoría de las implementaciones de Pthreads los hilos tienen el atributo de joinable por defecto. Para mayor portabilidad se recomienda activar este atributo explícitamente. Pueden encontrar un ejemplo de esto aquí.

Para simplificar el código, las matrices serán leídas en nuestro programa desde un archivo de texto. Creamos este archivo con dos matrices de enteros aleatorios (y una matriz de resultado para verificar la salida del programa en C) con el siguiente código en Python:

import numpy as np
n= 16
A = np.random.randint(0,9,size = (n,n))
B = np.random.randint(0,9,size = (n,n))
C = np.matmul(A,B)
namein = "matext"+str(n)+"x"+str(n)+".txt"
nameres = "resultado"+str(n)+"x"+str(n)+".txt"
np.savetxt(namein,np.concatenate((A,B),0),fmt = "%d",delimiter = " ")
np.savetxt(nameres,C,fmt="%d",delimiter= " ")

El código completo en C es el siguiente:

Compilamos y ejecutamos desde terminal con:

 gcc MatMulThreads.c -lpthread ; ./a.out | less 

Para verificar la reducción en el tiempo de ejecución, corrí el programa en una Raspbery Pi 3 que tiene un quad-core ARM Cortex-A53. Generé dos matrices de 1000x1000 y estos fueron los resultados variando el número de threads:
Este programa tiene varias limitaciones, una de ellas es que sólo admite números pares de hilos. Se deja como ejercicio modificarlo para cualquier número de hilos.  

Bien, hasta aquí se han cubierto los aspectos de creación y unión de threads. Existen aún varios temas importantes más como la sincronización de hilos, especialmente en los accesos de memoria (en el ejemplo de la multiplicaciones de matrices no existen conflictos de memoria ya que cada hilo trabaja con una parte diferente de los arreglos). Estos temas son tratados de forma consista en este artículo y en estas diapositivas de la Universidad de Buenos Aires. 

[Escribí el mismo ejemplo de esta entrada en Python utilizando el módulo threading. Pueden revisarlo aquí.]

Referencias
POSIX Threads Programming, Blaise Barney, Lawrence Livermore National Laboratory

martes, 4 de julio de 2017

Instalación de GNU Scientific Library (Debian)

GNU Scientific Library (GSL) es una librería numérica para C/C++, al parecer, poco conocida fuera del ámbito académico especializado. Tiene un repertorio de rutinas comparable con el popular módulo SciPy para Python. Encuentro muy útil GSL para sistemas con Linux embebido en robótica o IoT, especialmente en aplicaciones que requieran la operación de estos sistemas de tiempo real. Recomendaría echarle un vistazo si trabajan en proyectos serios con Raspberry Pi's o UDO's que requieran cálculos numéricos avanzados. Su documentación está bien estructurada y es muy amigable. El único inconveniente es que no hay muchos ejemplos y ayuda ahí afuera (ni siquiera en Stack Overflow) así que habrá que leer cuidadosamente el manual de referencia.

Para instalar GSL en Debian y derivados:

sudo apt-get install libgsl0ldbl libgsl0-dev 

Probaremos la instalación con el siguiente ejemplo con operaciones de números complejos (revisar documentación):

#include <stdio.h>
#include 
<gsl/gsl_complex.h>
#include 
<gsl/gsl_complex_math.h>

int main (void){
 
  //Declaración de variables complejas
  gsl_complex z,w,u;
 
  //Asignación de valores
  GSL_SET_COMPLEX(&z,3,4);  //z = 3+4i
  GSL_SET_COMPLEX(&w,4,5);  //w = 4+5i

  //ejemplos de operaciones
  u = gsl_complex_add(z,w);
  printf("z + w = %2.f + i%.2f\n",u.dat[0],u.dat[1]);
  u = gsl_complex_mul(z,w);
  printf("z*w = %.2f + i%.2f\n",u.dat[0],u.dat[1]);
  u = gsl_complex_log(z);
  printf("log(z) = %.2f + i%.2f\n",u.dat[0],u.dat[1]);
  u = gsl_complex_exp(gsl_complex_add(z,w));
  printf("exp(z+w) = %.2f + i%.2f\n",u.dat[0],u.dat[1]);
  return 0;
}


Compilamos y ejecutamos desde terminal con:

gcc GSL_Complex_demo.c -lgsl -lgslcblas ; ./a.out

viernes, 6 de enero de 2017

Muestras I/Q: Un ejemplo con GNU Radio

En la entrada anterior resumía todo lo relevante sobre las señales analíticas (I/Q). Esta vez haremos un ejemplo que nos ayudará a visualizarlas mejor y hacernos de una intuición sobre su naturaleza. El ejemplo consiste en obtener las componentes I/Q de la siguiente señal:
Al ser una señal real, esperamos que tenga un espectro simétrico tal como podemos observar en el sink de frecuencia:
Para obtener las componentes I/Q de esta señal requerimos implementar un modulador en cuadratura con un filtro pasabajas para cada componente y posteriormente usar un bloque de conversión Float to Complex. No hará falta agregar simular un ADC ya que la señal generada ya es discreta. Si aún no están familiarizados con GNU Radio tengo un entrada introductoria [Asumo también cierto conocimiento en filtros digitales, aunque los bloques de estos son fáciles de usar y pueden consultar su documentación aquí] y tampoco estará de más tener muy claro el concepto de frecuencia en tiempo discreto. El flowgraph nos queda de la siguiente manera:
Click para agrandar
He agregado un slider gráfico que nos permite cambiar de forma interactiva la frecuencia de los generadores de señal que representan al oscilador local en cuadratura. Esto me parece un recurso didáctico muy bueno porque ayuda visualizar la relación que existe entre la frecuencia del oscilador local y la frecuencia que vemos en el centro (0 Hz) del espectro de la señal analítica. Basta asignar una frecuencia de 14.5 KHz para sintonizar a la componente de esa misma frecuencia que existe en nuestra señal de prueba:

martes, 22 de marzo de 2016

Configuración inicial en Debian

[Esta entrada es sólo un apunte personal para recordarme lo que debo de hacer depués de instalar Debian para configurarlo a mi gusto.]

1. Instalación y configuración de WiFi:

https://wiki.debian.org/es/WiFi

2. Configuración de GNOME:
Escribir "Retoques" o "Tweak" en el buscador de aplicaciones. Abrimos la aplicación para configurar GNOME. En la pestaña de "Ventanas" podemos agregar los botones de maximizar y minimizar

3. Instalación de códecs multimedia
apt-get install libavcodec-extra 
4. Habilitación de sudo

En  Debian no vienen configurados sudoers por defecto pero pueden encontrar un tutorial para instalarlos aquí.

5. Instalación fuentes de Windows

apt-get install ttf-mscorefonts-installer

6. Instalación de Cairo Dock
Para instalar el dock solo tenemos que abrir Synaptic y escribir "Cairo Dock" en el buscador. Instalamos doble click en el paquete y seguimos el procedimiento de instalación dando click en "Aplicar". Una vez instalado, presionamos Alt+F2 y escribimos "cairo dock" para iniciarlo. Después abrimos la aplicación de retoques como (el mismo del punto 2) y abrimos la pestaña "Aplicaciones al inicio". Damos click en el signo "+" y damos click en Cairo Dock. De esta manera el dock se iniciara automáticamente al iniciar sesión.


sábado, 20 de febrero de 2016

OpenCV en Python

Instalación de Anaconda en Linux:

Descargar instalador aquí y ejecutar con:

$ bash nombredelinstallador.sh

Instalación de OpenCV usando conda (en la terminal):

$ conda install opencv 

Abrir Spyder:

$ spyder

Ejemplo. Cargar una imagen y mostrarla con matplotlib:

import cv2 
from matplotlib import pyplot as plt 

img = cv2.imread('eco.jpg',0) #Cargar imagen 
plt.imshow(img,cmap = 'gray') # Mostrar imagen 
plt.xticks([]), plt.yticks([]) #Ocultar numeración en ejes 
plt.title('Umberto Eco (1932-2016)') 


lunes, 28 de septiembre de 2015

Interrupciones externas en Raspberry Pi con Python

A partir de la versión 0.5.6 de la librería RPi.GPIO es posible utilizar rutinas de interrupción externas. Como los usuarios de microcontroladores experimentados deben saber, una rutina de interrupción permite ejecutar una o una serie de instrucciones sin perder tiempo en bucles de lectura. Es decir que si el procesador se encuentra ejecutando una tarea, éste pausará el proceso en curso y ejecutará la rutina de interrupción ante un flanco de subida o bajada ocurrido en un pin GPIO. Si no has comprado tu Raspberry recientemente y no has actualizado su software es recomendable hacerlo:

sudo apt-get update 

sudo apt-get upgrade #(Esto podría tardar hasta más de una hora)

El siguiente código es un ejemplo sencillo sobre el uso de interrupciones. Tenemos dos rutinas de interrupción CuentaA() y CuentaB() asociadas a GPIO23 y GPIO24 respectivamente. Cada una incrementan una variable de conteo y muestran el resultado en consola. El programa se detiene cuando el contador A es mayor o igual a 5. Para más detalles sobre interrupciones pueden revisar la documentación de la librería RPi.GPIO. Para evitar el el efecto de rebote se utilizan capacitores de entre 22 o 10 uF conectados en paralelo con las resistencias pulldown de 10K como se muestra en el circuito [aunque también puede utilizarse un debounce vía software agregando el argumento bouncetime=200 a la función add_event_detect()]:
import RPi.GPIO as GPIO
import os

contaA = 0
contaB = 0

#Setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.IN)
GPIO.setup(24,GPIO.IN)

#Callbacks
def CuentaA(channel):
    global contaA
    contaA += 1
    os.system("clear")
    print "Contador A: ", contaA
    print "Contador B: ", contaB

def CuentaB(channel):
    global contaB
    contaB += 1
    os.system("clear")
    print "Contador A: ", contaA
    print "Contador B: ", contaB

#Interrupciones
GPIO.add_event_detect(23, GPIO.RISING, callback = CuentaA)
GPIO.add_event_detect(24, GPIO.RISING, callback = CuentaB)

print "Contador A: ", contaA
print "Contador B: ", contaB

#Bucle principal
while(contaA < 5):
    pass

GPIO.cleanup()

domingo, 19 de julio de 2015

Comunicación serial con Arduino y Scilab

 Recuerda instalar Serial Communication Toolbox primero con Module Manager.

Programa en Scilab

h=openserial("/dev/ttyACM0","9600,n,8,1"); // *
xpause(1e06); // retardo (aprox. 1 sec)
writeserial(h,char(1)) // envía 1(uint8)
xpause(1e06) // retardo (aprox. 1 sec)
writeserial(h,char(0)) // envía 0 (uint8)
closeserial(h);

* En Windows se debe sustituir "/dev/ttyACM0" por el número (sin comillas) de COM. Por ejemplo, para el COM5 quedaría: h=openserial(5,"9600,n,8,1");

Probamos la comunicación con un programa simple en Arduino dónde el led del puerto 13 encienda enviando un 1 y apagándolo con un 0.

Programa de prueba en Arduino

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT); 
  digitalWrite(13,LOW);  
}

void loop() {
    while (Serial.available() > 0) {
     int lectura = Serial.read();    
     if (lectura == 1){digitalWrite(13,HIGH);}
     else if(lectura == 0){digitalWrite(13,LOW);}   
      
    }    
} 

Como ejercicio, se puede escribir un programa dónde se envíe un valor PWM (0-255) desde Scilab hacía un led conectado a la tarjeta. 

lunes, 13 de julio de 2015

Simulando circuitos con ngspice

Ngspice es un simulador de circuitos gratuito y de código abierto desarrollado por el CAD Group de la Universidad de California, Berkeley. Si ya están familiarizados con otros programas basados en SPICE no debe ser mayor problema aprender a usarlo. Por otro lado, si están acostumbrado a las comodidades de programas como Multisim o Proteus hay algunas cosas que deben saber para empezar. La forma de trabajar con ngspice es la siguiente:
 Es necesario crear un directorio en donde estén guardados los archivos .mod (SPICE models) que contienen los modelos de simulación de los dispositivos electrónicos que van a utilizarse. Estos archivos no están incluidos en la instalación por defecto de ngspice, pero son proveídos por los mismos fabricantes de componentes. Estos modelos deben ser enlazados a los componentes desde gschem.

Instalación en Debian/Ubuntu/Linux Mint:

$ sudo apt-get install ngspice

Para instalar gschem y gnetlist instalamos el paquede gEDA:

$ apt-get update && apt-get install geda pcb gerbv

Abrimos gschem:

$ gschem

, buscamos "añadir componente" en la barra de herramientas (su ícono es una compuerta and) y usamos los siguientes componentes:

SPICE simulation elements > vsin-1.sym
Diodes (generic) > diode-1.sym
Basic devices > resistor.sym
Power rails > gnd-1.sym

La interfaz de gschem es bastante intuitiva. Para girar 90° un componente sólo hay que seleccionarlo y presionar las teclas E y R (una después de la otra). Una vez terminado el circuito se deben configurar los componentes para poder generar un netlist que pueda ser simulado correctamente por ngspice. Dando doble click en el diodo se abrirá una ventana dónde debemos añadir una propiedad value cuyo valor será 1N4001 y damos click en "añadir":
Hacemos lo mismo con la fuente de AC. En este caso, value ya aparecerá en la tabla por lo que solo debemos modificar su valor directamente escribiendo "sin 0 5 60Hz". Para agregar un valor a la resistencia, le damos click derecho a su símbolo y buscamos "añadir propiedad", se abrirá una ventana dónde en "nombre"  escribimos "value" y en "valor" escribimos su resistencia en Ohms (100 para este ejemplo), en la última opción seleccionamos "Mostrar solo valor". Después de esto ahora sólo hace falta enlazar el archivo de modelo de SPICE al símbolo del diodo. Para esto regresamos a "agregar componente" y buscamos SPICE simulation elements > spice-model-1.sym. Para este modelo en particular las propiedades deben ser las siguientes:

Observen que en file he escrito la ruta al archivo de modelo para el diodo 1N4007 (pueden descargar un modelo de ese diodo aquí, cambiando la extensión de .txt a .mod) . Guardamos el esquema con el nombre diodo.sch. El esquema terminado debe verse algo así:

Para generar el netlist escribimos:

$ gnetlist -g spice-sdb -o diodo.net diodo.sch

[NOTA: consultar sintaxis y opciones de gnetlist]

Ejecutamos con ngspice:

$ ngspice diodo.net

Ya dentro de la consola de ngspice escribimos:

tran 100us 100ms #dónde se indica 100us de step simulando de 0 a 100ms
plot v(2)

Se abrirá una ventana con la gráfica del voltaje en la resistencia:


NOTA: Deben tomar siempre en cuenta el nombre del modelo que está declarado dentro del archivo .mod. El modelo del 1N4007 que estoy usando es diferente al que pueden descargar en diodes.com. Si usan ese archivo, deben asigar valores para la propiedad value de DI_1N4007 en vez de 1N4007 (o simplemente cambiar el nombre en el script del modelo). Este es el contenido del archivo de diodes.com, señalo el lugar donde va el nombre del modelo:

*SRC=1N4007;DI_1N4007;Diodes;Si;  1.00kV  1.00A  3.00us   Diodes, Inc. diode
.MODEL DI_1N4007 D  ( IS=76.9p RS=42.0m BV=1.00k IBV=5.00u
+ CJO=26.5p  M=0.333 N=1.45 TT=4.32u )

sábado, 6 de junio de 2015

Escribir y compilar un programa en C con gcc desde terminal

Abrimos una consola, asegurándonos de que estamos en nuestra carpeta personal (puedes hacerlo con el comando pwd) y escribimos:
$ mkdir Programas  # Creamos una nueva carpeta
$ cd Programas       # Nos movemos a la carpeta Programas
~/Programas$ nano ejemplo.c # Creamos nuevo archivo .c
~/Programas$ gcc -o ejemplo ejemplo.c # Compilamos y creamos código objeto con el nombre ejemplo.o
~/Programas$ ./ejemplo # Ejecutamos código objeto

jueves, 18 de diciembre de 2008

The Time is the Enemy

Una semana continua sin usar Windows (Si, ahora uso Ubuntu). Aunque todavía lo tengo en el disco duro. Pero fue un lata dejarlo así, eh. Linux por defecto es feo, hay que decirlo.

Me falta el Trompe Le Monde =(

* * *
El mas bonito mensaje de Navidad que he visto últimamente:


No había ido a la librería Gandhi desde que la abrieron no hace mucho en Plaza Galerias. Tan solo hoy encontre casi todos los libros que siempre he querido leer. Por fin llega algo interesante. Esa plaza no tenía mayor atractivo que la pista de hielo, donde la gente se divierte burlandose y valiendoles madre de las duras caidas que sufren los que, generalmente, patinan obligadamente por sus parejas o hijos. Digo, no sé, a mí tampoco se me hace muy machin que digamos entrar en esa madre. No se si sea solo por apertura pero Dante y Burrel pueden chingar mucho a su madre con la lana que me han clavado. Hasta varios discos y DVD's estan mas baratos en Gandhi que en Mixup.

* * *
Mañana es la "Super peda del 5º A". Algo nice, siendo en Altabrisa. Creo que nos salió carisima considerando que solo hay refrescos y papitas, ah si y los dos barriles de chela que supuestamente van a llevar. La verdad yo o soy muy adepto a tomar, pero de todos modos pagué.

* * *
Me acabé de chutar 100 años de soledad, ahorita empiezo con un Mundo Feliz.