Archivo

Entradas Etiquetadas ‘subir’

Preparando nuestro entorno para Arduino sin Java

Miércoles, 3 de Agosto de 2011 Gaspar Fernández 2 comentarios

Arduino Emacs

Como comenté en el post anterior, la plataforma Arduino viene con un IDE hecho en Java, no es muy completo, pero nos hace el apaño, aunque, como es mi caso, estoy acostumbrado a Emacs. Aunque esta guía no estará limitada a este editor, ni a Ubuntu (o basados en él).

El objetivo, es usar nuestro IDE o editor preferido para trabajar con estos pequeños bichos programables.

En principio tenemos que instalar las herramientas para compilar los programas para la plataforma (esto es común con todas las instalaciones). Los Arduino utilizan chips Atmel AVR, por lo que usaremos el compilador AVR-GCC para esta plataforma. Como construir el ejecutable es un proceso más o menos costoso (de hacer a mano) utilizaremos la herramienta de construcción scons con la que podremos generar el ejecutable gracias a un script en python.

Ubuntu y derivados (en mi caso Linux Mint)

Lo primero es instalar los programas necesarios:

$ sudo apt-get install gcc-avr avr-libc scons avrdude python-serial

En este caso:

  1. gcc-avr: Es el compilador
  2. avr-libc: Son las librerías para la plataforma
  3. scons: La herramienta de construcción
  4. avrdude: Utilidad para programar chips avr
  5. python-serial: Es un módulo de python para trabajar con el puerto serie (nos servirá para subir los programas al Arduino).

Sabayon Linux / Gentoo también

Ya que recientemente he instalado Sabayon en mi ordenador, quisiera extender esto un poco más:
En este caso, tendremos que instalar, ya sea vía Entropy (forma gráfica) o equo (en consola) los paquetes crossdev, scons y pyserial:

$ equo install crossdev scons avrdude pyserial
$emerge crossdev scons avrdude pyserial # Sólo para Gentoo

Tras ello tenemos que descargar y construir las bibliotecas y el entorno para compilar para AVR:

$ USE=”-openmp” crossdev -t avr -s4 -S –without-headers

(y esto tardará un rato)

Parte común y manual

Tras ello, descargamos la plataforma de aquí [ 64bit , 32bit versión 0022, última a 31 de Julio de 2011 (web de descarga con más opciones) ], por ahora bien podíamos estar instalando la plataforma completa, ya que el archivo que hemos descargado contiene el IDE Arduino. Ahora introduciremos una variación.

Debemos descomprimir el archivo que hemos descargado, yo he creado un directorio en mi home: /home/gaspy/proyectos/Arduino:

$ mkdir -p ~/proyectos/Arduino
$ cd ~/proyectos/Arduino
$ tar xvzf arduino-0022.tgz

Luego, debemos descargar el arma secreta, es un script de construcción para scons y Arduino. Podemos encontrarlo en la página oficial del proyecto arscons. Lo podéis descargar de aquí:

Este archivo tiene que estar en el directorio de cada proyecto. Nuestro primer proyecto será ej1

$ mkdir ej1
$ wget http://arscons.googlecode.com/svn/trunk/SConstruct

Antes de continuar debemos hacer alguna modificación de rutas en el archivo SConstruct, por lo que es una buena idea dejar un archivo SConstruct operativo y copiarlo dentro de nuestros proyectos. Las modificaciones serían para las variables:

  • ARDUINO_HOME_DEFAULT, que debe contener el directorio donde estan instaladas las herramientas de Arduino, lo que acabamos de descomprimir. En mi caso /home/gaspy/proyectos/Arduino/arduino-0022/
  • ARDUINO_BOARD, debe ser el modelo de nuestra placa.
  • ARDUINO_CONF, nos dice dónde está la configuración de las placas Arduino, donde buscará las especificaciones de la nuestra.

Vemos aquí la modificación de las variables en su contexto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
if platform == 'darwin':
# For MacOS X, pick up the AVR tools from within Arduino.app
ARDUINO_HOME_DEFAULT = '/home/gaspy/proyectos/Arduino/arduino-0022/'
ARDUINO_PORT_DEFAULT = getUsbTty('/dev/tty.usbserial*')
elif platform == 'winnt':
# TODO: add Windows port.
assert(False) # not supported.. yet.
ARDUINO_HOME_DEFAULT = None
ARDUINO_PORT_DEFAULT = None
else:
# For Ubuntu Linux (9.10 or higher)
####################### ESTA ES LA LÍNEA IMPORTANTE
ARDUINO_HOME_DEFAULT = '/home/gaspy/proyectos/Arduino/arduino-0022/'
####################### FIN DE LA LÍNEA IMPORTANTE
ARDUINO_PORT_DEFAULT = getUsbTty('/dev/ttyUSB*')
AVR_BIN_PREFIX = 'avr-'

ARDUINO_HOME    = ARGUMENTS.get('ARDUINO_HOME', ARDUINO_HOME_DEFAULT)
ARDUINO_PORT    = ARGUMENTS.get('ARDUINO_PORT', ARDUINO_PORT_DEFAULT)
####################### OTRA LÍNEA IMPORTANTE
ARDUINO_BOARD   = ARGUMENTS.get('ARDUINO_BOARD', 'diecimila')
####################### FIN DE OTRA LÍNEA IMPORTANTE
ARDUINO_VER     = ARGUMENTS.get('ARDUINO_VER', 20) # Arduino 0020
RST_TRIGGER     = ARGUMENTS.get('RST_TRIGGER', None) # use built-in pulseDTR() by default
EXTRA_LIB       = ARGUMENTS.get('EXTRA_LIB', None) # handy for adding another arduino-lib dir

ARDUINO_CORE    = pathJoin(ARDUINO_HOME, 'hardware/arduino/cores/arduino')
ARDUINO_SKEL    = pathJoin(ARDUINO_CORE, 'main.cpp')
####################### OTRA LÍNEA IMPORTANTE
ARDUINO_CONF    = pathJoin(ARDUINO_HOME, '/home/gaspy/proyectos/Arduino/arduino-0022/hardware/arduino/boards.txt')
####################### FIN DE OTRA LÍNEA IMPORTANTE

Dentro del directorio ej1 (de nuestro primer proyecto con Arduino) tiene que haber un archivo llamado ej1.pde que contendrá el código fuente del programa que queremos compilar y subir a nuestro Arduino. ¡ A trabajar ! Podemos coger este código de ejemplo para hacer que un led parpadee. Sólo copiar y pegar.

NOTA para Gentoo/Sabayon: Hay algún pequeño bug en esta distribución y al compilar no funcionará porque no existen los ficheros de biblioteca, el caso es que sí existen, pero no los encuentra. Para eso, modificaremos algunas líneas más de SConstruct:

1
2
3
4
5
6
7
8
9
10
11
envArduino.Append(BUILDERS = {'Processing':Builder(action = fnProcessing,
        suffix = '.cpp', src_suffix = '.pde')})
######## IMPORTANTE, LE PONEMOS LA RUTA DONDE TIENE QUE BUSCAR avr5.x
envArduino.Append(BUILDERS={'Elf':Builder(action=AVR_BIN_PREFIX+'gcc '+
        '-Wl,-dT /usr/lib/binutils/avr/2.20.1/ldscripts/avr5.x -mmcu=%s -Os -Wl,--gc-sections -o $TARGET $SOURCES -lm'%MCU)})
######## IMPORTANTE, LE PONEMOS LA RUTA DONDE TIENE QUE BUSCAR avr5.x
envArduino.Append(BUILDERS={'Hex':Builder(action=AVR_BIN_PREFIX+'objcopy '+
        '-O ihex -R .eeprom $SOURCES $TARGET')})

# add arduino core sources
VariantDir('build/core', ARDUINO_CORE)

