Sviluppare codice per Arduino dalla command line

arduino_uno

arduino_unoArduino Uno è un micro controllore basato su CPU ATmega328; si alimenta via alimentatore esterno o via USB ed ha a bordo 2KB di SRAM, 32KB di flash, una EEPROM da 1KB, 14 GPIO (di cui 6 possono funzionare come PWM) e 6 ingressi analogici. Insomma, tutto quello che ci serve se vogliamo giocare un po’!

In questo articolo, oltre a presentarvi il prodotto, vi farò vedere come si possa agilmente sviluppare software per Arduino direttamente dalla command line di un sistema GNU/Linux (Ubuntu nello specifico), cioè senza per forza utilizzare l’ambiente grafico (basato su JAVA) che viene fornito dal produttore.

Sian ben chiaro, la GUI del produttore va benissimo, ma è innegabile che la command line sia molto più versatile, una voilta che la si sa usare, di qualsiasi ambiente grafico.

Prima di tutto vediamo però di installare il sistema e i tool di sviluppo che ci vengono forniti dal produttore; questo per essere sicuri che il nostro Arduino funzioni correttamente.

Installare la GUI grafica

Prima di tutto occorre scaricarsi il software. Dal sito di Arduino ho scaricato il file arduino-0022.tgz (naturalmente questa a la versione della GUI per Linux 32bit, se usate un altro sistema dovete scaricare il software corrispondente), quindi l’ho esploso:

$ tar xvfz arduino-0022.tgz
$ cd arduino-0022
$ ls
arduino*   hardware/  libraries/  revisions.txt
examples/  lib/       reference/  tools/

A questo punto ho installato nel mio sistema i pacchetti necessari per far funzionare il tutto:

# aptitude install sun-java6-jdk gcc-avr avr-libc

quindi con il comando ./arduino ottengo:

arduino-uno-ss01

Da qui in poi è semplice, per provare Arduino basta andare nel menu Tools->Board e selezionare la voce Arduino Uno. Per quanto riguarda invece la porta di comunicazione da utilizzare per parlare con il dispositivo ho impostato in Tools->Serial Port la voce /dev/ttyACM0 poiché alla voce /dev/ttyUSB0 ho già un’altro dispositivo seriale.

Tutto qui! Per provare il nostro nuovo Arduino basta scegliere un programma di esempio ed inviarlo alla scheda. Io ho scelto di provare il programma Blink (che accende e spegne un led della scheda ad intervalli regolari) poiché è quello più semplice da utilizzare quando non si hanno periferiche aggiuntive e/o strumenti di misura speciali (come ad esempio un oscilloscopio) con cui testare il programma.

Per provare Blink ho selezionato in File->Examples->Basics la voce Blink ottenendo una nuova finestra come riportato in figura:

arduino-uno-ss02

Giusto per modificare un po’ l’esempio ho cambiato i valori della funzione delay() a 500 e 3000 in modo da tenere acceso il led per mezzo secondo e quindi spento per 3 secondi. Quindi ho cliccato sul pulsante Upload… et voilà, Arduino fa lampeggiare il led proprio come gli ho chiesto io!

Ok, ora abbiamo verificato che la scheda funziona, vediamo ora come la si può programmare in modo analogo dalla command line.

Programmazione dalla command line

Per proseguire dobbiamo installarci il programma scons (un tool simile a make per la compilazione – e non solo) e poi scaricare questo file.

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

Il file SConstruct fa un po’ le veci del Makefile con make: contiene le istruzioni che scons deve seguire per compilare il programma.

Una volta scaricato il file occorre adattarlo al sistema su cu ideve girare per far sì che funzioni correttamente; quindi, nel mio caso, l’ho modificato come segue:

$ diff -u SConstruct.orig  SConstruct
— SConstruct.orig  2010-10-19 07:29:29.000000000 +0200
+++ SConstruct.      2011-03-13 19:41:18.000000000 +0100
@@ -64,14 +64,14 @@
 ARDUINO_PORT_DEFAULT = None
 else:
 # For Ubuntu Linux (9.10 or higher)
–    ARDUINO_HOME_DEFAULT = ‘/usr/share/arduino/’ #’/home/YOU/apps/arduino-0018/’
–    ARDUINO_PORT_DEFAULT = getUsbTty(‘/dev/ttyUSB*’)
+    ARDUINO_HOME_DEFAULT = ‘/home/develop/embedded/arm/boards/arduino/arduino-0022’
+    ARDUINO_PORT_DEFAULT = getUsbTty(‘/dev/ttyACM*’)
 AVR_BIN_PREFIX = ‘avr-‘

 ARDUINO_HOME   = ARGUMENTS.get(‘ARDUINO_HOME’, ARDUINO_HOME_DEFAULT)
 ARDUINO_PORT   = ARGUMENTS.get(‘ARDUINO_PORT’, ARDUINO_PORT_DEFAULT)
-ARDUINO_BOARD  = ARGUMENTS.get(‘ARDUINO_BOARD’, ‘atmega328’)
-ARDUINO_VER    = ARGUMENTS.get(‘ARDUINO_VER’, 20) # Arduino 0020
+ARDUINO_BOARD  = ARGUMENTS.get(‘ARDUINO_BOARD’, ‘uno’)
+ARDUINO_VER    = ARGUMENTS.get(‘ARDUINO_VER’, 22) # Arduino 0022
 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

Ovviamente voi dovrete modificarlo in modo acconcio al vostro sistema.

Una volta fatte anche queste modifiche ho installato scons semplicemente con:

# aptitude install scons

Abbiamo poi anche bisogno dell’utility avrdude, un tool che trasferisce il programma che abbiamo scritto per Arduino all’interno della memoria della macchina. Anche questo lo installiamo allo stesso modo di scons.

Ora basta prendere i sorgenti di Blink (per semplicità li copio in una directory ad hoc) dalla directory arduino-0022 creata prima:

$ cp -a ../arduino-0022/examples/1.Basics/Blink .

copiarci il file SConstruct modificato prima:

$ cp SConstruct Blink/

e quindi entrare nella directory Blink:

$ cd Blink

ed eseguire il comando:

$ scons upload

Se alla fine ottenete il messaggio:

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

scons: done building targets.

allora il vostro Arduino è stato riprogrammato con il nuovo software!

Se per caso però, ottenete questo messaggio di errore:

pulseDTR([“upload”], [“Blink.hex”])
avrdude -V -F -c stk500 -b 115200 -p atmega328p -P /dev/ttyACM0 -U flash:w:Blink.hex
avrdude: stk500_2_ReceiveMessage(): timeout

interrompete l’operazione e provate a modificare il file arduino-0022/hardware/arduino/boards.txt (del pacchetto software scaricato prima) come segue:

diff -ur arduino-0022.orig/hardware/arduino/boards.txt arduino-0022/hardware/arduino/boards.txt
— arduino-0022.orig/hardware/arduino/boards.txt    2010-12-24 23:12:25.000000000 +0100
+++ arduino-0022/hardware/arduino/boards.txt         2011-03-13 19:42:12.000000000 +0100
@@ -1,7 +1,7 @@
 ##############################################################

 uno.name=Arduino Uno
-uno.upload.protocol=stk500
+uno.upload.protocol=stk500v1
 uno.upload.maximum_size=32256
 uno.upload.speed=115200
 uno.bootloader.low_fuses=0xff

e quindi ridate il comando; ora dovrebbe andare tutto liscio.

E’ interessante notare come, utilizzando questa tecnica, si scoprano alcuni «segreti» del processo di compilazione che prima, utilizzando la GUI, ci erano nascosti. Si vedono infatti i comandi di compilazione (ne riporto solo uno per brevità):

avr-gcc -mmcu=atmega328p -Os -Wl,–gc-sections -o Blink.elf build/Blink.o build/core/wiring_digital.o build/core/wiring_pulse.o build/core/wiring_analog.o build/core/wiring_shift.o build/core/WInterrupts.o build/core/wiring.o build/core/pins_arduino.o build/core/Tone.o build/core/Print.o build/core/WString.o build/core/WMath.o build/core/HardwareSerial.o -lm

il comando che crea il file in formato HEX da passare ad avrdude:

avr-objcopy -O ihex -R .eeprom Blink.elf Blink.hex

ed il comando avrdude per trasferire il programma appena compilato:

avrdude -V -F -c stk500v1 -b 115200 -p atmega328p -P /dev/ttyACM0 -U flash:w:Blink.hex

Altra cosa che apprendiamo è che, per compilare un programma pde (estensione dei programmi di esempio di Arduino) in realtà vengono usati altri file di codice sorgente che costituiscono l’equivalente di quello che, per i normali programmi per PC, è la libc. Possiamo avere un’idea di cosa sono e cosa fanno questi programmi guardando il contenuto della directory build che scons ci aggiunge nella directory di lavoro prima della compilazione vera e propria:

$ tree build/
build/
|– Blink.cpp
|– Blink.o
|– Blink.pde
`– core
|– HardwareSerial.cpp
|– HardwareSerial.h
|– HardwareSerial.o
|– Print.cpp
|– Print.h
|– Print.o
|– Stream.h
|– Tone.cpp
|– Tone.o
|– WCharacter.h
|– WConstants.h
|– WInterrupts.c
|– WInterrupts.o
|– WMath.cpp
|– WMath.o
|– WProgram.h
|– WString.cpp
|– WString.h
|– WString.o
|– binary.h
|– pins_arduino.c
|– pins_arduino.h
|– pins_arduino.o
|– wiring.c
|– wiring.h
|– wiring.o
|– wiring_analog.c
|– wiring_analog.o
|– wiring_digital.c
|– wiring_digital.o
|– wiring_private.h
|– wiring_pulse.c
|– wiring_pulse.o
|– wiring_shift.c
`– wiring_shift.o

1 directory, 38 files

Su Rodolfo Giometti

Ingegnere informatico libero professionista ed esperto GNU/Linux offre supporto per: - device drivers; - sistemi embedded; - sviluppo applicazioni industriali per controllo automatico e monitoraggio remoto; - corsi di formazione dedicati. Manutentore del progetto LinuxPPS (il sottosistema Pulse Per Second di Linux) contribuisce attivamente allo sviluppo del kernel Linux con diverse patch riguardanti varie applicazioni del kernel e dispositivi (switch, fisici di rete, RTC, USB, I2C, network, ecc.). Nei 15+ anni di esperienza su Linux ha lavorato con le piattaforme x86, ARM, MIPS & PowerPC.

Lascia un commento

Utilizzando il sito, accetti l'utilizzo dei cookie da parte nostra. maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi