Desarrollando con Visual Studio Code y Raspberry Pi

Hace un par de días me propuse empezar a utilizar Raspberry Pi con Raspian en lugar de Windows 10 core, esto significaba un reto interesante puesto que tenía que abandonar UWP y todas las herramientas a las que estaba acostumbrado; mi objetivo es utilizar Visual Studio Code en Windows, programar con Node.js y depurar remotamente en mi Raspberry Pi, este artículo muestra paso a paso cómo construir todo el ambiente que describí anteriormente y cómo depurar nuestro primer proyecto.

El primer paso es instalar Raspbian en el Raspberry Pi, esto es fácil de realizar por medio de NOOBS; en mi caso, yo decidí utilizar NOOBS LITE para hacer una instalación desde la red y seleccioné Raspbian Jessie with Pixel, esto da el sistema operativo con escritorio completo, realmente podía haber escogido Raspbian Lite pero quería ver todas las opciones en el sistema operativo :).

El proceso es simple, eliges una o más imágenes (puede tener multi boot si la tarjeta tiene suficiente espacio, pero yo sólo necesitaba Raspbian), seleccionas el idioma y procedes a instalar, todos los paquetes necesarios se descargan de internet, se hará el particionamiento adecuado de la tarjeta SD y se instalarán y configurarán los paquetes, después de esto el sistema iniciará y estará listo.

El segundo paso es configurar VNC, puedes usar la Raspberry Pi con un monitor directamente en el puerto HDMI, pero es más simple poder accederlo de forma remota, para esto debemos modificar la configuración de nuestro sistema. Habilitar VNC es una conveniencia, realmente todas las tareas que voy a describir pueden realizarse desde una conexión SSH en línea de comandos, pero como ya mencioné quería usar el sistema completo; para habilitar VNC, debes ir a las preferencias de Raspberry Pi:

Una vez que pude acceder remotamente era hora de configurar el ambiente, lo primero que hice fue actualizar el sistema para esto deberán hacer:

 sudo apt-get update

Algunas guías les dirán que adicionalmente hagan un upgrade del sistema, yo no lo hice debido a un problema entre wiringpi y la versión de Raspbian, estoy seguro que más adelante va a ser corregido, pero por el momento el update bastará, ahora es necesario instalar npm, realmente me sorprendió que no formara parte de la distribución, afortunadamente la instalación es muy sencilla.

 sudo apt-get install npm

La parte más importante para mí era poder depurar mi código directamente en Raspberry Pi, para lograr esto necesitaba utilizar un folder compartido; es momento de instalar y configurar samba para poder compartir archivos entre Windows y Raspbian, basándome en la siguiente guía, procedí a instalar y configurar el servicio de la siguiente forma:

 sudo apt-get install samba samba-common-bin
sudo mkdir -m 1777 /iot

La configuración de mi share es prácticamente idéntica a la mostrada en la guía:

 [iot]
Comment = IoT development folder
Path = /iot
Browseable = yes
Writeable = Yes
only guest = no
create mask = 0777
directory mask = 0777
Public = yes
Guest ok = yes

Dado que mi Raspberry no estará expuesta (de hecho está apagado la mayor parte del tiempo), no establecí una contraseña para samba, simplemente utilizaré acceso anónimo que ya tiene todos los permisos necesarios, ahora es necesario que Windows empiece a hablar con Raspbian, al principio pensé utilizar rutas UNC, pero pronto me di cuenta que npm no soporta rutas UNC para realizar instalaciones, la forma fácil de solventar esto es utilizar una unidad de red, abrimos una línea de comando de Windows como administrador y vamos a mapear la unidad, aprovecharé para crear una estructura de directorios básica:

 net use L: \\{dirección ip}\iot /persistent:yes
L:
md projects
md common

Ahora será necesario configurar Visual Studio Code, basta con iniciarlo y desde el menú File acceden a la opción Open Folder navegan a la unidad de red y deberán crear una nueva carpeta dentro de projects, yo decidí llamarla testprj, seleccionan el folder; una vez seleccionado, podemos agregar un nuevo archivo, en mi ejemplo este archivo es app.js y a continuación acceden a la terminal integrada (View -> Integrated Terminal), acá procedemos a configurar nuestra aplicación:

 rpm init

El asistente los guiará con preguntas y esto construirá el archivo package.json, este paso es opcional pero ayuda a reducir los warnings, si no están seguros de alguna de las preguntas pueden dejarla en blanco o simplemente aceptar la sugerencia; finalmente agregué código a mi aplicación:

 'use strict'

var wpi = require('wiring-pi');
wpi.setup('wpi');
wpi.pinMode(1, wpi.OUTPUT);
wpi.digitalWrite(1, 1);
   setTimeout(function () {
   wpi.digitalWrite(1, 0);
}, 500);

La aplicación está casi lista del lado de Code, pero aun se debe agregar la referencia a wiring-pi, normalmente ustedes podrán hacer esto desde la consola integrada, pero esta referencia tiene una dependencia nativa que sólo puede ser satisfecha desde Raspbian, pasamos a nuestro cliente VNC, abrimos una consola y empezamos a trabajar, no sólo agregaremos la dependencia, adicionalmente prepararemos el ambiente para la depuración remota:

 cd /iot/common
wget https://raw.githubusercontent.com/Microsoft/nodejstools/master/Nodejs/Product/Nodejs/Debugger/RemoteDebug/RemoteDebug.js
cd /iot/projects/testprj
npm install wiring-pi
cd /iot

Finalmente escriban el siguiente comando pero no lo ejecuten, sólo manténgalo listo.

 sudo node ./common/RemoteDebug.js -breakatentrypoint ./projects/testprj/app.js

Ha llegado la hora de armar el circuito, que en este caso es un simple LED que voy a encender y apagar, acá pueden ver el diagrama:

Regresando a Code, accedemos al área de depuración, en la parte superior hay una caja de selección, la abrimos y seleccionamos la opción Add Configuration... y luego  {} Node.js: Attach, estableciendo los siguiente valores:

  {
 "type": "node",
 "request": "attach",
 "name": "Attach to RPI",
 "port": 5858,
 "address": "{dirección ip}",
 "remoteRoot": "/iot/projects/testprj",
 "localRoot": "${workspaceRoot}"
 },

Deben tener en cuenta que si la dirección ip del Raspberry cambia va a impactar el ambiente, para evitar esto pueden asignar una dirección estática al dispositivo, yo preferí reservar una dirección para la mac address directamente en mi router. Nuestro ambiente finalmente está listo, ahora podemos poner un punto de interrupción en nuestro código, iniciar la depuración en Visual Studio Code e inmediatamente después ejecutar el comando que tenemos preparado en la consola de Raspbian, podrán ver que el programa se detiene en el punto de interrupción, las variables locales y la pila de llamada son mostradas en el depurador y adicionalmente podemos definir expresiones en la ventana de Watch para ver el estado de la memoria en nuestro Raspberry Pi:

Un tip adicional: si tienen dudas sobre los pines del Raspberry Pi y cual es GPIO al cual se mapean, pueden utilizar la herramienta de línea de comandos gpio que es instalada con wiring-pi, el siguiente comando les desplegará una tabla con el pinout mostrando el pin físico, el nombre, el modo (IN/OUT), valor actual, etc.; es muy útil si no están familiarizados con los pines.

 sudo /iot/projects/testprj/node_modules/wiring-pi/wiringpi/gpio/gpio readall

Hasta la próxima!
--Rp