PrettyPrint

lunedì 15 febbraio 2010

LM35+LCD+web+MySQL - 7) Visualizzazione in tempo reale;problemi noti

In ultimo ci rimane da creare una pagina web in PHP che ci visualizzi la temperatura in tempo reale e il grafico generato da plotter.

Ogni qualvolta si apre la pagina web temp.php, viene richiamata la funzione fetchTemp() precedentemente vista, che stampa la temperatura misurata in quel momento.

Comunque ogni 30sec. viene forzato il refresh della pagina e quindi viene rieseguita una nuova lettura.

Infine, lo script plotter.php viene richiamato nella pagina come immagine e il risultato è quello di visualizzare il grafico con temperature rilevate nelle ultime 24hh

TEMP.PHP



<?
require_once('fetcher.php')
/*************************************************************************************************
*
* Motivazione: visualizza a ogni refresh della pagina (e comunque in automatico ogni 30 secondi)
* il valore attuale di temperatura acquisito da Arduino.
* Inoltre, richiama plotter per creare un grafico con temperature delle ultime 24hh
*
* Autore : Francesco Parisi (fparisi at tiscali dot it) , (fparisi at gmail dot com)
*
* Richiede : fetcher.php
*
*************************************************************************************************/
?>

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Refresh" content="30; url="temp.php">
<title>Termometro Web</title>
</head>

<body>
<h1 align="center">Termometro Web</h1>
<center><table border="1" cellpadding="10" cellspacing="10" bgcolor="black">
<tr><td><font color="#00ff00" size="5"><b>

<?php echo fetchTemp() ?>
&nbsp;&deg;C

</font></b>
</td></tr></table></center>

<br><br><br><br>

<p align="center">
<img src="plotter.php" border=0>
</p>

<br clear="all">

<i>Autore: Francesco Parisi<br>Versione: 1.5, U.R. 03-Feb-2010</i>

</body>

</html>





Il risultato nel browser è il seguente (click sopra per ingrandire):







PROBLEMI NOTI


Se durante la fase dell'upload dello sketch avviene anche la richiesta della temperatura (a mezzo di fetcher) il flusso seriale va in stallo...lo script perl non riesce a disimpegnare le risorse allocate; ciò produce un consumo delle risorse pari al 100% da parte del relativo processo e l'unico modo è killarlo da shell.

Dall'altro lato non si riesce a caricare su Arduino lo sketch ottenendo degli errori da parte di avrdude.

Quindi l'unico modo per evitare questo è cercare di non rimanere aperta nel browser la pagina temp.php (o comunque metterla off-line, insieme allo script logger) durante i momenti di upgrade del firmware di Arduino.

Buon divertimento

LM35+LCD+web+MySQL - 6) Plotter

