Problemas tecladiles (8)

He empezado a añadir funcionalidades extra a mi teclado. En concreto, controles multimedia (volumen, etc). Y ya he encontrado un bug raro: sólo funcionan si la placa está en modo «keyboard+mouse+joystick», pero no en modo «serial+keyboard+mouse+joystick».

Las placas Teensy se pueden poner en varios modos desde el entorno de Arduino. Aquí los podemos ver:

Lo normal es utilizar el modo «Keyboard + Mouse + Joystick» para productos finales, y el modo «Serial + Keyboard + Mouse + Joystick» para depuración, pues podemos enviar texto a la consola. Sin embargo, por algún motivo, si la placa está en este último modo, los códigos de las teclas multimedia (KEY_MEDIA_VOLUME_INC, KEY_MEDIA_VOLUME_DEC, etc) no funcionan: no se recibe absolutamente nada (y lo he comprobado leyendo directamente de /dev/input/eventXX).

Terminus llega a la versión 2.0

Después de muchos años, Terminus acaba de llegar a la versión 2.0. Y no ha sido «porque sí», sino porque ahora incorpora una nueva funcionalidad que creo que lo convierte en aún más útil: Drag’n’Drop.

Ahora es posible arrastrar un terminal agarrándolo por la barra superior (la que se pone roja cuando el terminal tiene el foco), y cambiarlo de sitio, bien dentro de la misma pestaña, en otra pestaña de la misma ventana o de otra ventana, en una nueva pestaña de la misma ventana o de otra ventana, o incluso en una nueva ventana. Esta característica permitirá evitar el «arrepentirse» de estar ejecutando algo en otra pestaña cuando ahora vendría mejor tenerlo junto a ese otro terminal; o si tenemos algo en la ventana tipo «Guake» y nos interesaría tenerlo en una ventana independiente, etc.

A mayores incorpora alguna que otra característica nueva, como permitir configurar el auto-ocultamiento del cursor. Así, si está activo, al teclear cualquier cosa, el cursor del ratón desaparecerá (y así no molesta), apareciendo de nuevo tan pronto se mueva el ratón.

Como de costumbre, se puede descargar en mi página web.

Problemas tecladiles (7)

¡¡Hace unos días me han llegado las placas de PCBWay!! Pero como estuve fuera, hasta hoy no he podido poner nada.

Se trata de la versión 1.17 del teclado, que frente al diseño 1.0 de los teclados que construí hasta ahora, tiene tres NeoPixels, huella para el protector ESD, correcciones de compatibilidad con Teensy, serigrafía en los pines de programación, y algunos otros detallitos menores (como el maravilloso recuadro blanco para escribir anotaciones). Y el acabado es, sencillamente, perfecto. ¡Un 10 para PCBWay!

Después de la experiencia que he tenido, creo que estos teclados los voy a construir con pulsadores Cherry «de verdad». Iré contando.

Problemas tecladiles (5)

Recientemente estuve haciendo algunos cambios extra en el diseño. Por ejemplo, combiné en ambos diseños la tecla SHIFT corta + tecla de «menor y mayor» de las distribuciones ISO, junto con la tecla SHIFT larga de las distribuciones ANSI. Esto permite combinar distribuciones, algo que puede ser interesante para aquellos que prefieran la tecla de RETURN americana, pero quieran usar una distribución española, por ejemplo.

También aproveché para añadir dos NeoPixeles más en los dos huecos que había entre F4 y F5, y F8 y F9, lo que permite aumentar las posibilidades.

Por supuesto, llegó también el momento de diseñar la carcasa, para lo que decidí aprovechar los resultados de un cursillo de diseño e impresión 3D que hice hace tiempo (¡¡¡¡Gracias por convencerme para ir, Miguel!!!!). No tendría que ser demasiado difícil…

El primer problema que me encontré fue que el teclado mide 32cm de ancho, pero las impresoras 3D normales tienen una cama de entre 20 y 30cm, lo que significa que no podía imprimirlo todo de una sola vez sino que tendría que dividir la carcasa en dos mitades que se pudiesen pegar. Ante esto comencé con el primer diseño:

Como base no estaba mal, pero faltaban las patas y cubrir los huecos entre las teclas. Para ello se me ocurrió que podía utilizar una pieza que se añadiese por detrás.

Menos mal que se me ocurrió probar a imprimirla antes… ¡Menudo desastre! Se suponía que la parte delantera, que es la que queda hacia el fondo en la imagen, tenía unos huecos en donde la placa se introducía para quedar fijada; por desgracia, para imprimirlos hacía falta utilizar soportes, los cuales no había manera de quitar en una zona tan estrecha como una placa de circuito impreso. Ante esto, decidí probar un segundo diseño:

En este nuevo diseño, el bloque principal de la carcasa estaba compuesto por cuatro piezas en lugar de dos (a mayores hay dos piezas extra para hacer una pata que va de un extremo a otro). Las dos piezas traseras se imprimirían «planas», pero las delanteras, en donde estaba la ranura en donde encajaría la PCB, se imprimiría «hacia arriba», con el frontal apoyado en la cama. De esta manera se podían evitar los soportes.

Por desgracia, aún era demasiado complicado, pues la parte de la pata consumía muchísimo filamento y no era nada sencilla de montar. Además, la alineación de las cubiertas para las zonas entre las teclas era crítica, pues hay menos de un milímetro de margen: un error, por pequeño que sea, haría que las teclas rozasen o, peor aún, no pudiesen bajar… como de hecho me ocurrió.

Finalmente, tras darle muchas vueltas se me ocurrió que podía simplificarlo muchísimo si separaba las cubiertas de los huecos de la carcasa, de manera que fuesen piezas independientes. De aquí salió el diseño de arriba: las dos piezas traseras se imprimen rotadas 90 grados, mientras que las dos piezas delanteras se imprimen «tal cual», de manera que no hace falta ningún tipo de soporte. El diseño lo hice sin la base para ahorrar plástico, pues quería usar un trozo de lámina de polietileno recortada para abaratar costes y reducir el tiempo de impresión.

Las piezas para cubrir los huecos entre las teclas de función las imprimí aparte, con la intención de pegarlas directamente en la PCB. Esto no sólo simplificaba mucho el diseño, pues no había que hacer malabares para evitar tener que usar soportes, sino que, además, eliminaba completamente los problemas de falta de precisión:

El diseño tenía buena pinta, pero aún no me acababa de convencer, pues había que pegar cuatro piezas para construir la carcasa, lo que no era muy cómodo. Además, la idea de ahorrar costes utilizando una lámina de polietileno como base no resultó: para empezar, las ranuras que había en el diseño para que ésta encajase eran demasiado estrechas, algo que, además, dependería de la impresora en sí. Pero además, si quería que las piezas se imprimiesen bien, no me quedaba más remedio que imprimir una «balsa», con lo que el ahorro no era tal, pues al final estaba imprimiendo la base igual, sólo que la tiraba a la basura.

Finalmente, llegué al diseño actual, que es éste:

La carcasa en sí está compuesta por solo dos piezas, las cuales, además, son muy fáciles de pegar. La superficie principal de la base tiene un grosor de sólo 0,6 milímetros, lo que significa que se gasta la misma cantidad de filamento que si se utilizase una «balsa» con el diseño anterior; sin embargo, la resistencia es la misma, pues en los bordes el grosor aumenta para darle rigidez. Las patas se imprimen aparte y se pegan en el borde trasero. Esto tiene la ventaja de que es posible imprimir patas de distinta altura para ajustarlo a las preferencias de cada uno. Por último, las cubiertas se imprimen aparte, como se ve, y además hay tres piezas extra que también se pegan entre las teclas y que sirven como «tuercas» para atornillar la placa a la carcasa (aunque en los dos teclados que hice no fue necesario, pues quedaron perfectamente ajustadas).

Y el resultado final es éste:

Documentando con los pies (2)

En la entrada anterior expliqué cómo construí un pedal para tomar fotografías desde el móvil y así simplificar el documentar proyectos hardware. Por desgracia, cuando llegó el momento de usarlo por primera vez me encontré con un problema: resulta que la aplicación de cámara de Android se cierra automáticamente al cabo de dos minutos de no hacer nada con ella. Esto es un problema porque entre foto y foto bien puede pasar mucho más tiempo, lo que me obligaría a acercarme al móvil y lanzar la aplicación de nuevo. Esto no tiene nada que ver con el apagado automático de la pantalla: aunque le ponga media hora para que apague la pantalla, la aplicación de la cámara vuelve a la pantalla principal a los dos minutos de estar «sin hacer nada».

Obviamente esto es completamente inaceptable, así que decidí agarrar el toro por los cuernos y escribir una pequeña aplicación de cámara para Android que no tuviese este problema. Para ello partí de un ejemplo de cómo utilizar la cámara en Android, escrito en Kotlin. Reconozco que no es un mal lenguaje, pero no le acabo de pillar el punto (todo lo contrario que Go… pero esa es otra historia).

Tras una primera prueba, conseguí que funcionase de manera constante. Sin embargo, me encontré con la desagradable sorpresa de que el tener la cámara funcionando constantemente hace que el móvil se caliente un montón, cosa que no me hacía nada de gracia (de hecho, al buscar por qué la aplicación oficial de cámara se cerraba a los dos minutos, uno de los motivos que decía era ese; me parecía muy extraño, teniendo en cuenta que sí puedes grabar vídeo durante más tiempo, pero visto lo visto, podría ser una de las razones).

Ante esto, tuve que complicar un poco la aplicación, haciendo que la cámara se desactive al cabo de un tiempo sin hacer nada, pero dejando la aplicación en primer plano y activando de nuevo la cámara tan pronto se pulsa uno de los botones de volumen para tomar una foto. De esta manera el móvil no se recalienta.

Como comienzo no estuvo mal, pero claramente tenía un problema: ¿cómo puedo saber si una foto es buena, o tengo que repetirla? La solución fue relativamente sencilla: añadir la posibilidad de enviar cada foto tomada a mi portátil, que estaría en un sitio donde podría ver fácilmente el resultado. Así, añadí dos campos de texto en la app en los que teclear la dirección IP del portátil y un puerto (por defecto usa el 9000), y en éste correr una pequeña aplicación en python que se limite a escuchar por dicho puerto, y cuando se abra, recibir los datos de la imagen en formato JPEG, descomprimirlos, y mostrarlos en la pantalla.

El resultado era bastante bueno, pero tenía un problema aún: la cámara de mi móvil es de 4160×3120 pixels, un tamaño exageradamente grande que resulta en ficheros muy grandes. El resultado es que entre que pulso el pedal y aparece la foto en el portátil pasan unos nueve segundos (tres de los cuales son debidos a tener que encender la cámara). Para resolverlo añadí un campo de «resolución», que permite poner un tamaño deseado (yo le pongo 2048), de manera que el móvil escogerá la resolución más cercana a ese valor entre los que permita la cámara. Con esto, el tiempo baja a cuatro segundos si la cámara estaba apagada, y un segundo si la cámara estaba encendida (por ejemplo si no nos gusta la foto y decidimos sacar otra, la cámara estará ya encendida y será muchísimo más rápido).

El código fuente (compilable con Android Studio) está disponible en mi repositorio GIT: https://gitlab.com/rastersoft/footcam. Hay un paquete APK para Android ya compilado que se puede descargar desde la sección Tags, simplemente pinchando en el número de versión. En el repositorio principal se puede descargar el programa de visualización remota, llamado «receiver.py«. Para utilizarlo, además de Python3 es necesario WxPython.

Documentando con los pies

Me gusta hacer proyectos de electrónica, pero documentarlos… ¡ay! Eso ya es otro cantar. A fin de cuentas, para ello tengo que decidir cuando sacar alguna foto, y eso me obliga a parar lo que estoy haciendo, sacar el móvil, encuadrar con una mano mientras con la otra sostengo lo que estoy haciendo… un cristo.

Pero a la vez tengo claro que quiero documentarlo, por un lado por mí, porque así tengo un registro de las cosas que he hecho y me puede servir en el futuro («¿Cómo había hecho aquello…?), y también porque puede ser útil para otras personas.

Tras darle varias vueltas, se me ocurrió una idea: dado que tengo un trípode con soporte para el móvil, podría montarlo y encuadrar una zona concreta de la mesa de trabajo, ya con luz adecuada y demás, y cada vez que quiera sacar una foto sólo tendría que pulsar un botón.

Por supuesto, queda la cuestión de cómo conectar ese botón, pero afortunadamente es algo que hace cualquier palo selfie que se precie, por lo que sólo tenía que conectarlo a la entrada de cascos. Rebusqué en internet y encontré las especificaciones oficiales 3.5 mm Headset: Accessory Specification y 3.5 mm Headset Jack: Device Specification. Estas dos especificaciones indican cómo se deben conectar los altavoces, micrófono y pulsadores en un móvil Android, y qué funcionalidad debe tener cada uno.

Una lectura rápida nos indica que los botones están conectados entre el terminal 3 y 4 del jack, en paralelo con el micrófono, y que las cuatro funcionalidades posibles se consiguen presentando un valor concreto de resistencia entre dichos terminales. Así, si aparecen 0 ohmios (o sea, si se cortocircuitan), la función es la A (play/pausa/descolgar si es una pulsación corta; asistente si es una pulsación larga, o siguiente canción si son dos pulsaciones cortas); con un valor de entre 210 y 290 ohmios la función será la B (subir volumen); un valor de entre 360 y 680 ohmios activará la función C (bajar volumen); por último, un valor entre 110 y 180 ohmios activará la función D, que es una funcionalidad «reservada». Dado que la cámara se puede activar con cualquiera de los botones de volumen, bastaba con poner una resistencia adecuada en serie con un pulsador entre los terminales 3 y 4 del jack y estaría listo.

Decidí hacer una prueba rápida con un único botón, y para mi sorpresa… ¡¡¡no funcionó!!! Ante esto, decidí hacer un montaje un poco más completo con las funciones A, B y C:

Con los valores del esquema, el botón A cortocircuita los pines 3 y 4 del jack; el botón B muestra 240 ohmios, y el C 480 ohmios.

Y seguía sin funcionar: el móvil detectaba que había algo conectado, pero no hacía absolutamente nada: ni subir y bajar el volumen, ni responder a una llamada… ¡nada! Revisé los valores de resistencia con el polímetro, probé otros valores para activar otras funciones… pero nada, no quería funcionar. Era rarísimo.

Decidí buscar a gente que hubiese hecho un montaje similar y encontré un par de ejemplos documentados, pero ambos hacían exactamente lo mismo que yo.

Me releí una y otra vez la documentación, y entonces caí en un detalle: se indica que el micrófono tiene que tener una impedancia en continua superior a 1000 ohmios. Yo había dado por supuesto que podía dejarlo «desconectado», pues infinito es mayor que 1000 ohmios, pero, por si acaso, decidí poner en paralelo una resistencia de 2Kohmios, así:

¡Y ahora sí que funcionó! Está claro que al menos mi móvil espera que haya una cierta impedancia, y no un valor «infinito».

Con esto claro, hice algunos cálculos y el circuito definitivo es éste:

Cuando el pulsador está abierto, el móvil ve una resistencia de 2 Kohmios, y cuando se pulsa, al poner en paralelo un valor de 320 ohmios, el valor que ve es de 1 / (1/2000 + 1/320) = 275,8 ohmios, lo que activa la función B (subir volumen).

Ahora llegó el momento de decidir cómo activar la cámara. Aunque la primera opción sería tener un pulsador en algún lugar cómodo, eso seguiría implicando soltar lo que esté haciendo, así que decidí que tenía que ser algo que pudiese activar sin las manos. Y la opción obvia es un pedal. Aunque podía comprar uno, preferí aprovechar cosas que ya tenía por aquí y montarme uno yo mismo. Para ello utilicé unos pulsadores de circuito impreso que tenía en casa y unas protoboards.

Los cuatro pulsadores están conectados en paralelo, así que basta con que se active cualquiera para que el móvil detecte la función «subir volumen». Obviamente, la placa va al revés de como se ve, con los pulsadores hacia el suelo, y hago presión por el lado de las soldaduras… algo nada recomendable (ni para las soldaduras, ni para el pie si se hace descalzo), así que le pegué una segunda placa por el lado opuesto para taparlo todo.

Y este es el resultado:

Problemas tecladiles (4)

EDITADO: actualizados los fuses.

Como ya comenté, decidí reemplazar el cargador original del Atmega32U4, llamado DFU y que se puede descargar desde la página de Atmega, por Ubaboot, un bootloader reducido que sólo ocupa 512 bytes y que es muy sencillo de utilizar. A mayores envié dos parches para simplificarlo aún más:

Para instalar Ubaboot, lo primero que hay que hacer es editar el fichero config.h y configurar los parámetros de nuestra placa. En el caso de mi teclado, hay que descomentar OSC_MHZ_16 (pues el reloj es de 16MHz), y USB_REGULATOR:

Una vez hecho esto, hay que programar los fuses del microcontrolador para un bootloader de 512bytes, además de asegurarnos de configurar bien el resto. En el caso de mi teclado, la configuración es la siguiente:

Fuse LOW: 0x5E

  • CKDIV8 0
  • CKOUT 1
  • SUT1/0 = 0x01
  • CKSEL3/0 = 0x0E

En este bloque básicamente no tocamos nada.

Fuse HIGH: 0xDE

  • OCDEN 1 (desactivado)
  • JTAGEN 1 (JTAG desactivado)
  • SPIEN 0 (programación por SPI activada)
  • WDTON 1 (watchdog desactivado)
  • EESAVE 1 (preservar EEPROM al borrar la memoria)
  • BOOTSZ1/0 0x11 (bootloader de 512 bytes)
  • BOOTRST 0 (vector de reset apunta al bootloader)

En este bloque básicamente desactivamos el JTAG, pues no lo necesitamos para nada, ponemos la dirección de inicio del cargador a 512 bytes antes del final de la memoria, y por último configuramos el vector de reset para que salte al cargador directamente. Esto último es muy importante, pues el propio cargador detecta si estamos arrancando «en frío» (en cuyo caso saltará a nuestro código directamente) o si hemos pulsado el botón de reset (en cuyo caso entrará en modo programación).

Fuse EXTRA: 0xFE

  • RESERVADO 7/4 tienen que estar todos a 1 (0xF)
  • HWBE 1
  • BODLEVEL2/0 0x1 (EDITADO)

El entorno de Arduino me había cambiado el BODLEVEL a 110 (1,8 a 2,2 voltios), en lugar del original 011 (2,4 a 2,8 voltios). Tras algunas pruebas, y en base a mi experiencia, he decidido que es más seguro ponerlo a 001 (3,3 a 3,7 voltios). Esto es algo que he cambiado en este artículo después de haberlo publicado.

El siguiente paso es conectar un programador SPI al teclado a través de los pines correspondientes. Yo uso un BusPirate que me prestaron, para lo cual tuve que editar el fichero Makefile y sustituir usbtiny -B10 por buspirate -P /dev/ttyUSB0 -b 115200, además de instalar AVRdude y el resto de utilidades de AVR. Con esto ya sólo me queda conectarlo al teclado y ya puedo leer el estado con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4

borrar todo el estado para desprotegerlo con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -e

grabar los fusibles con

avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U efuse:w:0xFE:m
avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U hfuse:w:0xDE:m
avrdude -c buspirate -P /dev/ttyUSB0 -b 115200 -p m32u4 -U lfuse:w:0x5E:m

y hacer make y make program para grabar el Ubaboot. Con él grabado, sólo tengo que pulsar el boton de RESET del teclado y se pone automáticamente en modo programación por USB, con lo que ya no necesito más el BusPirate.

Y ya, por último, instalé Arduino y Teensyduino para disponer de las bibliotecas de USB. Sin embargo, hice un pequeño cambio para integrar la programación mejor. Los cambios concretos están descritos en el fichero README del segundo parche que envié a Ubaboot.

Y con esto escribí la primera versión del software de mi teclado, pero eso lo comentaré con calma en otra entrada.

Problemas tecladiles (2)

Acabo de subir la revisión 1.7 de la placa del teclado. Uno de los cambios más importantes ha sido conectar una de las columnas del teclado desde el puerto PE2 al PB7. Para entender el motivo, primero necesitamos entender cómo es el proceso de arranque del Atmega32Ux.

El procesador Atmega32Ux permite añadir un bootloader y arrancarlo en determinadas circunstancias. Hay varias posibilidades:

  • Llamarlo manualmente desde el programa principal (útil para cambiar a modo programación de manera «manual»)
  • Llamarlo siempre que se resetee el procesador
  • Llamarlo tras un reset si se da cierta condición externa

Y esta última es la clave: esa condición externa es que el pin PE2 esté a nivel bajo en el momento de ocurrir el reset. Esto permite que, por defecto, se arranque el código principal, pero si se desea arrancar el bootloader, sólo haya que conectar dicho pin a masa y pulsar reset.

Pues bien, hasta ahora yo utilizaba dicho pin para una de las columnas del teclado simplemente por comodidad de diseño: al hacer el enrutado de las pistas, era más sencillo utilizar ese pin que otro.

El problema es que la placa Teensy 2.0, que es la que lleva el mismo procesador, tiene ese pin permanentemente conectado a masa a través de un pull-down y, además, no está conectado al exterior. Eso significa que en las bibliotecas de teensyduino no está disponible la opción de utilizar dicho pin.

Por simplicidad, yo quería mantener la compatibilidad con la Teensy 2.0 porque me da un entorno de programación y bibliotecas listas para utilizar, lo que simplifica mucho el trabajo, pero este problema me obligaba a rediseñar la placa, algo que no me apetecía mucho porque ya mandé fabricarlas y, aunque la versión actual es mucho más avanzada que la que tengo físicamente, los cambios hechos hasta ahora eran cosméticos y no afectaban a la lógica en sí, mientras que éste sí implicaba un cambio en la lógica de funcionamiento.

Decidí ver qué alternativas tenía, y descubrí que las placas Arduino Leonardo y Arduino Micro también utilizaban el mismo micro, así que decidí echar un vistazo a ver si podía utilizarlas. Al principio tenía buena pinta porque el bootloader estaba disponible, por lo que podía convertir mi teclado en un Arduino «con todas las de la ley». Por desgracia, la alegría no duró mucho: en el caso del Micro, el pin PE2 tampoco estaba conectado al exterior, con lo que estaba en las mismas. Aún peor: otros dos de los pines que utilizo en el teclado están asignados a LEDs, con lo que probablemente no tendría mucha libertad a la hora de utilizarlos. En el caso del Leonardo, tres cuartos de lo mismo.

Al final no me quedó otra que cortar la pista que conectaba PE2, y añadir dos puentes: uno entre PB7 y la pista original, y otra entre masa y una resistencia conectada a PE2.

Probando otros bootloaders

A pesar de todo, decidí probar el bootloader de Arduino, por si era más cómodo que el ubaboot que estaba utilizando hasta ese momento. Arranqué el editor Arduino IDE, configuré una placa Leonardo, le indiqué que tenía un programador Bus Pirate, y le di a Quemar bootloader. Varios minutos (sí, sí… tarda un muy buen rato y no muestra nada en pantalla que indique progreso) finalizó la grabación. Lo primero que descubrí es que me había cambiado los fuses del Atmega, algo que no me gustó mucho porque algunos flags eran… raros. Por ejemplo, me activaba el divisor entre ocho del cuarzo, lo que supone que la CPU va más lenta. Pero lo más raro es que pone a cero los bits 4 y 5 del byte extendido, los cuales se supone que no se deben escribir, y deben estar siempre a 1. Lo peor es que no soy capaz de devolverlos a su estado normal.

Tras varias pruebas, no me acabó de convencer el bootloader, así que volví al ubaboot de nuevo, pero esta vez quería asegurarme de corregir un par de problemas que tenía, y es que al pulsar el botón de reset para entrar en modo programación, no siempre funcionaba, sino que normalmente tenía que darle dos o tres veces antes de que el identificador USB fuese el de OpenMoko en lugar del de Teensy. Por otro lado, al darle la orden de reiniciar desde el programador ubaboot, el USB dejaba de funcionar.

Al final, tras echar un vistazo al código fuente, me di cuenta de que este bootloader espera ser llamado siempre durante el arranque, lo que significa que hay que poner a cero el bit 0 del Fuse High Byte, el flag BOOTRST. De esta manera, siempre arrancará desde el bootloader, y si éste detecta que el procesador está arrancando por haber sido conectado a la corriente, saltará directamente al código principal, y sólo entrará en modo bootloader si se pulsó el botón de reset.

Con estos cambios ya puedo programar fácilmente la placa del teclado: simplemente tengo que instalar Teensyduino para disponer de todas las bibliotecas, indicar al IDE que tengo un Teensy 2.0, y cada vez que compile, fijarme en donde ha almacenado el fichero hex con el código objeto (normalmente en /tmp/arduino_build_XXXXXX, y utilizar el comando

sudo ubaboot.py write path_al_fichero.hex

para programarlo.