Programar un microcontrolador AVR remotamente mediante bluetooth

Los que llevamos un tiempo en esto de la robótica para concursos nos vamos dando cuenta que se pierde mucho tiempo en muchas cosas para hacer las pruebas a nuestros robots y dejarlos configurados correctamente. Una de las cosas que lleva más tiempo es reprogramar el robot cada vez que queremos cambiar algo en el firmware que no funciona: tienes que ir a por el robot, cogerlo, pararlo, llevarlo hasta el ordenador, quitarle la batería, ponerle el cable ICSP, seleccionar el fichero .hex, programarlo, ponerle la batería de nuevo, llevarlo a la pista, dejarlo en ella y activarlo.

Con este artículo nos vamos a ahorrar todos los pasos mencionados simplemente programando el firmware del robot mediante bluetooth gracias a un bootloader.

Aunque este artículo esté enfocado a la baby orangutan (atmel328P) y el módulo bluetooth CSR, podría funcionar con otros microcontroladores AVR (incluido Arduino) y otros módulos bluetooth.

Como comentaba antes, la posibilidad de programar el firmware de nuestro microcontrolador AVR mediante bluetooth se basa en un bootloader. Los bootloader permiten reprogramar el microcontrolador sin necesidad de tener que usar siempre un programador ICSP. En realidad no es más que un programa que se carga en la zona alta de la memoria y que cambiando los fuse bits del microcontrolador hacemos que sea el primero que se ejecute. Esta gran ventaja nos permite que el bootloader esté comprobando durante unos segundos si se envía información desde el puerto serie del microcontrolador, si es así, reprograma el microcontolador (excepto la zona de memoria del bootloader) con el código enviado y lo ejecuta, si no es así, entonces pasado un tiempo ejecuta el código que hubiese anteriormente. Como el puerto serie ya ha sido configurado por el bootloader, en nuestro programa ya podremos usar las rutinas de envío y recepción por el puerto serie sin la necesidad de tenerlo que configurar de nuevo.

El objetivo de este artículo no es explicar cómo hacer un bootloader, sino utilizarlo directamente. Por eso voy a usar uno ya hecho: KAVR. Este bootloader espera por el puerto serie que se le envíe el fichero .hex del código a programar, por lo que podríamos usar cualquier programa como Minicom (linux), Hyperterminal (windows xp) o, como en mi caso, Tera Term (windows 7).

Antes de usarlo hay que retocar los fuentes, por lo que debemos bajarnos el código fuente, descomprimirlo, entrar en el directorio bootloaderskavr-0.2_328P-14s y editar el fichero Makefile. Dentro de este hay 3 valores que cambiar dependiendo de nuestro sistema:

  • F_CPU: La velocidad de nuestro microncontrolador en hertzios, en el caso de la Baby Orangutan es 20000000.
  • BAUD: La velocidad del puerto serie en bps, en mi caso el bluetooth está configurado a 115200.
  • TIMEOUT: El tiempo que esperará el bootloader a posibles datos en el puerto serie antes de ejecutar el firmware anterior, en mi caso le he puesto 5000 (5 segundos).

Dentro de la misma carpeta tenemos que editar el fichero kavr.c y añadir a la lista de cabeceras la siguiente:

y justo antes de la línea

añadir las siguientes dos líneas que desactivan el watchdog (que explicaré más adelante) en el bootloader:

Después hay que recompilarlo para que nos genere el fichero kavr.hex Para ello usaremos el toolchain de AVR, que en mi caso está en directorio C:Program Files (x86)AtmelAVR ToolsAVR Toolchainbin:

A continuación debéis activar en el microcontrolador los fuse bits BOOTSZ y BOOTRST para indicarle que va a tener un bootloader, el BOOTSZ debe ser de 512 palabras para que quepa el KAVR:

Finalmente enviamos el fichero kavr.hex mediante ICSP al microcontrolador, esta será la última vez que tengáis que hacerlo 😉 .

Ya tenemos nuestro bootloader activo. Ahora hay que hacer nuestro programa, compilarlo y enviárselo mediante bluetooth a nuestro microcontrolador. Para ello previamente deberemos haber vinculado nuestro dispositivo bluetooth a nuestro PC. Después abriremos el puerto serie que se ha creado en la vinculación con los siguientes parámetros 115200,8N1,XON/XOFF:

Debido a la alta velocidad de transmisión he necesitado poner un retardo en el envío de cada línea de 1 ms, pero este ha sido mi caso y no se si os pasará igual si usáis otro módulo bluetooth (si ponéis todo el conjunto a una velocidad menor, por ejemplo 19200, no será necesario ese retardo en el envío con el módulo CSR). Lo del control de errores XON/XOFF lo implementa el bootloader, permite que el microcontrolador le diga al software de control de puerto serie que pare el flujo de datos mientras escribe en la memoria flash, así no se pierdan bytes por el camino al no poder procesarlos a tiempo.

Una vez abierto el canal de comunicación el bootloader nos enviará el texto KAVR indicando que está esperando a que le enviemos un fichero .hex:

Si no le enviamos el fichero en 5 segundos lanzará el programa que esté en la posición cero de la memoria flash, pero si no existiese tal programa, volvería el bootloader a ejecutarse. El fichero debe enviarse como fichero de texto, en Tera Term se hace en el menú FileSend File…

Si la programación ha ido mal, el bootloader enviará el símbolo ?. Si ha ido bien enviará el carácter S e inmediatamente se ejecutará el código.

Ahora sólo queda conseguir que cuando queramos programar otro firmware no tengamos la necesidad de acercarnos al robot y pulsar el botón de reset para que se resetee el microcontrolador y arranque el bootloader de nuevo. Por desgracia en los AVR no hay posibilidad de resetear mediante software, sin embargo hay un truco para lograrlo: El watchdog es un temporizador que si llega al final de su cuenta resetea el micro, por lo tanto para que no ocurra esto se debe poner a 0 el contador cada poco tiempo. El truco consiste en que cuando el microcontrolador reciba una orden a través del puerto serie, este lance un bucle infinito que no actualice el contador del watchdog, provocando su reseteo y en consecuencia ejecutando el bootloader.

A continuación pongo un ejemplo de código muy sencillo: Lo que hace el programa es activar la interrupción de recepción de carácteres. Después apaga y enciende un led en el pin PD7 cada 500 ms. indefinidatmente, pero cuando recibe una R por el puerto serie, cambia el valor de una variable a 1. Dentro del bucle principal se comprueba si esa variable está a 1, y si es así, envía OK por el puerto serie, activa el watchdog y se mete en un bucle infinito para provocar el reseteo.

En la siguiente imagen podemos ver cómo arranca el bootloader con el texto KAVR, como no hay nada que programar no sale nada más y arranca el programa principal, pero al cabo de poco se le ha enviado al programa una R y este ha respondido con un OK, a continuación el microcontrolador se ha reseteado arrancando de nuevo el bootloader y mostrando otra vez KAVR, se le ha enviado un fichero .hex y el bootloader ha respondido con una S indicando que todo ha ido bien y procediendo a ejecutar el programa principal:

Y aquí una demostración en vídeo:

17 comentarios en “Programar un microcontrolador AVR remotamente mediante bluetooth

  1. ionhs

    Genial el articulo, a mi se me escapa un poco principalmente porque no suelo usar las herramientas de AVR para programar ni cargar el bootloader

    Responder
  2. tony

    una duda amigo, estaba checando la velocidad de mi atmega1284 y es de 20mhz tambien entonces el procedimiento seria totalmente el mismo?? la velocidad en baudios en mi programa para usar el modulo bluetooth??

    Responder
    1. Oscar Autor

      Me temo que el problema es que el KAVR es para atmega328p o atmega88. No sabría decirle qué modificaciones hay que hacer en el código para que funcionase en un atmega1284.

      Responder
  3. Matias

    Hola,
    Muchisimas gracias!! ! !!! !-)

    Estoy haciendo un pequeño proyecto, donde me sera muyyy util. 🙂

    Eso si.. Le tengo miedo al tema de los fuses.. :S
    Estoy haciendo un diseño en eagle basado en un Arduino Uno. Simple, casi un paperduino.. 😉

    Tenes idea que fuses bits tengo que usar?. Sinseramente nunca aprendi estos temas.. Ya lo voy a hacer.. jajaja.

    Responder
    1. Oscar Autor

      Con que pongas los mismos que aparecen en la imagen del artículo es suficiente. Ya nos contarás qué tal la placa.

      Responder
  4. javier

    Después hay que recompilarlo para que nos genere el fichero kavr.hex Para ello usaremos el toolchain de AVR

    como hago para recompilarlo. no se como interpretar tus instrucciones. soy un poco novato

    Responder
    1. admin Autor

      ¿Sabes manejar un compilador? si es asi es volver a compilar el código fuente, si no es así tendrás que buscar un manual de winavr o avr studio.

      Responder
  5. javier

    tengo un atmega328p y bluetooh hc06. te agradeceria me mandases por email la recompilacion ya realizada. tengo problemas y conflictos en el pc y no le puedo dedicar tiempo para solucionarlos. gracias

    Responder
  6. Ernesto Paredes

    Hola. he estado buscando por mucho tiempo información sobre crear mi propio Bootloader pero no hay información contundente, creo que eres el primero que ofrece una excelente alternativa, te felicito!!! Necesito hacer mi propio Bootloader y no se que escribir en él..entiendo el concepto y todo, pero no se como hacerle para lo que reciba por UART lo escriba en la FLASH..después de eso cómo le hago para que el AVR ya con la FLASH programada remotamente sea ejecutada sin que el AVR se quede enclavado en el Bootloader..es decir..como se sale el AVR de Boot para pasar ala aplicación??.
    Podrias orientarme??
    Gracias y saludos.

    Responder
    1. admin Autor

      Hola

      Tu programas un código y después le dices al programador que te lo guarde en la zona alta de la memoria flash, es decir, la que está reservada al bootloader. Como está activado el flag de bootloader, el microcontrolador salta a esa zona de memoria y es como otro programa más, puedes leer de la UART, usas los puertos GPIO, etc y además grabar datos en la zona baja de la memoria (que empieza desde el 0) con sentencias boot_page_write y similares, luego simplemente saltas a la posicion de memoria flash 0 para ejecutar el nuevo código.

      Responder
  7. electronic

    Gracias por compartir tus conocimientos, pido tu ayuda he buscado por todas partes como lograr la programación remotamente por bluetooth hc-05 o HC-06 pero de un PIC 16f877A o cualquier otro PIC, he intentado muchas técnicas pero no lo he logrado, por favor podrías hacer un post sobre como lograr hacerlo pero para un PIC te lo agradecería mucho.

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *