ebook img

Elettronica in 182 PDF

38.7 MB·Italian
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview Elettronica in 182

Networking Dotiamo Arduino di uno shield e una libreria per farlo comunicare con il mondo esterno tramite WiFi. WI-FI E INTERNET ARDUINO PER di DANIELE DENARO L a scheda Arduino ha rappresentato una vera i collegamenti con le reti ed ancor più la connettività rivoluzione in campo elettronico dimostrandosi Internet, richiedono una gestione asincrona e sostan- particolarmente adatta ai non esperti ed allo stesso zialmente multi-task dei protocolli di comunicazione. tempo anche molto versatile, tanto da riuscire a gesti- Per questo motivo, il collegamento di Arduino con re moltissime applicazioni in svariati ambiti. L’abbia- Internet è sempre stato un po’ difficoltoso, tanto da mo vista, ad esempio, affrontare compiti impegnativi spingere i suoi creatori a implementare un sistema come la connessione con il mondo esterno, realizzata ibrido come la YÚN, dove il processore Atheros ha lo ora con le semplici interfacce di base (seriale, I²C-Bus), scopo principale di gestire le comunicazioni. ora con quella che definiamo la connettività vera e YÚN non è comunque l’unica soluzione, infatti, come propria, ossia le interfacce wireless e la rete Ethernet. dimostreremo in queste pagine, Arduino può dispor- In entrambi i casi i limiti di Arduino si manifestano re della connettività Internet attraverso uno shield palesemente, perché la scheda del team di Banzi, equipaggiato con un gestore dello stack TCP/IP, in come si sa, conta su un hardware minimale, mentre modo da liberare l’ATmega da alcune incombenze Elettronica In ~ Dicembre 2013 / Gennaio 2014 23 di base. Ma anche con il gesto- protocollo TCP/IP, semplifichi LO SHIELD WIFI re, bisogna comunque superare al massimo la vita di chi vuole Se ricordate, già qualche tempo diverse difficoltà nella gestione programmare Arduino e vuole fa (precisamente, nel fascicolo dei collegamenti Internet, sia con farlo dialogare con altri computer n° 160) abbiamo pubblicato il semplici socket2 (vedi più avanti), tramite Internet. progetto di uno shield per do- sia con il protocollo Http (quello Iniziamo con la descrizione tare Arduino della connettività usato dal mondo Web). Per questo dell’hardware del nuovo shield WiFi; quello qui descritto è una motivo, è fondamentale correda- WiFi e successivamente descri- versione migliorata, in quanto, re la scheda di una libreria che, viamo la libreria di corredo ed il rispetto al precedente, basato su oltre a dialogare con il gestore del suo uso. un modulo di Microchip che ora ] O C I R T T E L E a m e h c s [ 24 Dicembre 2013 / Gennaio 2014 ~ Elettronica In [piano di MONTAGGIO] Elenco Componenti: R1, R4, R11: 10 kohm (0805) R2, R10: 4,7 kohm (0805) R3: 100 kohm (0805) R5: 1 Mohm (0805) R6: - R7: - R8: 1 kohm (0805) R9: 1,5 kohm (0805) R12÷R15: 330 ohm (0805) C1, C5, C6, C9: 100 nF multistrato (0805) C2, C10: 220 µF 6,3 VL elettrolitico (D) C3, C4: 22 pF ceramico (0805) C7, C8: 10 µF 35 VL elettrolitico (B) U1: MRF24WB0MA/RM U2: MCW1001A U3: TC1262-3.3 (SOT-223) T1: BC817 Q1: Quarzo 8 MHz (HCX-7SB) > RS: 675-4703 RST: Microswitch LD1÷LD4: LED verde (0805) Varie: - Strip maschio 3 vie (2 pz.) - Strip maschio 4 vie (3 pz.) - Strip maschio 5 vie (1 pz.) - Strip maschio/Femmina 6 vie (1 pz.) - Strip maschio/Femmina 8 vie (2 pz.) - Strip maschio/Femmina 10 vie (1 pz.) - Strip maschio/Femmina 3 vie (2 pz.) - Jumper (2 pz.) - Circuito stampato è uscito di produzione, dispone questo motivo abbiamo correda- Il modulo radio ha già l’antenna dell’hardware che permette di to la scheda di una libreria che integrata. gestire da sé il protocollo TCP/IP. pensiamo finalizzata agli utilizzi Il processore governa il modulo Più esattamente, la differenza di Arduino, con un grado di sem- WiFi tramite il bus SPI (linee sostanziale tra il vecchio shield plificazione superiore a quello SDO, SDI, SCK) ed altre linee e questo nuovo è che nel pre- per un hardware più complesso di controllo come CS, INT, RST, cedente era Arduino (tramite (anche se più flessibile) come HIBERNATE, WP; dal lato host un’apposita libreria) a governare quello della YÚN. (cioè Arduino) il processore è col- il modulo WiFi e gestire il proto- Venendo alla descrizione legato con un’interfaccia seriale collo TCP/IP, mentre in questo dell’hardware, possiamo notare a due fili in logica TTL (RX,TX). nuovo circuito abbiamo inserito che lo shield (che ha le stesse di- Questo ci ha costretto ad utiliz- un processore di interfaccia mensione della scheda Arduino zare una porta seriale simulata che si occupa della gestione del Uno) si basa essenzialmente su da software con una versione protocollo TCP/IP, scaricando un modulo WiFi MRF24WB0MA personalizzata della libreria Sof- così Arduino da un compito che, ed un processore MCW1001A, twareSerial. La personalizzazione dall’esperienza del primo shield, entrambi Microchip. L’alimenta- è stata necessaria a causa della è apparso troppo impegnativo. zione è a 3,3V (ottenuti mediante modalità con due bit di stop, ma Ma una scheda di rete diventa un riduttore di tensione alimen- anche per aggiustare la velocità veramente utile se è pilotata da tato dalla linea 5V di Arduino) ottimale e rendere trasparente un software che semplifica il ma il processore sopporta anche l’utilizzo della libreria. Infatti più possibile il suo utilizzo; per livelli TTL. questa versione della Software- Elettronica In ~ Dicembre 2013 / Gennaio 2014 25 Fig. 1 - Comunicazione fra due applicazioni. una figura di server (e listener, ovvero ascoltatore) ed una figura di chiamante (client), altrimenti sarebbe impossibile sincronizza- re il colloquio. La libreria copre questi due tipi di funzionalità: ad esempio può essere utilizzata quando voglia- mo dare ad Arduino il compito di server, in modo che reagisca e risponda a messaggi di un altro Serial è compresa nella libreria. stack TCP/IP, gestendo il proto- computer. Oppure può essere Tale modalità di collegamento, collo di base attraverso l’utilizzo utilizzata per dare ad Arduino tuttavia, preclude la possibilità di della sua RAM interna per i la possibilità di collegarsi di sua utilizzo della libreria Software- buffer di trasmissione e ricezione, iniziativa ad un computer server Serial standard per altri usi nello nonché per la memorizzazione per spedirgli, per esempio, misu- stesso sketch. La porta seriale si- dei vari parametri. Va però detto re effettuate da sensori. mulata si può collocare, a livello che, non disponendo di memoria Il collegamento si stabilisce hardware, su due coppie di pin non volatile interna, il processore in TCP/IP tramite delle entità di Arduino: tramite due ponticel- ad ogni riavvio va riconfigurato. chiamate socket, le quali corri- li potete scegliere se utilizzare D3 Il protocollo di comunicazione spondono al concetto di “presa” o D11 per il canale RX (D3 è la li- tra l’host ed il processore e le sue cui collegare un cavo di comuni- nea predefinita) e D2 o D10 per il funzioni sono ben descritti nel cazione. Esiste quindi un socket TX (D2 è la predefinita). Nel caso datasheet del componente, che per ciascuno dei due computer decidiate di modificare i valori trovate alla pagina web: www. che devono dialogare tra loro. Un predefiniti, dovete editare il file microchip.com/wwwproducts/Devi- socket si crea nell’ambito di un MWIFI.h e modificare le righe: ces.aspx?dDocName=en555844. numero di porta. I numeri di por- In ogni caso, la gestione di basso ta sono dei sub-indirizzi appli- livello è demandata alla libreria cativi all’interno di un indirizzo #define RXPIN 3 che fornisce un insieme di fun- IP. I numeri inferiori a 1.000 sono #define TXPIN 2 zioni per aprire socket o gestire il riservati ai servizi pubblicamente I pin scelti, insieme al pin D7 usa- protocollo HTTP. riconosciuti quali Mail, Ftp, Web to per il reset della scheda WiFi, La scheda dispone di quattro (porta 80), e così via. non possono, quindi, essere usati LED di cui due sono utilizzati per altri scopi. Però il processore dalla libreria. Più precisamente: LA LIBRERIA MWIFI MCW1001A mette a disposizio- il LED0 è attivato all’accensione Bene, giunti a questo punto pos- ne ulteriori pin digitali, i primi e start-up della scheda mentre siamo descrivere la libreria per quattro dei quali sono collegati il LED1 viene acceso quando si Arduino che implementerà la ge- ad altrettanti LED, mentre altri stabilisce la connessione con la stione della connessione in TCP/ tre sono attestati ad altrettanti rete. Gli altri due possono essere IP. La libreria si può scaricare dal connettori insieme al positivo utilizzati dall’utente. nostro sito www.elettronicain.it di alimentazione (5V o 3V3) e Per comprendere le scelte pro- insieme agli altri file del progetto. a GND. Infatti questi tre pin gettuali in fatto di hardware e Ma procediamo con ordine: la (GPIO5, GPIO6, GPIO7) possono software Arduino, spendiamo MwiFi va posizionata (dopo la gestire anche livelli di 5V con una qualche paragrafo per descrive- decompressione) nella directory corrente massima di circa 25 mA re le problematiche insite nella “libraries” dell’IDE di Arduino, (IN/OUT). I pin GPIO sono atti- comunicazione TCP/IP: a livello come le altre librerie; va utilizza- vabili con funzioni della libreria, applicazione, quando un compu- ta includendo negli sketch il file ma i primi due LED sono riservati ter decide di mettersi in comuni- <MwiFi.h>. alla libreria per segnalare accen- cazione con un altro, bisogna che A questo punto va istanzia- sione e collegamento in rete. quest’ultimo sia in ascolto degli ta come oggetto e può essere Come accennato, il processore eventuali elementi che stanno utilizzata; la prima funzione da MCW1001A si preoccupa dello inviando dati; quindi, c’è sempre richiamare è begin(), che serve a 26 Dicembre 2013 / Gennaio 2014 ~ Elettronica In WiFi 5 GHz + Bluetooth inizializzare la scheda: #include <MWiFi.h> ConnectBlue presenta OWL355, un modulo WLAN capace MWiFi WIFI; di funzionare sia nella classica banda a 2,4 GHZ, sia void setup() nella nuova 5 GHz, oltre che di interfacciarsi con tutti gli { standard Bluetooth. Progettato per l’Internet delle WIFI.begin(); Cose, le applicazioni diomedicali e quelle : industriali, supera gli attuali standard Lo start-up della scheda deter- sia IPC che AQL. Grazie al driver open mina l’accensione del primo source Linux, il modulo consente LED. Proviamo, ora, a collegare di implementare con facilità una Arduino in rete utilizzando un connessione wireless in un access-point, che potrebbe essere qualsiasi dispositivo elettronico quello del router WiFi casalingo, fornendo hardware modulare per esempio assegnando il nome omologato, certificazione (SSID) “D-Link-casa”: EMC, qualificazione Bluetooth, un’ampia gamma di antenne. Tra le altre caratteristiche, WIFI.ConnSetOpen(“D-Link-casa”); da segnalare la tecnologia valido nel caso la rete fosse non Castellation Package che protetta, oppure: utilizza dei rilievi di metallo ai lati del modulo che rendono molto più agevole la saldatura (anche WIFI.ConnSetWPA(“D-Link- manualmente) consentendo l’impiego casa”,”miarete”); del modulo in applicazioni con bassi nel caso la rete avesse protezione volumi di produzione. WPA con password “miarete”. Le precedenti funzioni servo- no a predisporre la scheda alla Per comodità sono state ag- funzionare Arduino da server: connessione; ma la vera e propria giunte anche funzioni dirette per prima cosa chiamiamo la connessione si ottiene chiamando di connessione, che preparano funzione openServerTCP(), che la funzione: la connessione e la eseguono crea l’ascoltatore su una certa in un unico step. Inoltre è stata porta (per esempio 5000), e poi aggiunta la possibilità di gene- mettiamo in loop la ricezione di WIFI.Connect(); rare la chiave numerica dalla una eventuale richiesta di link: Se la connessione va a buon fine, password, in modo da utilizzare si accende il secondo LED. Fate successivamente questa al posto int ssocket=WIFI.openSer- però attenzione, perché nel caso della password; infatti l’accesso verTCP(5000); di rete protetta, la connessione con password, prevedendo ogni void loop() può richiedere anche più di mez- volta l’elaborazione della chiave { zo minuto, in quanto il controller numerica, può richiedere anche int csocket=WIFI. della scheda deve codificare un minuto, mentre l’accesso con pollingAccept(ssocket); la chiave tramite la password. chiave è velocissimo. : L’attuale versione della libreria Ad Arduino viene assegnato, dal prevede un reset automatico di router, un indirizzo IP dinamico, Le variabili intere ssocket e csocket Arduino nel caso la connessione perché il comportamento pre- sono dei riferimenti (handle) venga persa; il reset automatico definito della scheda è questo; rispettivamente al server e al si verifica anche se vengono ma volendo si può imporre un socket di collegamento con rilevati errori dal controller. In indirizzo fisso. L’indirizzo asse- l’eventuale computer che vuole questo modo, un eventuale gnato può essere richiesto da una effettuare il link. La funzione pol- blocco è scongiurato ed il sistema funzione della libreria. lingAccept() ritorna un numero può essere “unattended”. A questo punto scegliamo di far minore di 255 se il collegamento Elettronica In ~ Dicembre 2013 / Gennaio 2014 27 Fig. 2 - Comunicazione HTTP. int csocket=WIFI.openSoc- kTCP(“192.168.1.2”,5000); E se csocket è valida (minore di 255), vuol dire che il collegamen- to, con il computer all’indirizzo 192.168.1.2 sulla porta 5000, è stato stabilito. A questo punto possiamo utiliz- zare le funzioni di scrittura e let- tura viste precedentemente. Tra gli esempi ce n’è uno (SendDa- è stato richiesto, o 255 se non c’è e produce questo tipo di stringa, ta) che si collega ad un server alcuna richiesta di collegamento da non confondere con l’oggetto remoto per spedirgli ad inter- in arrivo. String presente anche nel langua- valli regolari letture di sensori; Nel caso il collegamento sia ge reference di Arduino. in questo caso è necessario un stato stabilito potremo spedire In questo semplice modo abbia- programma server installato sul o ricevere messaggi facendo mo stabilito e utilizzato un colle- computer remoto. Per facilitare i riferimento a questo csocket. Per gamento WiFi con un computer test, insieme alla libreria è stato esempio per ricevere un record, remoto. Nella libreria, tra gli fornito un programma Java che cioè una stringa terminante con esempi riportarti, c’è un esempio riceve i dati e li scarica su un file un line-feed possiamo utilizzare di server chiamato CommandSer- aggiungendo un time-stamp (per la funzione: ver, che permette di comandare ovviare alla mancanza di un RTC, Arduino utilizzando un program- Real Time Clock, su Arduino). ma tipo telnet sul computer remo- Oltre a queste funzionalità di char *line=WIFI. to. Per semplificare i test è stato base, nella libreria sono presenti readDataLn(csocket); aggiunto un programma Java che tutte le funzioni necessarie per Ci verrà restituita una “null-ter- opera come telnet. definire diversi parametri quali minated string” ma senza il line- Se invece volessimo far agire Ar- l’indirizzo di mascheramento feed. In questo caso, la libreria duino come un “client” che si col- della rete (255.255.0.0 è il prede- utilizza un buffer predefinito di lega ad un server, la situazione finito), l’eventuale indirizzo di 81 caratteri (ma la sua lunghezza sarebbe ancora più semplice, Gateway, la lettura del codice può essere modificata nel suo de- perché dovremmo crea- MAC della scheda, ecc. fine) perciò non abbiamo bisogno re solo un socket di In particolare, sono di fornirlo noi. Sono comunque collegamento, presenti delle previste altre possibilità. così: Se invece vogliamo rispondere possiamo utilizzare la funzione: WIFI.writeDataLn(csocket,answer); La variabile che abbiamo chia- mato answer corrisponde ad un buffer di char, però deve essere una “null terminated string”. Utilizzare una “null-terminated string” vuol dire che non dob- biamo fornire la lunghezza dei caratteri utili nell’array, perché la funzione la calcola automatica- mente, potendo basarsi sul carat- tere terminale nullo. La maggior parte delle funzioni in C gestisce 28 Dicembre 2013 / Gennaio 2014 ~ Elettronica In Listato 2 prog_char pagerdigital[] PROGMEM= funzioni per rilevare access-point : presenti e visibili nell’ambiente. “<tr>” “<td><div align=’center’>@</div></td>” Ad esempio, per rilevare tutte le “<td><div align=’center’>@</div></td>” reti presenti si usa l’istruzione: “<td><div align=’center’>@</div></td></tr>” : int nn=WIFI.scanNets(); void rdigital(char *query) { char *val[3]; La variabile intera nn conterrà il if(digitalRead(4)) val[0]=ON;else val[0]=OFF; numero di reti rilevate. if(digitalRead(5)) val[1]=ON;else val[1]=OFF; if(digitalRead(12))val[2]=ON;else val[2]=OFF; Invece la funzione: WIFI.sendDynResponse(csocket,pagerdigital,3,val); } char* net=WIFI.getNetScanned(i); (header) e dati veri e propri GlassFish, Jboss, PHP, ecc.). restituirà le caratteristiche (sotto (come le pagine html, immagini, Supponiamo di voler realizzare forma di record) della “i-esima” video o anche semplice testo). un Web Server da interrogare rete rilevata. Infine, per comodità, Per scaricare l’utente da tutta con un qualunque browser: per è stata prevista una funzione che questa problematica, la libreria far funzionare Arduino come restituisce il nome della rete non per HTTP si preoccupa di forma- Web Server dobbiamo predispor- protetta che fornisce il segnale re questi pacchetti utilizzando, re le risorse che esso può mettere più potente. inoltre, in modo spinto la moda- a disposizione, cioè le pagine Rimandiamo alla documentazio- lità PROGMEM cioè la possibilità html di risposta. Queste pagine ne della libreria la descrizione di di porre in area Flash di pro- saranno memorizzate in aree tutte le funzionalità disponibili. gramma le costanti ed in partico- PROGMEM per i motivi detti La libreria contiene un help (in lare i testi. Facciamo notare che il sopra. Per esempio: inglese) ed è documentata nei file protocollo HTTP è un protocollo di codice (in particolare i file .h). testuale: usa solo caratteri. L’uso prog_char pageindex[] PROGMEM= Ma la libreria non si esaurisce della memoria Flash per i testi “<html><head>” nella sola gestione di connes- permette di risparmiare spazio “<title>Index</title>” sione e socket; infatti in essa è nell’esigua RAM di Arduino. : inclusa una classe derivata (e quindi specializzata) che gestisce LA LIBRERIA HTTP A questo punto si tratta di col- il protocollo HTTP. Quest’ultimo Essendo una classe derivata di legare questi buffer in memoria è un protocollo che prevede sem- MwiFi, la libreria HTTP eredita con i nomi delle risorse da richia- pre una richiesta ed una risposta; tutte le funzioni di MwiFi; tut- mare tramite browser. I nomi sia la richiesta che la risposta tavia se si vogliono utilizzare le delle risorse sono la parte di path fanno viaggiare in rete pacchetti nuove funzioni bisogna inclu- locale della URL (o URI), ovvero, formati da alcune intestazioni dere il file HTTPlib.h (al posto in sostanza, il nome del file in di MwiFi.h) ed istanziare un una URL completa (Es.: http:// oggetto HTTP: www.mio.it/miapag.html). In que- Listato 1 sto ambito minimale, le risorse da richiamare saranno identifica- #include <HTTPlib.h> WEBRES rs[8]= HTTP WIFI; te dal solo nome senza estensione. { Per cui si tratta di associare una {“/index”,pindex}, Riguardo alla connessione con pagina memorizzata con il suo {“/Analog”,panalog}, {“/RDigital”,rdigital}, un access-point e alla gestione nome Internet corrispondente {“/Wdigital”,wdigital}, dei socket, tutto rimane come (per esempio “/indice”). {“/wdig”,wdig}, {“/Pwm”,pwmpage}, prima (forse ora sceglieremo la In realtà questa pagina non si {“/PwmSet”,pwmset}, porta 80); ma anche questa volta spedirà da sola e quindi bisogna {“/End”,sessend} }; dobbiamo decidere se far fare ad collegare il nome della risorsa Arduino le veci di un server (que- con una funzione che si occuperà void loop() sta volta Web Server) o quelle di di spedirla. Per rendere il mecca- { WIFI.getRequest(csocket,8,rs); un client che accede ad un Appli- nismo più automatico possibile, è : cation Web Server (come Tomcat, stata predisposta una struttura o Elettronica In ~ Dicembre 2013 / Gennaio 2014 29 Listato 3 void pwmset(char *query) tag utilizzato è il carattere @; ne { char *pwmval; va usato uno solo a prescindere pwmval=WIFI.getParameter(query,strlen(query),”PWM10”); dalla lunghezza della stringa che if (pwmval!=NULL) {int pv;sscanf(pwmval,”%d”,&pv); lo dovrà sostituire. Nell’esempio analogWrite(10,pv);d10=pv;} che trovate nel Listato 2, tre tag pwmval=WIFI.getParameter(query,strlen(query),”PWM11”); if (pwmval!=NULL) saranno sostituiti da altrettante {int pv;sscanf(pwmval,”%d”,&pv); stringhe che rappresentano i va- analogWrite(11,pv);d11=pv;} lori di tre input digitali. Alla fun- pwmpage(query); } zione sendDynResponse() vanno passati l’array delle stringhe e più esattamente un tipedef chia- e rileverà la modalità utilizzata la relativa dimensione. Per far mato WEBRES; questa struttura GET o POST, comportandosi di sì che Arduino agisca in seguito è formata dall’accoppiata di due conseguenza (i dati sono conte- campi: il nome della risorsa ed nuti in modo diverso) e lancerà il nome della funzione (che in C la funzione corrispondente alla corrisponde ad un indirizzo). Si richiesta (o un messaggio “Not tratta, quindi, di formare tante Found”). La call-back function coppie nome-funzione da pas- pindex() sopra descritta, però sare alla funzione getRequest(), non fa altro che spedire in rispo- che si occuperà di lanciare la fun- sta una pagina html statica, cioè zione corretta (call-back function), definita in modo fisso. o spedire un messaggio standard Arduino Web Server definito così “Not Found” di risposta, nel caso non è molto utile, perché si pre- il nome non combaci con alcuno suppone di poterlo utilizzare per di quelli predisposti. leggere valori forniti da sensori Nel Listato 1 è presentato l’esem- (Fig. 4) o attivare uscite (Fig. 5); Fig. 3 - Home page del Web Server. pio della costruzione di un array per ottenere ciò, la pagina html di 8 strutture WEBRES ed il suo di risposta deve essere costruita inserimento nella chiamata alla sul momento, inserendo i valori funzione getRequest(). Ogni che si vogliono leggere. Deve, secondo campo delle strutture insomma, essere una pagina corrisponde alla call-back fun- dinamica. Ma sarebbe troppo ction che getRequest() lancerà. dispendioso costruire, all’interno La call-back function si dovrà delle call-back function, la pagina preoccupare di spedire il buffer tutta intera; per semplificare il corrispondente alla pagina scelta compito si è previsto di definire ed il suo prototipo prevede che la pagina “una tantum” come sia di tipo void (cioè che ritorni una pagina statica, potendo nulla) ed abbia un solo argo- però inserire al suo interno dei Fig. 4 mento; in pratica, un puntatore tag (etichette segna-posto) nella ad una null-terminated string posizione che si vuole completa- fornita dal chiamante (si veda re al momento. Per questo scopo più avanti): esiste, in alternativa a sendRe- sponse(), la funzione sendDyn- Response() che si preoccupa di void pindex(char *query) rintracciare e sostituire i tag men- { tre spedisce la pagina. La sostitu- WIFI.sendResponse(csocket,pagei zione avviene sequenzialmente ndex); andando a scorrere un array di } stringhe predisposto sul momen- Riassumendo: ponendo getRe- to; quindi il primo tag incontrato quest() nel loop, essa si occuperà viene sostituito con la prima di tutta la gestione della richiesta stringa dell’array e così via. Il Fig. 5 30 Dicembre 2013 / Gennaio 2014 ~ Elettronica In

See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.