Per la creazione del grafico si è usata la libreria JpGraph (http://www.aditus.nu/jpgraph/) che consente di produrre grafici in PHP in modo molto semplice e flessibile.

Su Ubuntu la libreria si installa comodamente da riga di comando:

$ sudo apt-get install libphp-jpgraph


tutti i file della libreria vengono così installati nella directory /usr/share/jpgraph/


PLOTTER.PHP




<?php
/*************************************************************************************************
*
* Motivazione: costruisce un grafico con temperature rilevate nelle ultime 24hh
*
* Autore : Francesco Parisi (fparisi at tiscali dot it) , (fparisi at gmail dot com)
*
* Richiede : db.php, jpgraph.php, jpgraph_line.php
*
*************************************************************************************************/

require_once ('/usr/share/jpgraph/jpgraph.php');
require_once ('/usr/share/jpgraph/jpgraph_line.php');
require_once ('db.php');


// Apre la connessione al server
$conn = mysql_connect( $host, $user, $pass )
or die('Impossibile connettersi al server: ' . mysql_error());


// Seleziona il database
$sel = mysql_select_db( $dbname, $conn )
or die('Impossibile selezionare il database: ' . mysql_error());

// Temperature ultime 24hh
$sql_last_24hh = 'SELECT * FROM `log` WHERE `time` >= NOW() - INTERVAL 1 DAY';
$res = mysql_query( $sql_last_24hh )
or die('Impossibile eseguire query: ' . mysql_error());

// Formatta il timestamp e costruisce gli assi per il grafico
if ( $row = mysql_fetch_assoc($res) or die(mysql_error()) )
{
do
{
// Converte il timestamp MySQL in timestamp PHP
$timestamp = strtotime($row['time']);

// Costruisce il vettore degli orari (asse x)
$x[] = sprintf("%s, %s", date ('j/n', $timestamp), date ('H:i', $timestamp) );

// Costruisce il vettore delle temperature (asse y)
$y[] = $row['temp_int'];

} while ( $row=mysql_fetch_assoc($res) );
}

// Crea il grafico
$graph = new Graph(1024, 800,"auto");
$graph->SetScale( "textlin");
$graph->img-> SetMargin(60,40,40,110);
$graph->title->Set( 'Temperature rilevate nelle ultime 24hh');
$graph->title->SetFont( FF_FONT2, FS_BOLD );
$graph->xaxis->SetTickLabels( $x );
$graph->xgrid->Show(true);
$graph->xaxis->SetLabelAngle(90);
$graph->SetShadow();

// Crea il plot
$lineplot = new LinePlot( $y );
$lineplot->value->Show();
$lineplot->SetColor("blue");
$lineplot->SetWeight(2); // Two pixel wide
$lineplot->value->SetColor("darkred");
$lineplot->value->SetFormat( "%0.1f");
//$lineplot->mark ->SetType(MARK_FILLEDCIRCLE);

// Aggiunge il plot al grafico
$graph->Add( $lineplot );

// Mostra il grafico
$graph->Stroke();

// Chiude connessione
mysql_close( $conn )
or die('Impossibile chiudere connessione: ' . mysql_error());
?>



Ecco un esempio di grafico generato (click sopra per ingrandire), che verrà poi richiamato nella pagina web:

LM35+LCD+web+MySQL - 5) Logger,mysql e cron

logger è lo script incaricato di leggere la temperatura (mediante fetcher) e inserirla nel server MySQL. Questo script viene lanciato in automatico da cron ogni mezz'ora.

Quindi si crea prima la il database con la tabella sql, poi lo script e infine si configura cron.

Il codice sql per creare il database e la tabella che conterrà orario e temperatura interna sarà:
LOG.SQL

CREATE DATABASE `temperature` ;

CREATE TABLE `temperature`.`log` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`temp_int` FLOAT NOT NULL
) ENGINE = MYISAM ;

Lo script logger.php va salvato in una directory diversa da quella html pubblica proprio perché non deve essere richiamabile via web.

Personalmente li ho salvati nella cartella utente /home/frank ma si potrebbe pensare anche alla directory /usr/local/bin:

LOGGER.PHP


<?
/*************************************************************************************************
*
* Motivazione: memorizza in un database MySQL il valore di temperatura acquisito da Arduino.
*
* Autore : Francesco Parisi (fparisi at tiscali dot it) , (fparisi at gmail dot com)
*
* Richiede : db.php, fetcher.php
*
*************************************************************************************************/

require_once('fetcher.php');
require_once('db.php');

// Apre la connessione al server
$conn = mysql_connect( $host, $user, $pass )
or die('Impossibile connettersi al server: ' . mysql_error());

// Seleziona il database
$sel = mysql_select_db( $dbname, $conn )
or die('Impossibile selezionare il database: ' . mysql_error());

// Legge da Arduino la temperatura
$temperature = fetchTemp();

// Query di inserimento
$sql=("INSERT INTO `log` (`id` ,`time` ,`temp_int`)
VALUES (NULL, NULL, ". $temperature .")");

// Esegue la query
$res = mysql_query( $sql )
or die('Impossibile eseguire query: ' . mysql_error());


// Chiude connessione
mysql_close( $conn )
or die('Impossibile chiudere connessione: ' . mysql_error());


?>



Nel file logger.php viene incluso un file db.php, che contiene i dati di accesso al server MySQL. Sostituire con i propri parametri:

DB.PHP



<?php
$host = 'localhost';
$dbname = 'temperature';
$user = 'root';
$pass = 'tua_password_qui';
?>







Infine, si configurerà cron per lanciare il comando:

php /home/frank/logger.php > /dev/null 2>&1


ogni mezz'ora.

Da shell, lanciare

$ crontab -e


Apparirà l'editor di cron per l'utente corrente. Aggiungere la seguente riga:

*/30 * * * * php /home/frank/logger.php # logga temperatura


Salvare il file e uscire dall'editor testo

Assicurarsi che il compito sia stato correttamente inserito:


$ crontab -l


Non ci resta ora che la creazione del grafico e una pagina web che mostri la temperatura corrente e il grafico stesso

domenica 14 febbraio 2010

LM35+LCD+web+MySQL - 4) Fetcher

