Il neTTarello

Descrizione

Misuratore analogico del traffico di rete (o di qualunque altra cosa vi passi per la mente).

Il dispositivo è composto da due parti: un software che raccoglie ed elabora i dati da visualizzare e uno strumento “ad ago” realizzato con una board a microcontroller e un servocomando che indica, istante per istante, la misura effettuata.

Materiale necessario per la realizzazione:

  • 1 servocomando RC (quelli utilizzati per il modellismo radiocomandato)
  • 1 po' di fantasia per realizzare l'indicatore :-)

Funzionamento board e servocomando

La board Arduino viene utilizzata come terminale per il controllo del servocomando: riceve la posizione desiderata attraverso la porta seriale (USB) e muove il servocomando di conseguenza.

Controllo del servocomando

Il servocomando ha 3 terminali: 2 due di alimentazione (GND e 5V) e uno di controllo posizione. I servi standard possono effettuare una rotazione del loro asse da 0° a 180°. Il servo può essere mosso fornendo sul pin di controllo una serie di impulsi di durata variabile da 0.9ms a 2.1ms proporzionale alla posizione desiderata (0.9ms per 0° fino a 2.1ms per 180°). La distanza massima fra un impulso e il successivo deve essere compresa tra 10ms e 50ms, tipicamente si usa inviare un impulso ogni 20ms (50Hz).

Firmware

Possiamo ottenere il segnale di controllo molto facilmente utilizzando la libreria Servo disponibile su arduino:

Con questa libreria non ci dobbiamo preoccupare dei dettagli implementativi in quanto sono già stati realizzati per noi. Per poter lavorare con la libreria bisogna scompattare il file servo.zip all'interno della cartella arduino-0011/hardware/libraries prima di procedere nella compilazione.

Lo stesso vale per la comunicazione seriale, in quanto è già incluso nelle funzioni di libreria l'oggetto Serial che si occupa di tutta la gestione a basso livello.

Il firmware da caricare sulla board è semplice e si commenta praticamente da solo. Quello che fa è sentire se ci sono dati in arrivo dalla porta seriale e in caso affermativo leggere un byte e usarlo come valore di “angolo” a cui posizionare il servo.

// Includi la libreria di controllo del servo nel firmare
#include <Servo.h>
 
// Dichiara un oggetto Servo
Servo servo;
 
// Inizializzazioni varie
// ----------------------
// (vengono eseguite una sola volta all'accensione della board)
void setup()
{
    // Associa il pin 9 al segnale generato per il servo
    servo.attach(9);
 
    // Imposta la velocità della porta seriale a 9600 bps
 
    Serial.begin(9600);
}
// Ciclo di controllo principale
// -----------------------------
// (funzione ripetuta all'infinito dopo l'inizializzazione)
 
void loop()
{
   // Se ci sono dati in arrivo dalla seriale...
 
   // (il numero di byte disponibili è > 0?)
)
    if (Serial.available() > 0) {
 
      // Leggi un byte dalla porta seriale
e
        int i;
        i = Serial.read();
 
      // muovi il servo nella posizione indicata
a
        servo.write(i);
    }
 
  // Questa funzione è di servizio per il funzionamento della
la
 // libreria Servo e va richiamata almeno una volta ogni 20ms
ms
 // (noi la chiamiamo a ogni ciclo quindi molto più di frequente)
te)
    Servo::refresh(

Collegamenti e schemi elettrici

Lo schema dei collegamenti è, oserei dire, banale, il servocomando standard ha i seguenti contatti:

Colore Funzione Pin su Arduino
Marrone o Nero Massa GND
Rosso Alimentazione 5.0V-9.0V +5V
Giallo Impulsi di controllo Pin 9

Abbiamo utilizzato il pin 9 perchè la libreria Servo può controllare al massimo due servocomandi contemporaneamente e questi devono essere collegati per forza al pin 9 e al pin 10 (in ogni caso questi due pin non potranno essere utilizzati per fare altro, anche disponendo di un solo servocomando).

Software di raccolta dati dal PC

Vediamo ora come pilotare il nostro hardware da PC.

Driver di comunicazione seriale

Collegando la porta USB al PC, il driver installato nel sistema operativo creerà una porta seriale “virtuale” per comunicare con l'arduino. Se avete Linux, il driver è già fornito come modulo del kernel nella maggiorparte delle distribuzioni e la porta seriale creata si chiamerà /dev/ttyUSB0 (o /dev/ttyUSB1…9 se ne avete più di una).

Il software è scritto in python, ma chiaramente potete utilizzare un linguaggio qualunque che sia in grado di controllare la porta seriale.

In python è particolarmente semplice, basta utilizzare la libreria pyserial. Nel caso non fosse già installata python la può scaricare e installare automaticamente per noi con il comando:

sudo easy_install pyserial

Software di movimentazione

quello che segue è un pezzo di programma che si occupa di far muovere il servo

# Importa la libreria per la porta seriale
import serial
 
# Crea un oggetto serial sul device /dev/ttyUSB0, velocità 9600 bps
 
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
# Funzione move(angolo)
 
def move(ang):
 
   # Se l'angolo non è compreso tra 0 e 180 riportalo nei limiti
i
    if ang>180:
        ang=180
    if ang<0:
        ang=0
 
  # Invia il valore attraverso la porta seriale come un singolo byte.
.
  # (dobbiamo usare la funzione chr(...) per convertire ang in un singolo
o
  # byte, altrimenti la write invierebbe una stringa con la codifica
a
  # in ASCII del valore di ang)
)
    ser.write(chr(ang

Una volta dichiarata la funzione move(..) possiamo muovere il servocomando con un istruzione del tipo:

# Muove il servocomando alla posizione di 100°
 
move(100

Adesso che abbiamo il controllo del servocomando, possiamo utilizzarlo per far visualizzare praticamente qualsiasi grandezza ci viene in mente, basta scrivere un programma che invii uno stream continuo del valore da visualizzare alla board.

Software di raccolta dati

Nel nostro caso abbiamo scritto un piccolo software che calcola l'utilizzo della scheda di rete calcolandolo sulla quantità di byte ricevuti. La funzione seguente legge le statistiche dell'interfaccia di rete prelevandole dal file /proc/net/dev e restituisce il numero di byte ricevuti (i dettagli di questa funzione e delle successive esulano dagli scopi dell'articolo ma in caso di dubbi vi consigliamo comunque di guardare la documentazione di python o uno dei migliaia di tutorial disponibili in rete):

# Importa la libreria per la gestione delle regular expression
import re
 
# Restituisce il numero di byte ricevuti dall'interfaccia di rete "interface"
def read_traffic(interface):
    f = open("/proc/net/dev")
    for line in f:
        if line[6-len(interface):6]==interface:
            return re.split('[ :]+', line)[2]
    f.close()

Il programma principale contiene un ciclo che viene eseguito ogni 200ms, che effettua la lettura dei byte ricevuti dalla scheda di rete, calcola la differenza con la lettura precedente in modo da ottenere il numero di byte ricevuti fra un ciclo e il successivo. Una volta ottenuta la lettura questa viene portata in una scala logaritmica e convertita in gradi. La conversione in scala logaritmica ci permette di vedere anche i valori più bassi di traffico che altrimenti risulterebbero compressi sotto l'1% di tutta la scala.

Byte ricevuti % su byte log(Byte ricevuti) % su log
0 0% non esiste :-)
1 < del 1% 0 0.0%
10 < del 1% 1 12.5%
100 < del 1% 2 25.0%
1K < del 1% 3 37.5%
10K < del 1% 4 50.0%
100K < del 1% 5 62.5%
1M 1% 6 75.0%
10M 10% 7 87.5%
100M 100% 8 100.0%

il risultato poi viene scalato in modo da avere un range da 0 a 180. Ecco il codice:

# Importa la libreria matematica e di gestione dei timings
import math
import time
 
actual = read_traffic("eth0")         # Effettua la prima lettura
 
while True:
    time.sleep(0.200)                 # pausa di 200ms
 
    # Effettua una nuova lettura e salva la precedente
    old = actual
    actual = read_traffic("eth0")
 
    # Calcola il valore da visualizzare...
    res = math.log(int(actual)-int(old)+1)
 
    # ...lo converte in gradi...
    res = res * 180 / 9
 
    # Invia il valore al servocomando
    move(int(res))
 
il_nettarello.txt · Last modified: 02/10/2008 19:48 by megabug
 
Except where otherwise noted, content on this wiki is licensed under the following license:Public Domain
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Debian Driven by DokuWiki