También falla otra cosa, no se encuentra el archivo crtm168.o (mi placa Diecimila, este es el chip que usa), el archivo está en /usr/avr/lib/avr5/crtm168.o , pero lo busca en /usr/avr/lib/ podemos copiarlo como root, hacer un enlace,

root$ ln -s /usr/avr/lib/avr5/crtm168.o /usr/avr/lib/

o copiarlo como usuario en el directorio del proyecto, total, son 2Kb.

Para compilar el proyecto debemos, en el mismo directorio actual, ejecutar:

$ scons

y él se encarga de todo. Cuando estemos listos para subir al Arduino, lo conectamos y ejecutamos:

$ scons upload

Lo realmente bueno de esto es que podemos utilizar el editor o IDE que queramos, incluso podemos asignar una tecla rápida para compilar+subir

Mejoras para Emacs

Si utilizas Emacs, te interesará introducir lo siguiente en tu ~/.emacs :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(defun run-scons ()
  "run scons"
  (interactive)
  (shell-command "scons"))

(defun run-scons-upload ()
  "run scons upload"
  (interactive)
  (shell-command "scons upload"))

; Ejecuta scons y scons upload con C-x SPC y C-x C-SPC
(global-set-key (kbd "C-x SPC") 'run-scons)
(global-set-key (kbd "C-x C-SPC") 'run-scons-upload)

; Asigna la extensión .pde al modo c++-mode
(setq auto-mode-alist (cons '("\\.pde$" . c++-mode) auto-mode-alist))

Aunque hay formas más elegantes de hacerlo, esta es la forma más rápida de asignar una tecla a scons; puede que utilicemos make para otras y no queramos modificar nuestro constructor. Otra cosa, las teclas elegidas no son las mejores, tengo que perfeccionar esto.

Por otra parte, es importante que los archivos .pde se abran directamente con el modo c++ y así podemos aprovechar sus ventajas.

Otros editores

Si usáis kate, podéis mirar este artículo para coger inspiración.
Si usáis gedit, podéis leer esto. (fuera de Poesía Binaria).

Script para subir archivos rápidamente (y actualizarlos)

Jueves, 13 de Agosto de 2009 Gaspar Fernández 2 comentarios

Normalmente, cuando estoy desarrollando aplicaciones para Facebook, primero, las hago Offline, ejecutándolas en mi servidor local y, una vez que funcionan, las subo al servidor desde las que se ejecutarán, aunque muchas veces hay ciertos problemas una vez se está ejecutando la aplicación de forma definitiva, que requieren hacer algunas modificaciones más, y con esto, subir varias veces los archivos de los scripts.

Por otra parte, a veces, en ciertas aplicaciones web, es necesario introducir cierta información nueva (que hago fuera de línea) y cuando todas las novedades han sido introducidas procedo a subirlo todo junto.

También es importante, sobre todo para proyectos más o menos grandes, que sólo se suban al servidor los archivos nuevos o modificados antes de la última actualización, es muy importante, ya que la ejecución puede eternizarse si tenemos que subir 10Mb de datos cada vez que queremos actualizar, por lo tanto, almacenamos en un archivo el momento en que se ejecutó el script por última vez, y cada vez que buscamos archivos, lo hacemos con los que han sido actualizados a partir del momento que almacenamos en el fichero anterior.

Para eso creé este script (aún queda mucho trabajo por hacer), pero por ahora hace bastante bien el apaño. Yo llamo a este archivo (autoftp):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/bash

servidor=$1
ruta_serv=$2
ruta_local=$3
endline="
"

dir_actual=`pwd`
cd $3

if [ -e $ruta_local"/last_update" ]; then
    f_locales=`find . -newer $ruta_local/last_update`
else
    f_locales=`find .`
fi

function cierratodo()
{
    kill $ftp_pid
    kdialog --msgbox $1
}

function estadoman()
{
    while read estado
    do
        estadonum=`echo $estado | cut -d' ' -f1`
        echo $estado
        if [[ $estado != "Not connected" ]]; then
            if [[ $estadonum == "226" ]]; then
                subidos=$(($subidos+1))
                kdialog --passivepopup "Subido archivo "$subidos" de "$total_archivos 2
            elif [[ $estadonum == "221" ]]; then
                cierratodo "Los archivos se subieron con éxito"
                date +%s > $ruta_local"/last_update"
            # Fin del programa
               
            fi
        else
            echo "Cerrandooo"
            cierratodo "La conexión se cerró inesperadamente"
        fi
    done
}

to_do="pass"$endline"cd $ruta_serv"$endline;
last_dir="";
total_archivos=0
for i in $f_locales
do
        arch_relat=${i:2}
        if [ ! -z $arch_relat ]; then
            nombre_dir=`dirname $arch_relat`
            if [[ $nombre_dir == "." ]]; then
                nombre_dir=""
            fi
                if [ -d $arch_relat ]; then
                    to_do=$to_do"cd $ruta_serv/$nombre_dir"$endline
                    to_do=$to_do"mkdir $ruta_serv/$arch_relat"$endline
                else
#                   echo "*"$nombre_dir"="$last_dir"*";
                    if [[ $last_dir != $nombre_dir ]]; then
                        last_dir=$nombre_dir
                        to_do=$to_do"cd $ruta_serv/$nombre_dir"$endline
                    fi

                    to_do=$to_do"put $ruta_local/$arch_relat "`basename $arch_relat`$endline
                    total_archivos=$(($total_archivos+1))
#                     to_do=$to_do"put $3/$arch_relat\n"
                   echo "FICHERO --- $arch_relat";
                fi
        fi
done

OLDIFS=$IFS
IFS="
"

to_do=$to_do"quit"$endline

if [[ $total_archivos > 0 ]]; then
    for j in $to_do ; do echo $j;done;

    rm /tmp/ftp_pipe > /dev/null 2>&1
    mkfifo /tmp/ftp_pipe > /dev/null 2>&1

ftp -v totaki.com > /tmp/ftp_pipe <<EOF &
`for j in $to_do ; do echo $j;done;`
EOF

    ftp_pid=$!

else
    kdialog --msgbox "No hay archivos para subir"
fi
cd $dir_actual
IFS=$OLDIFS

rm /tmp/ftp_pipe > /dev/null 2>&1

Para su uso, son necesarios tres parámetros:

  • Dirección del servidor
  • Ruta donde se colocan los archivos en el directorio remoto
  • Ruta de donde se buscarán los archivos en el directorio local

Requerimientos:

  • kdialog (Se puede modificar el script para utilizar otro fácilmente)
  • ftp (Este programa se encargará de subir los archivos)

Para configurar el script es necesario editar el archivo .netrc localizado en nuestro home y donde irá el nombre de usuario y contraseña del FTP (este fichero es leído por ftp automáticamente y así no necesitamos incluir passwords ni en la línea de comando ni en el propio script, que quedan muy feos). El fichero .netrc tiene la siguiente estructura:

machine [servidor] login [usuario] password [contraseña]

Por ejemplo podemos hacer un .netrc que contenga:

machine www.servidor.com login pepito password josefina

Una vez completado esto, podemos asociar una tecla al script, y con ello simplemente pulsando esa tecla se subirán los archivos al servidor.
Por último, yo lo tengo configurado en Fluxbox con Mod4+F5 o lo que es lo mismo la tecla de Windows y F5; basta con crear un script lanzador que incluya lo siguiente (yo lo llamo ftp_upload):

1
2
3
4
#!/bin/bash
# Modelo
#/home/gaspy/.scripts/autoftp [servidor] [ruta interna] [ruta_local]
#/home/gaspy/.scripts/autoftp ftp.servidor.com http_docs/pruebas /home/yomismo/proyectos/pruebas

añadir al fichero keys dentro de /home/[usuario]/.fluxbox/ la siguiente línea:

Mod4 F5 :execcommand ~/.scripts/ftp_upload

Visita otras webs de la red