Il primo script è fetcher, incaricato di aprire la porta seriale, inviare un carattere convenuto ('s' nel nostro caso) leggere la temperatura che gli invia Arduino e stamparla.

-----------------------------------------------------------------------------------------------------------

Prima di tutto, bisogna aggiungere l'utente sotto il quale gira il demone http predefinito (Apache), al gruppo dialout; diversamente, dalla pagina web non sarà possibile accedere ad Arduino.

Infatti solo gli utenti di questo gruppo hanno il diritto di accedere alle periferiche.
Nel caso di Ubuntu l'utente di Apache è www-data , quindi da shell si lancierà:

$ sudo usermod -a -G dialout www-data


Una volta modificato, riavviare Apache:

$ sudo /etc/init.d/apache2 restart


Le modifiche così apportate saranno applicate definitivamente.

-----------------------------------------------------------------------------------------------------------

Agli inizi avevo provato con phpSerial (una libreria in PHP per la gestione della seriale), ma ho avuto molti malfunzionamenti spesso subdoli che mi hanno portato a sostituirla in favore di Device::Serial Port (http://search.cpan.org/dist/Device-SerialPort/) una libreria Perl per la gestione della seriale davvero efficiente e facile da impiegare.

La cosa senz'altro più interessante di questa libreria è che consente di disabilitare la linea DTR e quindi di prevenire l'autoreset di Arduino 10000 ogni qualvolta si invia un dato sulla seriale.

Per installare Device::Serial Port da Ubuntu/Debian:

$ sudo apt-get install libdevice-serialport-perl


Essendo gli altri script in PHP si è usata una funzione wrapper PHP ( fetchTemp() ) che fa semplicemente il lavoro di richiamare da sistema lo script fetcher.pl e riporlo in una variabile a disposizione degli altri script in PHP.

Ecco i due script:


FETCHER.PL



#!/usr/bin/perl -w

#########################################################################################################
#
# Motivazione: preleva e stampa a video il valore di temperatura acquisito da Arduino.
#
# Autore : Francesco Parisi (fparisi at tiscali dot it) , (fparisi at gmail dot com)
#
# Richiede : Device::SerialPort <http://search.cpan.org/~cook/Device-SerialPort-1.04/SerialPort.pm>
#
# Su Ubuntu: $ sudo apt-get install libdevice-serialport-perl
#
#########################################################################################################


use strict;
use Device::SerialPort;

my $portName = "/dev/ttyUSB0"; # identificativo seriale/USB usata
my $bps = "9600"; # velocità in bps
my $car = 's'; # carattere convenuto per la richiesta dati


# Costruttore (apre la porta e impegna le risorse hw)

my $port = Device::SerialPort->new( $portName )
|| die "Impossibile aprire $portName !\n";


# Configurazione trasmissione

$port->databits(8) || die "Impostazione databits fallita";
$port->baudrate($bps) || die "Impostazione baudrate fallita";
$port->parity("none") || die "Impostazione parity fallita";
$port->stopbits(1) || die "Impostazione stopbits fallita";
$port->dtr_active(0) || die "Impostazione dtr fallita"; # disabilita linea DTR (previene autoreset di Arduino)
sleep(1); # attendi 1s

# Invia carattere convenuto per la richiesta della temperatura

$port->lookclear; # svuota buffer
$port->write($car); # invia carattere convenuto


# Legge dato da seriale (in pooling)

my $gotit = ""; # dato letto

until ("" ne $gotit) {
$gotit = $port->lookfor; # poll until data ready
die "Aborted without match\n" unless (defined $gotit);
}


# Distruttore (chiude la porta e rilascia le risorse hw)

$port->close || warn "Chiusura porta non riuscita!\n";

# Stampa il dato letto

printf "%.1f\n", $gotit;





Lo script wrapper in PHP, FETCHER.PHP:


<?

/*************************************************************************************************
*
* Motivazione: funzione "wrapper" per lo script Perl di fetch della temperatura da Arduino
*
* Autore : Francesco Parisi (fparisi at tiscali dot it) , (fparisi at gmail dot com)
*
*
*************************************************************************************************/

function fetchTemp()
{
$perlCmd = '/usr/bin/perl'; // il comando Perl completo del suo path
$path = '/home/frank/public_html/'; // path allo script Perl (completo di '/' finale)
$script = 'fetcher.pl'; // nome script Perl

$temperature = exec ( $perlCmd . ' ' . $path.$script );
return $temperature;
}
?>




Codice evidenziato generato con Generator: GNU source-highlight 3.1
by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite

LM35+LCD+web+MySQL - 3) Schema

Lo schema di principio è raffigurato di seguito (click sopra per ingrandire):





Il trimmer da 10k regola la retroilluminazione. I due pin BACKLIGHT sono presenti se il LCD è dotato di retroilluminazione. Il pin RW è "forzato" a massa (solo scrittura) così si risparmia un collegamento.


Lo schema di montaggio con l'LCD che è stato impiegato (disegno realizzato con Fritzing) è riportato di seguito (click per ingrandire):





Qui invece una foto di una primissima versione della realizzazione (click sopra per ingrandire):




Il pin-out del LCD utilizzato:





1 ... GND
2 ... +5V
3 ... Contrasto (va collegato sul cursore del trimmer)
4 ... RS (collegato al pin digitale 12 di Arduino)
5 ... RW (collegato a GND)
11,12,13,14 ... D4,D5,D6,D7 (rispettivamente collegati ai pin digitali 5,4,3,2 di Arduino)
6 ... ENABLE (collegato al pin digitale 11 di Arduino)
15, 16 ... RETROILLUMINAZIONE (risp. a +5V e GND)

Per i pin fare comunque sempre riferimento al datasheet del LCD usato

sabato 13 febbraio 2010

LM35+LCD+web+MySQL - 2) Lo sketch

tempLM35.zip (tutti i file)


Dal momento che l'LM35 nel contesto in cui lavora al più potrà generare circa 0,5V (10mV/°C => 50°C) si è usata come tensione di riferimento quella interna (1.1V) del micro ATmega,per avere una risoluzione migliore.

Infatti con Vref=1,1V ed essendo l'ADC da 10bit abbiamo così 1 LSB = 1,074mV il che assicura una risoluzione di circa 0,1 °C migliore di quella propria del sensore.

Nel loop del programma, si è pensato di usare tre funzioni distinte, per tre rispettivi compiti:

  1. la prima, per la misura della temperatura: readTemp()
    esegue 20 letture della tensione fornita dal sensore, per ciascuna ne calcola la temperatura e alla fine ne fa la media aritmetica, questo per avere una migliore stima della misura; questo valore medio costituirà il valore di ritorno della funzione stessa che viene salvato nella variabile temp.

  2. la seconda, per inviare la temperatura alla seriale: sendTempToSerial()
    prende come parametro di ingresso la temperatura acquisita mediante readTemp()
    e la invia sulla seriale (USB) solo quando arriva un carattere convenzionale (ch)
    dal PC

  3. la terza, per inviare la temperatura al LCD: sendTempToLCD()
    come la precedente, prende la temperatura acquisita mediante readTemp() e la
    manda sul LCD collegato in locale ad Arduino. Il refresh avviene con un tempo di circa 0.5s che si è dimostrato un buon compromesso

Così, se non si è interessati a visualizzare la temperatura sul LCD o viceversa a non usare il lato PC, nel loop potra "commentare" la funzione che non interessa.

N.B. Lo sketch funziona da Arduino release 18

Da questa release,infatti, sono state apportate modifiche all'implementazione dei metodi print()/println() della classe Print, che consentono ora di specificare (nel secondo parametro di ingresso) il numero di cifre dopo la virgola ovviamente per i numeri in virgola mobile. Se si lavora su release precedenti (e non si vuole fare l'upgrade alla 18) si possono sempre copiare i nuovi file di implementazione e interfaccia: Print.cpp e Print.h della release 18 sull'installazione precedente:

http://arduino.googlecode.com/svn/trunk/hardware/arduino/cores/arduino/Print.cpp

http://arduino.googlecode.com/svn/trunk/hardware/arduino/cores/arduino/Print.h

Personalmente, ho seguito questa strada sulla mia release 17 (il path della 17 è ./hardware/cores/arduino) e tutto ha funzionato perfettamente.

Ecco lo sketch:

/*
* Sketch : LM35.PDE
* Motivazione: Misura di una temperatura ambientale (indoor) mediante sensore LM35
* Autore : Francesco Parisi ( fparisi at tiscali dot it ), (fparisi at gmail dot com)
* Ultima rev.: 1.5
* Data: : 09-Feb-2010
* Note : La scala dell'LM 35 è T = K * V,ove:
* K = 100 [°C/V] coeff.angolare della scala
* V è la tensione generata dall'LM35 (10mV/°C)
* T è la temperatura in °C
*/


/* Include la libreria per la gestione del LCD */

#include <LiquidCrystal.h>

/* Corrispondenza pin LCD <-> pin digitali di Arduino */

#define RS 12
#define EN 11
#define D7 2
#define D6 3
#define D5 4
#define D4 5

/* Numero del pin analogico sul quale è collegato l'LM35 */

#define ANALOGPIN 5


/* Definizioni globali */

double vref = 1.1; // Vref dell'ADC (quell'interno è di 1,1V)
LiquidCrystal lcd( RS, EN, D4, D5, D6, D7 ); // 'lcd' è una variabile di tipo LiquidCrystal */


/* Impostazione dell'hardware */

void setup()
{
/* Impostazioni comuni */
analogReference( INTERNAL ); // per l'ADC usiamo il Vref interno da 1,1V (migliore precisione)
analogRead( ANALOGPIN ); // Prima lettura "a vuoto" (cfr. pag. 47 datashett ATmega168)

/* Impostazione per l' LCD (2x16) */
lcd.begin( 2, 16 );

/* Impostazione per l'invio dati alla seriale */
Serial.begin( 9600 ) ; // apriamo uno stream seriale a 9600 bps
}



/* Legge la temperatura */

double readTemp()
{
double temp = 0.0; // valore convertito in temperatura (°C)
int val = 0; // valore quantizzato dall'ADC [0..1023]
int nread = 20; // numero di letture
double somma = 0.0; // somma delle letture

for (int i=0; i<nread; i++)
{
val = analogRead( ANALOGPIN ); // legge il dato della tensione sul pin 'voltagePin'
temp = ( 100.0 * vref * val ) / 1024.0; // lo converte in °C
somma += temp; // aggiunge alla sommaf delle temperature lette
delay(50); // aspetta 50ms
}

return ( somma / nread ); // restituisce la temperatura media
}



/* Invia la temperatura quando sulla seriale arriva il carattere convenuto */

void sendTempToSerial( double temp )
{
char incomingByte = 0; // Primo byte di input dallo stream seriale
char ch = 's'; // carattere convenuto

if ( Serial.available() > 0 )
{
incomingByte = Serial.read(); // Leggi il primo carattere in arrivo dal PC via seriale/USB
if ( incomingByte == ch ) // se è quello convenuto...
Serial.println( temp ); // ...manda la temperatura al PC via seriale/USB

}

}


/* Invia la temperatura su un LCD (modo 4bit) */

void sendTempToLCD( double temp )
{

lcd.clear(); // Pulisce lo schermo
lcd.noBlink(); // No lampeggio cursore
lcd.setCursor( 0, 0 ); // Posiziona cursore a colonna 1, riga 1
lcd.print( temp, 1 ); // Stampa temperatura con una cifra decimale
lcd.print(' ');
lcd.print( (char) 223 ); // Stampa '°'
lcd.print( 'C');

}



/* Esegue ripetutamente... */

void loop()
{

// acquisisci la temperatura e memorizzala nella var. temp.
double temp = readTemp();

// inviala al PC via seriale/USB, quando richiesto
sendTempToSerial( temp );

// inviala al LCD
sendTempToLCD( temp );


}





Codice evidenziato generato con Generator: GNU source-highlight 3.1
by Lorenzo Bettini http://www.lorenzobettini.it http://www.gnu.org/software/src-highlite

venerdì 12 febbraio 2010

LM35+LCD+web+MySQL - 1) Panoramica

Quello che andrò a descrivere è un semplice progettino per la misura di una temperatura interna, che vede impiegato ovviamente Arduino, il noto sensore LM35, un classico LCD HD44780 compatibile e un PC con OS Linux (es. Debian oppure una distribuzione derivata come Ubuntu).

L'LM35 e l'LCD sono collegati ad Arduino che a a sua volta è collegato a un PC sul quale gira un server web Apache, un server MySQL oltre ad ospitare i vari interpreti PHP e Perl





Dal lato Arduino:


il sensore è collegato a uno dei sei ingressi analogici, mentre l'LCD è collegato a 7 pin (4 per i dati + 2 per il controllo) del port I/O digitale di Arduino. Lo sketch nel suo loop esegue tre compiti molto semplici assegnati a tre rispettive funzioni:

  1. legge la tensione dell'LM35 e la converte in gradi Celsius;
  2. se dal PC gli arriva un carattere convenzionale (es. la lettera 's'), risponde inviando al PC stesso la temperatura acquisita (es. '15.42')
  3. invia comunque sull'LCD locale ogni mezzo secondo circa la temperatura acquisita

Dal lato PC:

il carattere di richiesta invio temperatura viene inviato dal PC ad Arduino in due scenari d'uso:
  1. dalla pagina web, on demand, ogni qualvolta il visitatore apre la pagina stessa o ne fa il refresh; la temperatura restituita da Arduino viene così visualizzata nella pagina web
  2. da uno script eseguito automaticamente dal sistema ogni mezz'ora; il dato della temperatura prelevata da Arduino viene inserito in un database MySQL
I dati memorizzati nel database vengono successivamente elaborati, creando un grafico delle temperature acquisite nelle ultime 24hh.

Quindi dal lato server, a un livello generale, abbiamo bisogno di:

  1. Un primo script, fetcher, che ha il compito fondamentale di aprire la seriale(USB), mandare ad Arduino un carattere (es. 's') e leggere da questo la temperatura in quel momento. Questo script verrà dunque utilizzato, per produrre la stampa nella pagina web della temperatura corrente.

  2. Un secondo script, logger, il quale anche esso sfrutta fetcher per prendersi la temperatura, ma non la visualizza: la va a inserire in un database di MySQL. Questo script viene lanciato automaticamente dal sistema ogni mezz'ora, dunque verranno memorizzati nel database le temperature lette ogni mezz'ora (es. 10:00, 10:30...ecc.)

  3. Un terzo e ultimo script plotter, che ha il compito di prendersi dal server MySQL le temperature loggate da logger nelle ultime 24hh e creare, dinamicamente, un'immagine con il grafico delle temperature in funzione degli orari. Quest'immagine verrà poi visualizzata in una pagina web.

  4. Una pagina web dinamica (es. in PHP), chiamiamola temp, che ogni qualvolta viene aperta, va a leggersi la temperatura misurata in quel momento da fetcher e la stampa a video. Inoltre, deve visualizzare anche il grafico generato da plotter.
Nel prosieguo scenderemo nei dettagli, prima dal lato Arduino e poi dal lato PC.

domenica 7 febbraio 2010

Uno sketch per il test dell'installazione

blink.pde


Il classico "hello world" dei sistemi embedded è un LED che lampeggia.

Arduino ha un LED in tecnologia surface-mount, già on-board e collegato al pin digitale 13...useremo quello.

Già che ci siamo, testiamo anche il flusso seriale fra Arduino e PC, per verificare la corretta installazione/configurazione di librxtxjava.

L'idea del nostro "hello world" è allora molto semplice: far lampeggiare il LED, ma impostarne il tempo di accensione/spegnimento dal PC, via seriale/USB: inviando la lettera 'u' si aumenta il tempo di 100ms, inviando la lettera 'd', si diminuisce sempre di 100ms

Dal menù Tools -> Board si selezionerà il tipo di Arduino impiegato (es. Arduino Diecimila...)

Dal menù Tools > Serial port si selezionerà la porta seriale/USB in uso (es. /dev/ttyUSB0)

Fatto questo si creerà un nuovo sketch e nell'editor (File -> New) si farà il copia&incolla del sorgente riportato più avanti.

Una volta salvato (es. BLINK.PDE) successivamente si farà il click sulle tre icone:


VERIFY: è la fase di compilazione e collegamento: vengono generati diversi file (fra cui quello oggetto in formato HEX) e messi in una dir. temporanea (es. /tmp/build* in ambiente Linux)


UPLOAD: il file oggetto HEX viene caricato dal software di programmazione (avrdude) nella memoria flash di Arduino. Contestualmente viene creata una sottodirectory ./applet in cui vengono copiati tutti i file precedentemente messi nella dir. temporanea


MONITOR: è un terminale di scrittura/lettura per dialogare con la seriale


Terminato l'upload, il piccolo LED sulla scheda inizierà a lampeggiare inizialmente a un tempo di circa 100ms.

Digitando la lettera 'u' e premendo il bottone Send del monitor seriale il periodo verrà incrementato di 100ms e così fino a 1s (1000 ms);successivi invii della lettera 'u' non sortiranno alcun effetto e quindi si potrà solo scendere di tempo (lettera 'd') fino a 100ms.


Ecco lo sketch:


/*
* BLINK.PDE
*
* Autore: Francesco Parisi ( fparisi at tiscali dot it )
*
* Motivazione: "Blinka" il LED di Arduino con un tempo da 100ms a 1s regolabili dal PC
*
* Uso: L'utente dal PC, attraverso un emulatore di terminale, inviando
* il carattere 'u' aumenta di 1s il tempo di lampeggio, mentre lo
* diminuisce inviando il carattere 'd'
*
* Limitazioni: L'utente non può andare oltre il secondo o al di sotto di 100ms
*
*/


#define LEDPIN 13 // Sul pin 13 è collegato il LED montato su Arduino


/*** Definizioni globali ***/

int incomingByte = 0; // Primo byte di input dallo stream seriale
long t = 100; // Tempo di lampeggio in ms, inizialmente 100ms


/*** Impostazione dell'hardware ***/

void setup()
{
pinMode( LEDPIN, OUTPUT ); // Imposto il pin 'LEDPIN' come di uscita
Serial.begin( 9600 ) ; // Imposto uno stream seriale a 9600 bps
}

/*** Esegue continuamente ***/

void loop()
{
digitalWrite( LEDPIN, HIGH ); // Manda livello alto sul pin 'LEDPIN' (LED on)
delay( t ); // Aspetta 't' ms

digitalWrite( LEDPIN, LOW ); // Manda livello basso sul pin 'LEDPIN' (LED off)
delay( t ); // Aspetta 't' ms


if ( Serial.available() > 0 ) // Se ci sono caratteri in arrivo dal PC...
{
incomingByte = Serial.read(); // ...leggi il primo carattere
if ( incomingByte == 'u' ) // se è 'u' (sta per UP)...
t += 100; // ...incrementa di 100ms
else if ( incomingByte == 'd' ) // altrimenti se è 'd' (sta per DOWN)...
t -= 100; // ...decrementa di 100ms

if ( t > 1000 ) // se si prova a salire oltre 1s...
t = 1000; // ...imposta t a 1s
else if ( t < 100 ) // se si prova a scendere sotto i 100ms...
t = 100; // ...imposta t a 100ms

}

Serial.print( t , DEC ); // Scrivi il tempo in ms
Serial.println( " ms" ); // Scrivi " ms" (unità di misura) e ritorna a capo

}

Installare l'IDE di Arduino su Ubuntu 9.10

Una volta installata la libreria che consente il riconoscimento di Arduino, si può passare all'installazione dell'ambiente di sviluppo (IDE) che consentirà di scrivere i programmi (sketch) e di caricarli (via USB) sulla board.

L'IDE di Arduino è scritto in Java, dunque c'è un solo pacchetto multipiattaforma che viene interpretato dal runtime Java del sistema operativo. Per funzionare ha bisogno che ci siano sul sistema i seguenti pacchetti: librxtx-java, il JRE di Sun , il compilatore gcc e le libc per AVR.

Il comando per installare tutti questi pacchetti è il seguente:

$ sudo apt-get install sun-java6-jre avr-libc gcc-avr


