sábado, 22 de agosto de 2020

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.  


martes, 11 de agosto de 2020

Chan's FatFs en PIC24: Librería para lectura/escritura en memorias SD

FatFs es un módulo de sistema de archivos FAT32/16 para microcontroladores. Está escrito en ANSI C y es altamente portable entre una gran variedad de dispositivos. Si bien su documentación es muy detallada, al ser muy genérica es fácil perderse a la hora de hacer una implementación en un microcontrolador en particular.  En esta entrada trataré de explicar lo mejor posible como portarla a la familia PIC24. Lo primero que hay que entender es como están estructurados sus 5 archivos:

 Los únicos archivos del módulo que hay que editar son diskio.c y ffconf.h. La portabilidad radica en terminar de escribir las siguientes funciones de comunicación SPI:

  • BYTE xchg_spi (BYTE dat)
  • void xmit_spi_multi (const BYTE* buff, UINT cnt)
  • void rcvr_spi_multi (BYTE* buff, UINT cnt )
  • void FCKL_SLOW(void) 
  • void FCKL_FAST(void)

definir los macros:

  • CS_LOW()
  • CS_HIGH()
  • MMC_CD    
  • MMC_WP

y crear una rutina de interrupción por timer de 1 KHz que incrementa una variable de conteo de tiempo: volatile UINT Timer. Esta interrupción sirve para el manejo de timeouts. En los archivos del ejemplo podrán encontrar comentarios detallados sobre el funcionamiento de estas funciones. Pondré un enlace al final.

Para simplificar esta primer versión del programa de ejemplo he desactivado la opción de reloj de tiempo real modificando la linea 237 de ffconf.h: FF_FS_NORTC = 1.  Cuando está opción esta desactivada se requiere crear una función adicional que maneje el tiempo del sistema de archivos (lo haremos en otra entrada usando el módulo RTC del PIC24FJXXGB002).

En esta entrada ya he explicado como configurar el reloj de sistema y en esta otra como configurar el modulo SPI y el Periferial Pin Select.

Configuración de SCK

La primer cosa que hay hacer es estar seguros de que se pueda elegir entre dos frecuencias diferentes para el reloj del módulo SPI. Una baja que se encuentre entre 100 y 400 KHz y una alta que se la de operación (hay limites para esta frecuencia que explicaré más adelante). En la página 23 del documento Section 23. Serial Peripheral Interface encontramos la siguiente información: 

 

Los módulos de la familia PIC24 tienen dos prescalers. En este ejemplo lo que haré será dejar fijo el prescaler primario a 16:1 y alternar con el secundario entre 8:1 para el reloj con FCLK_SLOW() para tener 125 KHz y 2:1 con FCLK_FAST() para tener 500 KHz. Para verificar experimentalmente que la frecuencia sea correcta pueden usar el modo de disparo único de un osciloscopio (aquí hay un tutorial para configurar ese modo). Buena parte de las fallas con la implementación de la librería FatFs tienen que ver con una frecuencia baja incorrecta.

Conexión con el modulo SD

La segunda falla de implementación más común tiene que ver con la conexión física con los módulos SD. He visto en varios foros, y también me pasó, que los dispositivos de 3.3 V fallan con algunos módulos microSD de este tipo pero que funcionan perfectamente cuando construyen sus propios circuitos de conexión a la memoria SD. En mi caso sólo me ha funcionado cn PIC24 con un módulo SD de tamaño estándar (como este) y con jumper flotando conectado a SCK. Desde PIC18 a 5V no he tenido problemas.  

La tercer falla más común es con la frecuencia máxima. Comentan en los foros que algunos módulos prefabricados no están optimizados para trabajar a máxima frecuencia de SDK. Sus circuitos tienen un pasa-bajas que solo permite frecuencias de entre 1-2 MHz. Si están desarrollando una aplicación comercial es mejor que integren su propio circuito de conexión con un socket microSD.

Edit: ¡Alcance hacerla funcionar hasta la frecuencia máxima de SCK para el GB002 que es de 8MHz! 

Otro detalle más. El simulador Proteus solo funciona con memorias virtuales en formato FAT16 en algunas instalaciones. Al menos a mi sólo me he funcionado así. En físico no he tenido problemas con FAT32. 

Nivel de optimización

Esta librería ocupa bastante espacio. Un microcontrolador de 32K de memoria de programa es apenas suficiente (pero funciona). Idealmente deberían usar de al menos 64K. Si llega a marcar un error al compilar pueden intentar subir el nivel de optimización del compilador a 2 de la siguiente forma:

Click para agrandar


Código principal

Si todo lo anterior está en orden el siguiente ejemplo de escritura debe funcionar sin problemas con este circuito (el código es para GB002, el circuito en Proteus tiene un GA002 pero el conexionado es el mismo):

 

jueves, 6 de agosto de 2020

Cielomotos y trenes

Se le llama cielomoto a un conjunto de fenómenos atmosféricos (de naturaleza poco comprendida aún) que provocan sonidos o señales inusuales en múltiples instrumentos de monitoreo. Los más conocidos son los eventos de sonidos similares a una trompeta o instrumento metálico. Otros reportes mencionan sonidos similares a motores sin poder ubicar la fuente. En los últimos meses ha habido un repunte de estos reportes en medios de noticias y redes sociales.  Desde antes de la pandemia mis primos, aquí en Mérida, me habían contado que les da mucho miedo unos sonidos muy fuertes y extraños que parecen venir del cielo. En el grupo de WhatsApp que tenemos han comentado estos fenómenos siempre entre las 2 y 4 de la mañana. Yo no había tenido la oportunidad de escucharlos hasta hace cosa un mes. Es verdaderamente un sonido tan extraño que enchina la piel. No pude grabarlo porque no era muy intenso y se perdía entre el ruido de los aires acondicionados de mis vecinos. El tipo de sonido era una mezcla entre trompeta y ballena de canto metálico. Pero el sonido también me hizo recordar una grabación de uno mis amigos en Puebla de hace dos años donde se escucha un sonido metálico estilo "pelicula de terror". Pero en este caso la fuente fue identificada y se trataba de los frenos de emergencia del tren (por un asalto organizado según cuenta). Si bien los sonidos no son exactamente iguales me ha hecho pensar si una parte de los sonidos en el cielo reportados podían deberse a los frenos de tren. En el caso de Mérida parece tener sentido porque el tren suele pasar por la ciudad en la madrugada cuando hay menos transito en las calles.

Con la hipótesis del tren como el origen de las Trompetas del Apocalipsis lo que necesitaba para fortalecer las evidencia era tener un mapa con todas las rutas ferroviarias de México. Esto era que quería saber desde que era niño. Siempre me han gustado los trenes. Llegué a subirme con mi papá a una máquina azul del Tren del Balsas que estaba parada en la estación de Puente de Itxla. Este tren dejó de operar en 1997. Varias veces me tocó verlo pasar desde la autopista Acapulco-Cuernavaca y me había quedado con la duda de hasta donde llegaba ese tren. Pude resolver ambas incógnitas con el sitio OpenRailwayMap. No sólo muestra las vías activas sino también las vías retiradas (como la del Balsas). Con este mapa ya podía trabajar. Tenía seguras hasta ese entonces dos ubicaciones de reportes de sonidos similares: Lagos de Moreno (vía Román Villalobos) y Mérida.  Ambas ciudades con pasos de tren. ¿Habría mas reportes de estos sonidos en las ciudades de las rutas ferroviarias? Empece a buscar en Youtube y estos ruidos aparecen en todas las ciudades grandes en rutas de tren: León, Querétaro, Xalapa, Coatzacoalcos y la lista sigue. No puedo demostrar aun que esta sea la causa pero creo que es un buen acotamiento de la búsqueda. La evidencia definitiva sería captar al tren directamente haciendo los sonidos. Si algún lector la tiene le agradecería ponerla en comentarios.  

sábado, 1 de agosto de 2020

Creatividad

Se habla mucho de la creatividad y la innovación pero muchas veces es poco lo que se dice. Me parece excelente que haya motivación para arreglar el mundo pero las buenas intenciones no son suficientes ¿Exactamente cómo se es creativo? ¿Cuáles son las herramientas mentales que hay que tener para resolver problemas complejos? Entiendo que no son preguntas fáciles de responder y más que crítica es solo un señalamiento para no trivializar las dificultades. Tampoco creo que todo en la cultura maker y de emprendimiento este mal en este sentido. Creo que la popularidad del Design Thinking es lo mejor que ha pasado en el tema de innovación en los últimos años.  Incluso creo que falta mucha más divulgación de metodologías como Sprint y SCRUM fuera de la comunidad de desarrollo de software y empezar a deshacernos tanto del perfeccionismo como de la improvisación excesiva. Pero hay una pieza muy grande que falta en el fondo. El mundo es complejo y se requiere de redoblar y simultáneamente reducir inteligentemente el esfuerzo para encontrar soluciones.

Mi pequeña contribución que puedo hacer aquí es recomendar dos libros que he leído durante la cuarentena y que sentí que verdaderamente abren la caja negra del pensamiento creativo:


He descartado muchos otros por repetir los clichés del "genio creativo" o dar recetas demasiado ambiguas. Estos dos libros aportan insight real en la cuestión de la creatividad y en lo que yo llamaría soft problem solving. Para el hard problem solving estoy preparando una selección diferente. También la publicaré por aquí cuando la tenga lista.

domingo, 12 de julio de 2020

Little Fury Things, J Mascis


¿Cómo que Richard Stallman y J Mascis no son la misma persona?

sábado, 27 de junio de 2020

Consola serial en PIC en XC16

Chan ya es famoso por ser el autor de la librería para manejo de archivos FAT32 en memorias SD pero tiene muchas otras creaciones geniales. Aquí describiré un ejemplo para usar la librería xprint que permite dotar de forma sencilla a casi cualquier microcontrolador de una pequeña consola de operación o depuración. Usaré un PIC24FJ32GA002 pero entendiendo la idea general se puede portar facilmente a cualquier otro dispositivo.  Primero, deben descargar los archivos xprinf.h y xprintf.c. Esta librería está escrita en ANSI C por lo que es independiente de la plataforma y el compilador. Las tres funciones más importantes que contiene son:
  • void xputs (const char* str)          : análoga a la función puts()
  • void xprintf (const char* fmt, ...) : análoga a la función printf()
  • int xgets (char* buff, int len)        : similar a la función gets()

 xputs() permite escribir una cadena simple. como un "Bienvenidos al programa". xprintf() nos permite dar formato a la cadena, como ("Temperatura %d",temp), como lo haríamos en un C en una PC. xgets() es muy útil y la que la dará mucha presentación a un programa para microcontrolador. Es en esencia muy distinta a su contraparte gets(). Lo que hace xgets es ir capturando en tiempo real lo que se vaya recibiendo el microcontrolador del puerto serial hasta que se presiona ENTER. La misma función va enviado simultáneamente cada carácter a Tx como espejo (aunque esta opción puede desactivarse en los macros del header). ¡Permite incluso borrar caracteres!    

La librería no puede funcionar por si sola. Es necesario asociarla a funciones de escritura y lectura bajo nivel. Lo que sigue ahora es crear un programa que contenga las rutinas para enviar y recibir un byte por puerto serial con la siguiente forma:

//-- Poner byte en el registro Rx
unsigned char uart_getc(void);

//-- Poner byte en el registro Tx

void uart_putc(unsigned char d);


Esta parte del programa siempre será dependiente del dispositivo y compilador. Estas dos rutinas pueden tener cualquier nombre siempre y cuando se asocien en el código principal de la siguiente manera:

//-- Unir UART con funciones de consola
xdev_in(uart_getc);        
xdev_out(uart_putc);

La implementación de las funciones de comunicación serial también están basadas en la implementación de Chan pero las he reescrito de una forma más clara y comentadas lo mejor que pude. Esta implementación utiliza dos colas (registros FIFO), una de envío y otra de recepción. Esto es muy útil porque permite aprovechar las interrupciones de la UART para no perder bytes. Las referencias a páginas son para la data del GB004 pero es la misma información.   

Aislamiento

Si están utilizando baterías para alimentar al PIC o van a estar realizando depuración es una buena práctica utilizar opto-acopladores. Esto también permite utilizar módulos de conversión USB-Serial que no tengan salida de 3.3v:


 

Programa completo:

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



miércoles, 10 de junio de 2020

Trazos

Mi persona es como el meme del dibujo del caballo. Algunas partes están muy bien definidas y estilizadas, y quien me conozca sólo desde esos ángulos suele intimidarse o tenerme por una persona con los cabos bien atados. No digo que se equivoquen en todo pero si quiero señalar que pocos saben que el resto de mi son solo bosquejos y garabatos. No digo esto por complejo de inferioridad como podría pensarse, o como alguna vez si lo fue. Es lo que he visto en mis introspecciones y hay, diría, razones históricas. Con la misma evaluación honesta se también que soy perfectamente capaz de tomar un lápiz y terminar de dibujarme. Pero hoy no. Aún no sé que dibujar sobre muchos de los espacios en blanco ni sobre las lineas pobremente trazadas. Sigo inacabado y a veces me lo recuerda una que otra amarga circunstancia.