Nota: I repository (dal gennaio 2010) di Ubuntu assicurano che la versione di avr-gcc sia definitivamente maggiore della 4.3.0, che invece dà qualche problema e non supporta il micro del nuovo Arduino 2009 (cfr. http://www.arduino.cc/playground/Learning/Linux).
La versione installata (gennaio 2010) è la 4.3.3 (quindi > 4.3.0)



Per quanto riguarda l'installazione di librxtx, invece, ci sono due percorsi differenti a seconda della versione di Ubuntu.

Se si è su Ubuntu versione a 32 bit va bene quella del repository:

$ sudo apt-get install librxtx-java


Se, invece, si è su Ubuntu versione a 64 bit, bisogna scaricare e installare questa versione più recente di librxtx:

http://chemicaloliver.net/code/librxtx-java_2.2pre2_amd64.deb

(che è più aggiornata di quella attuale dei repository, la quale invece dà problemi).

Il pacchetto .deb può essere installato all'atto dello scaricamento con il front end grafico Gedi oppure con dpkg dalla riga di comando. Supponendo che il pacchetto sia stato salvato nella home directory:

$ cd

~$ sudo dpkg -i librxtx-java_2.2pre2_amd64.deb


Si passa dunque a scaricare il pacchetto dell'IDE.

Dal sito http://code.google.com/p/arduino/downloads/list scaricare la versione più recente del pacchetto multipiattaforma (scegliere il formato .tgz) e salvarlo nella propria home directory (es. /home/frank)

Il nome del file segue la sintassi arduino-xxxx.tgz ove xxxx è il progressivo della versione. Al momento in cui si scrive, la versione corrente è la 0017, quindi il file più recente
è arduino-0017.tgz

Va da sé, che, per il futuro, occorrerà sostituire nei comandi successivamente riportati il numero 0017 con il numero della la versione più recente.

Portarsi nella home directory e scompattare l'archivio:

$ cd

~$ tar zxvf arduino-0017.tgz


Nella home dir. verrà dunque creata la cartella arduino-0017

Sempre dalla propria home directory, portarsi nella cartella lib dell'installazione, es.

~$ cd arduino-0017/lib


e rinominare il file librxtxSerial.so :
~$ mv librxtxSerial.so librxtxSerial.so.orig


ciò consentirà di utilizzare la corretta libreria librxtx (precedentemente installata) per la versione di Ubuntu usata (se 32 o 64 bit)

A questo punto l'installazione è sostanzialmente terminata salvo alcuni step "cosmetici" decisamente consigliati.

Il primo è quello di crearsi una directory sull'home directory, es. di nome Arduino, che si userà per contenere tutti gli sketches (i file sorgenti di che hanno convenzionalmente estensione .pde):

~$ mkdir Arduino


Si è pronti per il primo avvio dell'IDE; portarsi nella directory arduino-0017 e lanciare l'eseguibile arduino:

~$ cd arduino-0017

$ ./arduino


Facoltativamente si può creare un link simbolico arduino che punti, di volta in volta, alla versione aggiornata arduino-xxxx

~$ ln -s arduino-0017 ./arduino


Al primo avvio, ci verrà chiesta la directory di lavoro, dove salveremo i nostri sketch. Questa cartella rappresenterà il nostro "Sketchbook" e potrà essere comodamente richiamato dal menù file dell'IDE (File -> Sketchbook) . Selezionamo dunque come directory di lavoro quella precedentemete creata (~/Arduino):



L'ultimo passo è quello di creare un lanciatore sulla Scrivania, seguendo l'ottimo suggerimento che ho trovato su Ubuntu Forum:


http://ubuntuforums.org/showpost.php?p=5974212&postcount=1

L'icona che servirà per il lanciatore http://osx.iusethis.com/icon/osx/arduino.png verrà salvata nella propria home dir e poi da lì, copiata su /usr/share/icons:

~$ sudo cp arduino.png /usr/share/icons


Personalmente ho preferito la nuova icona di Arduino 17: http://upload.wikimedia.org/wikipedia/commons/d/d7/Arduino-0017-512x512px.png


Portarsi sulla scrivania stessa con il pulsante destro del mouse selezionare dal menù pop-up "Crea lanciatore..."

Appare la maschera con le proprietà del lanciatore, i cui campi vanno riempiti come nell'esempio:


Nel campo Comando digitare:

bash -c "cd /home/nomeutente/arduino-0017/; ./arduino"

Nel campo Nome: digitare

arduino

A questo punto, cliccare sull'icona di default del lanciatore ("la molla") e selezionare l'icona arduino.png precedentemente salvata in /usr/share/icons.

Ecco come compare l'icona di Arduino sulla mia scrivania: