Comments
Description
Transcript
Controllo di stabilità per elicottero
Istituto Tecnico Industriale Statale Galileo Galilei Anno scolastico 2011/2012 Via G. Galilei, 16 – 31015 Conegliano (TV) Controllo di stabilità per elicottero Galet Matteo classe 5° A - ART/ET Tesina per gli esami di Maturità Sommario 1) STORIA DELL’ELICOTTERO -3- 2) IL FUNZIONAMENTO -5- I. Il principio -5- II. Il giroscopio -5- III. Lo “swashplate” -6- 3) IL PROGETTO -8- I. I sensori -8- II. I servocomandi -9- III. Il motore - 10 - IV. La batteria LiPo - 10 - V. La comunicazione - 11 - 4) LA REALIZZAZIONE - 12 - I. Il telecomando - 12 - II. L’elettronica di bordo - 20 - 5) CONCLUSIONI (LA PROVA SUL CAMPO) - 26 - 6) RINGRAZIAMENTI - 27 - 7) BIBLIOGRAFIA - 28 - -2- 1) Storia dell’elicottero I primi progetti di macchine per il volo verticale sono stati ritrovati tra i documenti di Leonardo Da Vinci: già alla fine del 1400 egli aveva elaborato una serie di disegni riguardanti quella da lui chiamata “vite aerea”. Leonardo aveva infatti cercato di applicare all’aria il principio della vite di Archimede (usata per spostare l’acqua di un fiume o lago ad un’altezza superiore): la macchina doveva essere composta da una spirale rotante che spostasse l’aria verso il basso e di conseguenza facesse staccare da terra il rudimentale velivolo. Sebbene Leonardo costruì qualche piccolo prototipo, non ci sono prove che una di La “vite aerea” di Leonardo queste macchine abbia mai funzionato. Quello di cui Leonardo non tenne conto inoltre è la rotazione inversa della fusoliera data dalla rotazione della spirale: la macchina, appena staccatasi da terra, avrebbe cominciato a ruotare su se stessa, rendendola incontrollabile e facendola ritornare immediatamente al suolo. Gli studi continuarono quando Sir George Cayley, un ingegnere inglese, sviluppò nei primi dell’800 una serie di macchine che usavano due rotori contro-rotanti per librarsi in aria; come mezzo propulsivo usava una striscia di gomma attorcigliata, che svolgendosi permetteva qualche secondo di rotazione. I suoi studi influenzarono il parigino Alphonse Pénaud, il quale creò un giocattolo ponendo sullo stesso asse i due rotori, creando di fatto il capostipite di quelli che oggi sono gli elicotteri a rotori coassiali. Pénaud battezzò il suo prototipo “Helicoptère“, parola coniata qualche anno prima e formata dalle due L’Helicoptère di Pénaud parole greche: helix (ricurvo, attorcigliato) e pteron (ala). Uno di questi giocattoli, regalato dal padre ai fratelli Wilbur e Orville Wright, fu la scintilla che li fece appassionare alla conquista del volo. Il primo vero elicottero capace di librarsi in aria autonomamente fu sviluppato dall’italiano Enrico Forlanini: nel 1878, spinto da un motore a vapore, il prototipo si alzò verticalmente fino ad un’altezza di 12 metri, dove stazionò per una ventina di secondi, prima di ritornare al suolo. Nel 1885, un giornalista statunitense donò la cospicua somma di 1000 dollari a Thomas Edison, allo scopo di condurre esperimenti per lo sviluppo del volo. Edison costruì un elicottero che usava della nitrocellulosa per alimentare il motore; purtroppo il prototipo andò distrutto in un’esplosione, ed uno dei suoi collaboratori riportò gravi ustioni. In base a questi esperimenti, Edison formulò che sarebbe servito un motore con rapporto di potenza quasi pari ad un cavallo per chilogrammo per poter sollevare un elicottero. -3- Nel 1920 l’argentino Raúl Pateras-Pescara dimostrò come fosse possibile variare l’inclinazione delle pale per aumentare o diminuire la spinta, ed inoltre il rotore del suo prototipo poteva essere inclinato leggermente in avanti per poter avanzare senza necessità di eliche aggiuntive. Il suo elicottero però non era abbastanza potente nemmeno per sollevare il proprio peso. Una data storica è il 1936: Henrich Focke, con l’aiuto di un collaboratore, costruì un velivolo ad ala rotante che superò per prestazioni tutti i predecessori: il FW-61 fu il primo elicottero prodotto in piccola serie, e fu adottato durante la Seconda Guerra Mondiale, assieme al fratello maggiore FA-223 ed al Fl-282, dalla Germania nazista, che lo impiegò per ricognizioni, trasporto e recupero dei feriti. I Il Focke-Wulf Fw 61 bombardamenti degli Alleati impedirono alla Germania di produrre elicotteri su larga scala, nonostante i primi esemplari si rivelarono validi. Negli USA, il primo elicottero prodotto in 100 esemplari fu l’R-4, progettato da Igor Sikorsky per la marina americana, seguito dai modelli R-5 ed R-6; gli Alleati ne usarono un totale di 400 durante la Seconda Guerra Mondiale per trasferire truppe in luoghi impervi. Nel campo civile, la prima azienda a costruire elicotteri fu la Bell Aircraft: gli ingegneri Bell applicarono ad un rotore a due pale una barra con due masse agli estremi, posta a 90° rispetto alle pale principali; questo dispositivo, chiamato flybar, si mantiene sempre parallelo al suolo, stabilizzando il volo. Grazie alla sua semplicità costruttiva, l’esemplare fu prodotto in molti paesi con il nome di Bell 47, e rimase in uso per quasi 30 anni. Una turbina per elicotteri Il Bell 47 Nel 1951 avvenne una svolta nel campo dell’ aviazione: Charles Kaman modificò il suo K-225 montandovi un motore turboalbero da jet. Questo adattamento permise di generare una grande potenza con un peso ridotto rispetto ad un normale motore a pistoni; la turbina infatti non dispone di un pesante monoblocco e di molti altri accessori presenti nei motori convenzionali. Qualche anno dopo molte case costruttrici cominciarono a produrre in larga scala elicotteri a turbina. -4- 2) Il funzionamento I. Il principio “Il fatto è che gli elicotteri sono diversi dagli aeroplani. Un aeroplano per sua natura vuole volare […], un elicottero non vuole volare, è mantenuto in aria da una moltitudine di forze e controlli che lavorano in opposizione; se c’è un qualsiasi disturbo in questo delicato equilibrio, l’elicottero smette di volare, immediatamente ed in modo disastroso.“ [autore ignoto] A differenza degli aeroplani, gli elicotteri sfruttano uno o più rotori invece di ali fisse. Possono così decollare verticalmente, muoversi in ogni direzione e rimanere in volo stazionario (in gergo hovering). Le forze in gioco La spinta prodotta dalle ali di un aereo dipende da due cose: l’angolo di attacco delle ali e la velocità dell’aria rispetto all’ala stessa. Per avere la spinta necessaria per volare, quindi, l’aeroplano ha bisogno di avanzare ad una certa velocità. Nel caso di un elicottero, questo movimento in avanti è prodotto dalla rotazione delle pale del rotore; quando l’angolo di attacco delle pale (chiamato in questo caso “passo”), supera un determinato valore, la spinta verso l’alto prodotta dal rotore supera il peso dell’elicottero, che decolla in modo verticale. La rotazione del rotore principale causa però, secondo la terza legge di Newton (“ad ogni azione corrisponde una reazione uguale e contraria”), una rotazione opposta della fusoliera. Negli elicotteri a doppio rotore, questi ruotano in senso opposto, bilanciandosi a vicenda. Se il rotore principale è uno solo, però, è necessario un piccolo rotore (detto di coda) che produca una forza tale da contrastare la rotazione della fusoliera. II. Il giroscopio La spinta del rotore di coda però non può essere fissa: deve adattarsi alle variazioni di velocità del rotore principale, siano esse dovute al comando del pilota o a fattori esterni; per questo un elemento fondamentale in ogni elicottero è il giroscopio: questo strumento consente di misurare la velocità angolare a cui sta ruotando l’elicottero, permettendo di agire poi sul rotore di coda per contrastare la rotazione. -5- I primi giroscopi meccanici (o inerziali) sfruttavano la rotazione continua di un piccolo volano: per effetto giroscopico, infatti, la massa in rotazione tende a mantenere sempre il proprio asse parallelo a sé stesso; quando la carcassa del giroscopio è fatta ruotare, l’asse (che vi è fissato con un cardine) tende a Giroscopio meccanico (sx) ed elettronico per modelli RC (dx) rimanere nella posizione precedente, ruotando sul cardine; a questi è collegato un potenziometro, che rileva la rotazione dell’asse e la trasmette all’attuatore del rotore di coda per correggere l’imbardata. I moderni giroscopi elettronici invece sono realizzati con un chip di silicio in cui sono implementate delle piastre vibranti: la rotazione del chip fa avvicinare o allontanare le piastre, variando la frequenza di questa micro vibrazione, che poi sarà convertita in tensione ed elaborata per il controllo della coda. I giroscopi da modellismo incorporano anche un microprocessore, che ha il compito di inviare al servomotore di coda un segnale che contempla la correzione del giroscopio stesso e vi somma il comando del pilota, che può decidere di ruotare su se stesso l’elicottero. III. Il die di un giroscopio elettronico Lo “swashplate” Il cuore del rotore principale è il piatto oscillante (swashplate): inventato agli inizi del 1900, questo elemento è stato alla base dello sviluppo dell’elicottero, in quanto permette di trasferire i comandi impartiti dal pilota dalla fusoliera (relativamente ferma) alle pale del rotore principale (le quali ruotano a migliaia di giri al minuto). Sezione di uno swashplate Il piatto è composto da due elementi: il piatto esterno ed il piatto interno, uniti da un cuscinetto che permette unicamente il movimento rotatorio dell’uno rispetto all’altro. Il piatto esterno, fermo rispetto alla fusoliera, è attuato dai comandi di pilotaggio: lo swashplate si inclina così in base alla direzione in cui il pilota vuole muovere il velivolo; questa inclinazione si riflette sul piatto interno, che ruota assieme al resto del rotore e quindi alle pale: con dei tiranti, l’inclinazione è trasferita alle pale, con 90° di anticipo, variandone l’angolo di incidenza (passo) dinamicamente in base alla posizione della singola pala lungo i 360°. -6- Nell’esempio di un inclinazione a sinistra, il pilota sposta il joystick inclinando lo swashplate verso sinistra; quando le pale passano in corrispondenza degli 0°, il relativo tirante, che si trova già sui 90°, sarà spinto verso l’alto, e agirà incrementando il passo della pala, che risulterà inclinata verso sinistra. Swashplate da modellismo (sx) e di un elicottero commerciale (dx) Allo stesso modo l’altra pala, posta a 180°, si trova in una situazione speculare, con il passo decrementato; in questo modo entrambe le pale sono inclinate verso sinistra, trascinando il velivolo in quella direzione. Il passo delle pale Posizione dei tiranti di comando (A, B, C) Inclinando il piatto oscillante si ottengono dunque gli spostamenti a destra, sinistra, in avanti ed all’indietro: l’insieme dei comandi che controllano questi spostamenti è chiamato “passo ciclico”; per aumentare la spinta verso l’alto è necessario agire su quello che si chiama “passo collettivo” (o semplicemente pitch): il piatto oscillante è sollevato rispetto al piano neutro, così da ottenere un incremento di passo comune per tutte le pale, indipendentemente dalla loro posizione angolare. Dalla molteplicità di comandi da azionare si capisce come il compito del pilota non sia affatto semplice, dovendosi giostrare con gas, passo ciclico, passo collettivo e coda; inoltre va tenuto conto di come anche il minimo soffio di vento influisca notevolmente sul movimento del velivolo (specialmente negli elicotteri più leggeri), costringendo il pilota a continui aggiustamenti e controlli di posizione, in special modo durante la manovra di hovering: spesso infatti è necessario mantenere l’elicottero fermo a mezz’aria il più a lungo possibile per consentire la salita o la discesa di truppe o per eseguire operazioni di salvataggio. Elicottero della guardia costiera irlandese -7- 3) Il progetto Come si è visto, è estremamente difficile per il pilota mantenere la padronanza completa del velivolo; l’idea alla base del progetto è che, come è possibile mantenere la coda dell’elicottero ferma nonostante la rotazione impressa dal rotore alla fusoliera, altresì è possibile stabilizzare il velivolo in modo da mantenerlo fermo in hovering (quasi) senza l’intervento del pilota. Partendo da un elicottero radiocomandato da modellismo comunemente reperibile (in questo caso un T-Rex 450 prodotto dalla Taiwanese Align), sono stati sviluppati e costruiti gli apparati elettronici sia nel radiocomando che a bordo. Il T-Rex 450 pronto al volo I. I sensori Innanzitutto il modello ha bisogno, per sua natura, di un giroscopio: l’esemplare utilizzato, di marca ignota, è stato recuperato da un elicottero giocattolo; va alimentato a 3.3v e fornisce in uscita una tensione di circa 1.38v quando la velocità angolare è 0. Se la velocità aumenta, la tensione aumenta (o diminuisce, a seconda del senso di rotazione) proporzionalmente. Il giroscopio Per il movimento laterale (destra/sinistra, avanti/indietro, su/giù) è necessario un sensore simile al giroscopio, poiché costruito con la stessa tecnica: un accelerometro. Il dispositivo usato è un MMA7361 di produzione Freescale; anch’esso va alimentato a 3.3v (in realtà la breakout board su cui è montato dispone di un regolatore per alimentarlo anche a 5v) e presenta tre uscite analogiche per i tre assi (X, Y, Z) con lo 0g a metà della tensione di alimentazione. Inoltre ha diversi pin di configurazione: Self-test: input, esegue l’omonima funzione G-select: input, usato per impostare la scala (±1.5g, ±6g) Pin-out dell’accelerometro 0g-detect: output, si attiva quando tutti e tre gli assi sono MMA7361 prossimi allo 0g (rileva la condizione di caduta libera) Sleep: input, porta l’accelerometro in una condizione di basso consumo (3µA) -8- Il sensore HC-SR04 In previsione di decolli e atterraggi automatizzati, è stato montato sotto all’elicottero un sensore ad ultrasuoni: questo sfrutta il tempo di andata e ritorno di un segnale sonoro a 40kHz per misurare la distanza da terra, permettendo di abbassare il passo collettivo automaticamente a mano a mano che ci si avvicina al suolo, così da atterrare in maniera dolce. La scelta è caduta su un HC-SR04, in quanto economico e adatto alle nostre necessità: Alimentazione: 5v Distanza misurabile: 2cm ~ 4mt Precisione: ±2mm Gestione del sensore ad ultrasuoni La lettura di questo sensore va fatta inviando sul pin TRIG un impulso alto di almeno 10uS, così da far emettere l’onda sonora; quando il sensore rileva l’onda riflessa, alza il pin ECHO per il tempo trascorso tra l’emissione sonora ed il suo ritorno (tECHO); misurando questo tempo e conoscendo la velocità del suono (340m/sec), si può risalire alla distanza a cui si trova l’oggetto che ha riflesso l’onda (il terreno nel nostro caso): ( ( ) ) Il due al denominatore è dato dal fatto che il tempo tECHO comprende sia il tempo di andata che di ritorno del segnale, e quindi è doppio rispetto a quello che ci interessa. II. I servocomandi Per muovere lo swashplate ed il meccanismo che regola il passo del rotore di coda sono usati dei servomotori da modellismo, precisamente dei Corona 928BB: sviluppano 1.8kg*cm a 5v. L’albero di uscita di questi particolari attuatori non ruota completamente, ma solo di 90° o 180° a seconda del modello: si comandano inviando un impulso che spazia da Servo da modellismo 1000 a 2000 uS, corrispondenti rispettivamente alle posizioni di minimo e massimo. Inoltre hanno il vantaggio di implementare un controllo di posizione ad anello chiuso: all’interno vi è un circuito a microprocessore, un driver per il motore ed un potenziometro solidale all’albero di uscita; il micro elabora la posizione dell’albero letta dal potenziometro e la confronta con il segnale in input, per poi azionare il motore in modo che l’albero si porti nella posizione voluta e quindi i due valori coincidano. Temporizzazione del segnale di controllo -9- III. Il motore I due rotori sono azionati da un motore brushless TP 2415-07T della Tower Pro. Sviluppa 3850 giri per volt (circa 42000 RPM con gli 11v della LiPo) e consuma massimo 35 Ampere. Il termine brushless significa senza spazzole: nei motori in corrente continua tradizionale, le spazzole servono a portare la corrente all’avvolgimento presente sul rotore; questi motori invece hanno tre avvolgimenti sullo statore, ed il rotore è un magnete permanente ad alto potenziale; si pilotano con tre onde sinusoidali sfasate di 120°, in un modo che ricorda i motori trifase utilizzati in elettrotecnica. I motori brushless, rispetto ai tradizionali motori in corrente continua, hanno un rendimento molto elevato, e data la mancanza di spazzole e collettore, vi sono meno parti soggette ad Il motore brushless e l’ESC usura. Nel campo del modellismo sono largamente utilizzati in aerei, elicotteri ed automobili, nonostante la loro diffusione sia cominciata solo una quindicina di anni fa: anche se la struttura dei brushless è più semplice di quella di un motore a spazzole, infatti, l’elettronica di controllo è decisamente più complicata. Per ogni fase è necessario un ponte H, e tutti e tre i ponti devono essere pilotati in sincronia. Al giorno d’oggi, con lo sviluppo di mosfet ad alte prestazioni e microprocessori sempre più potenti, i controller sono diventati versatili ed economici: gli ESC (Electronic Speed Controller) si occupano non solo di pilotare il motore nel verso giusto, ma gestiscono anche funzioni di soft-start, freno elettronico e arresto d’emergenza in caso di mancanza di segnale di input. Nel progetto è impiegata una ESC da 40A della Turnigy; il pilotaggio avviene analogamente a quello di Struttura interna del motore e fasatura per la rotazione un servomotore: la velocità è regolata da un impulso che va da 1000uS (motore fermo non frenato) a 2000uS (velocità massima). IV. La batteria LiPo Per alimentare un motore a 11v che consuma 35 Ampere sono necessarie batterie particolari: le LiPo. Questa sigla, che significa Lithium-ion Polymer, indica una categoria di accumulatori ad alte prestazioni molto usate nel modellismo: hanno una densità energetica molto elevata, che permette di realizzare batterie dal peso contenuto. Le celle hanno una tensione nominale di 3.7v, ma variano da 4.2v completamente cariche a 3v quando sono scariche; non devono in ogni caso scendere sotto i 2.7v, La batteria usata - 10 - pena il danneggiamento dei componenti interni. La peculiarità principale di questi accumulatori è la capacità di scarica molto elevata: nel nostro caso la batteria impiegata è una 3 celle da 2200mAh 55C, il che significa che può essere scaricata a 55 volte la capacità nominale; possiamo quindi assorbire fino a 55 x 2200mAh = 121A (121A x 11v = 1331 watt!). Ovviamente la batteria si scaricherà molto più in fretta (in un minuto circa a 121A). E’ necessario maneggiare con cura questo tipo di batterie, in quanto tendono ad esplodere nel caso in cui siano sovraccaricate, danneggiate o in condizione di corto circuito. V. La comunicazione Una parte cruciale del progetto è la comunicazione radio: si è optato per la banda dei 2.4GHz, perché i moduli implementano nativamente un algoritmo anti-intrusione, vitale nel nostro caso, dove ogni problema di comunicazione porta quasi certamente allo schianto al suolo del velivolo. I moduli scelti sono due transceiver NRF24L01+ della Nordic, usati in questo caso solamente come trasmettitore uno e ricevitore l’altro; sono alimentati a 3.3v e comunicano tramite bus SPI. Si collegano alla scheda principale con un Il modulo NRF24L01+ connettore a 10 pin, su cui (oltre ai 4 pin per l’alimentazione) vi sono: CE: Input, attiva le modalità di ricezione (RX) o di trasmissione (TX) CSN: Input, Chip Select del bus SPI SCK: Input, Clock SPI MOSI: Input, Slave Data Input SPI MISO: Output, Slave Data Output SPI IRQ: Output, pin di richiesta interrupt (attivo basso) Per la gestione del modulo e della comunicazione sono state utilizzate le librerie scritte da Brennen Ball e reperibili sul sito diyembedded.com . - 11 - 4) La realizzazione I. Il telecomando Il telecomando è stato recuperato da un elicottero giocattolo: costruire un contenitore abbastanza ergonomico da essere impugnato con naturalezza non è infatti alla nostra portata. E’ stato dunque necessario modellare la scheda elettronica in base alla forma ed alla dimensione dell’originale; la seconda scheda presente sul telecomando supporta i tasti accessori, ed è stata lasciata inserita e collegata alla nuova per impieghi futuri. Il telecomando prima delle modifiche (sx) e la scheda trasmittente originale (dx) La scheda pulsanti montata (sx) e la nuova scheda appena prima di essere installata (dx) Uno dei due switch ed il connettore USB - 12 - Come si nota dalle ultime due immagini, sono stati aggiunti due interruttori a levetta, in una posizione pratica da azionare con gli indici mentre i pollici sono impegnati sui joystick; inoltre, sul lato inferiore, è stato sistemato un connettore USB mediante il quale il telecomando può essere riprogrammato e attraverso il quale può scambiare dati con il software su PC. Il cuore del telecomando è un PIC18F2550: il motivo della scelta è determinato dalla possibilità di comunicare con un PC tramite la porta USB, in modo nativo e con funzionalità Plug-and-Play; il software su PC riconosce quando il micro è collegato e di conseguenza inizia a scambiarvi dati. In aggiunta, alimentando il circuito con lo switch sinistro premuto, il PIC entra in modalità bootloader, che permette (con un apposito programma sul PC) di installarvi un nuovo firmware direttamente da USB, senza bisogno di un programmatore. Inoltre il clock interno arriva a ben 48MHz. Questo microcontrollore dispone di 12 ingressi analogici, quattro dei quali dedicati ai controlli: ogni joystick possiede infatti due potenziometri (uno per l’asse verticale, l’altro per quello orizzontale), che vengono letti dall’A/D del micro e trasmessi all’elicottero; un Uno dei due joystick ingresso è riservato alla lettura dello stato di carica della batteria, ed un altro alla lettura dei pulsanti di servizio. Questi sono infatti collegati in modo da fornire in uscita una tensione diversa per ognuno, così da poter discriminare quale pulsante è premuto semplicemente leggendo con l’A/D il valore di tensione e confrontandolo con determinati intervalli. Lo schema del telecomando è riportato più avanti; partendo dall’alto troviamo il regolatore switching per l’alimentazione (MCP1601): questo permette di abbassare i circa 4.5v provenienti dalle 3 batterie AA ad una tensione di 3.3v, senza eccessivi surriscaldamenti e con un rendimento che varia dall’80% al 90%. Un regolatore lineare, oltre a dissipare inutilmente in calore molta più potenza, avrebbe avuto qualche difficoltà ad operare correttamente dato che la differenza di tensione tra ingresso ed uscita è di soli 4.5v – 3.3v = 1.2v. Le resistenze R7 ed R8 impostano la tensione di uscita: sul pin FB (feedback) infatti devono essere presenti 0.8v alla tensione di uscita desiderata (3.3v); imponendo R8 a 22k, si ricava R7: 10 pulsanti, un unico ingresso ( ) ( ) Arrotondando al valore commerciale più vicino abbiamo scelto una resistenza da 68k. Allo stesso modo abbiamo calcolato il valore di R9 ed R10 per portare in input al micro la tensione della batteria, così da poter leggere con il convertitore A/D integrato lo stato di - 13 - carica della stessa: a batterie completamente cariche la tensione non supera mai i 5v, e dato che il micro accetta in ingresso tensioni fino a Vcc (3.3v), abbiamo deciso che il partitore dovesse dividere per 2 il valore di tensione; si sono scelti 2 valori uguali per R9 ed R10 (10k). In alto a sinistra vi sono i due switch a levetta: sono collegati con delle resistenze di pull-down, in modo che qualsiasi cosa accada (si rompa lo switch, si scolleghi il cavetto), il segnale di ingresso sia a 0; questo perché uno dei due switch è utilizzato per l’attivazione del “pilota automatico”, e deve essere attivato solo ed esclusivamente se il pilota preme volontariamente lo switch relativo. Accanto si nota il transistor che attiva il buzzer preoscillato: è sufficiente fornirgli alimentazione e questo genera un tono ad una frequenza fissa. Infine vi sono i connettori per il modulo radio e per il display; questo elemento, che non risponde a nessun protocollo standard, era già presente nel telecomando recuperato, ed è stato fatto funzionare con una procedura chiamata “reverse engineering”: in pratica, sono stati analizzati i segnali di controllo che la scheda originale inviava al display, e sono stati “decifrati” generandone di nuovi, cambiandone un bit alla volta ed osservando il risultato che ne derivava. Grazie a questo procedimento si è giunti a capire che il display comunica con un segnale di abilitazione (CS_D), un segnale di clock (WR) e un segnale dati (DAT). Per prima cosa si abilita il display, portando a 0 il CS_D; poi si inviano degli impulsi di clock, e per ogni impulso il display legge lo stato del dato e accende o spegne il relativo segmento del display; poi si riporta ad 1 il CS_D. Vi sono un totale di 137 impulsi di clock in una trasmissione; circa un centinaio sono direttamente relativi a segmenti, dei restanti non è nota la funzione. Il PCB della scheda principale del telecomando Il display in funzione - 14 - Lo schema elettrico del circuito installato nel telecomando - 15 - Il software nel microcontrollore è scritto usando il Microchip C18, un compilatore realizzato appositamente per questa serie di PIC; è disponibile gratuitamente in versione Student, con delle limitazioni che però non hanno influito sulla compilazione del codice sorgente. La finestra di lavoro dell’MPLAB IDE Il programma inizia con la configurazione delle porte del PIC, degli interrupt e delle varie periferiche interne; il tutto è eseguito nella funzione InitializeSystem(), che comprende le righe analizzate in seguito. La prima routine configura il modulo SPI per operare a 1/16 della frequenza di clock (48MHz/16 = 3MHz), nella modalità definita come 00 e campionando il dato a metà clock: OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI Una volta aperta la comunicazione via SPI, si procede inizializzando il modulo radio, utilizzando una funzione contenuta nelle apposite librerie; con il primo “false” si decide di disabilitare la ricezione (in pratica si configura il modulo come trasmettitore), si specifica la lunghezza della payload (10 byte) e si abilita l’auto-ACK: in questo modo, se il ricevente riceve correttamente i pacchetti, manda automaticamente un segnale di acknowledge; in caso contrario il trasmettitore re-invia i pacchetti persi; questo ciclo si ripete fino all’arrivo dell’ACK o del raggiungimento del numero massimo di tentativi definito nel file di configurazione della radio. nrf24l01_initialize_debug(false, 10, true); Il passo successivo è la configurazione del convertitore A/D interno; si sceglie la frequenza di lavoro (48MHz/64 = 750kHz), il risultato a 10 bit giustificato a destra, il tempo di campionamento, il canale (CH0), si disabilita il relativo interrupt, si settano i riferimenti di tensione tra Vcc e Vss, si configurano quali pin devono essere analogici e quali digitali. - 16 - OpenADC( ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_20_TAD, ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 10 ); Gli ingressi sono letti in sequenza nella funzione get_analogs(); all’interno vi è la porzione di codice seguente, ripetuta per ciascun canale. Come prima cosa si seleziona il canale da leggere, poi si avvia la conversione e si attende che termini; a questo punto, ReadADC()ritorna il valore letto, in una scala da 0 a 1023; questo dato, perché possa essere contenuto in una variabile ad 8 bit, va diviso per 4 (o traslato di 2 bit verso destra come in questo caso); se l’asse risulta invertito, basta sottrarre a 255 questa variabile. SetChanADC(ADC_CH2); ConvertADC(); // Wait for completion while( BusyADC() ); joy_left_hor = 255 - (ReadADC() >> 2); Uno dei canali contiene l’informazione relativa ai pulsanti premuti sulla scheda ausiliaria; nella funzione get_switches(), oltre a leggere i due interruttori a levetta, si decodifica quale di questi pulsanti è attivato, confrontando il valore con degli intervalli al cui interno si suppone essere la tensione di uscita di ogni singolo pulsante, con un po’ di margine data la tolleranza dei componenti. if ((analog_switch > 70) && (analog_switch <= 95)) switches2.b4 = 1; else switches2.b4 = 0; I bit delle variabili switches1 e switches2 rappresentano lo stato di un pulsante ciascuno. Procedendo nel codice, troviamo la parte di trasmissione radio; le variabili da inviare vengono caricate su di un array, che sarà spedito dalla funzione successiva: stream_tx[0] stream_tx[1] stream_tx[2] stream_tx[3] stream_tx[4] stream_tx[5] = = = = = = SW1; SW2; joy_left_vert; joy_left_hor; joy_right_vert; joy_right_hor; nrf24l01_write_tx_payload(stream_tx, 10, true); //transmit received char over RF In seguito, con la funzione display_setup() si preparano i dati nelle variabili apposite per essere visualizzate sul display, e con display_update() si invia un refresh al display con i nuovi elementi da visualizzare. La funzione successiva, Process_USB_IO(), si occupa di comunicare con il PC tramite la porta USB: dopo aver controllato di essere effettivamente collegato al PC, il micro controlla se sono stati ricevuti dati; in questo caso carica il buffer di trasmissione con le variabili che è necessario trasmettere al PC e le trasmette; successivamente svuota e ripristina il buffer di lettura per rendere possibile un successivo invio di dati da parte del PC. - 17 - if(!HIDRxHandleBusy(USBOutHandle)) //Check if data was received { if(!HIDTxHandleBusy(USBInHandle)) { ToSendDataBuffer[0] = joy_left_vert; ToSendDataBuffer[1] = joy_left_hor; ToSendDataBuffer[2] = joy_right_vert; ToSendDataBuffer[3] = joy_right_hor; ToSendDataBuffer[4] = 0; ToSendDataBuffer[5] = switches1.string; ToSendDataBuffer[6] = switches2.string; ToSendDataBuffer[7] = batt_ctrl; USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64); } USBOutHandle=HIDRxPacket(HID_EP,(BYTE*)&ReceivedDataBuffer,64); } L’applicazione sul PC è sviluppata con Microsoft Visual C++ 2010, anch’esso disponibile in versione Express gratuita per uso personale. L’interfaccia contiene cinque trackbar, che corrispondono ognuna ad un asse di ciascuno dei due joystick; la quinta indica il livello della batteria del telecomando, espresso anche in volt. In basso vi sono cinque caselle numeriche, per impostare manualmente le relative cifre sul display del telecomando, in attesa di sviluppi futuri; vi sono poi molte checkbox, che ricalcano la posizione dei vari pulsanti sul telecomando: quando un pulsante è premuto, la relativa casellina si attiva. Il programma è gestito da due eventi, ReadWriteThread e FormUpdateTimer: il primo è un processo separato ed a sé stante che si occupa della lettura e scrittura su USB; il secondo è un interrupt periodico (ogni 10mS circa) che aggiorna L’interfaccia del programma sul PC l’interfaccia con i valori ricevuti dall’USB. Per la lettura dell’USB, il software controlla che il telecomando sia collegato, e procede leggendo il buffer in ingresso; come si può notare, ad eccezione di INBuffer[0] che in realtà non ha alcuna funzione, l’ordine in cui arrivano i byte è scelto all’invio dal firmware del PIC. //INBuffer[0] joy_left_vert = INBuffer[1]; joy_left_hor = INBuffer[2]; joy_right_vert = INBuffer[3]; joy_right_hor = INBuffer[4]; switches1 = INBuffer[6]; switches2 = INBuffer[7]; batt_ctrl = INBuffer[8]; - 18 - Per impostare il valore delle trackbar, si usa la seguente espressione: joy_left_vert_bar->Value = joy_left_vert; dove joy_left_vert è la variabile a 8 bit che contiene il valore dell’asse Y del joystick sinistro, e joy_left_vert_bar è la relativa trackbar; per scrivere il valore della variabile nella casella di testo si usa la funzione di conversione Convert::ToString : joy_left_vert_label->Text = Convert::ToString(joy_left_vert); dove joy_left_vert_label è la casella di testo. Per attivare o meno le checkbox dei pulsanti, si usa una bit-mask: questa prevede un AND binario tra la variabile che contiene tutti i pulsanti e il singolo bit del pulsante che ci interessa: exit_b->Checked = (switches2 & 4); mode_b->Checked = (switches2 & 8); In questo caso exit_b e mode_b sono le checkbox dei pulsanti EXIT e MODE. - 19 - II. L’elettronica di bordo L’elicottero scelto per il progetto, nonostante i quasi 700mm di apertura alare del rotore principale, ha una fusoliera di dimensioni relativamente piccole: si è reso necessario miniaturizzare il più possibile la scheda che vi deve essere installata, facendo uso di componenti SMD dove possibile. L’integrato principale è il microcontrollore, un dsPIC33FJ12GP202; si è deciso di usare la famiglia dsPIC della Microchip perché offre una serie di vantaggi e di possibilità superiori rispetto ai precedenti PIC16 o PIC18: Architettura a 16 bit: permette di usare registri più completi e supporta nativamente le operazioni con variabili intere; Peripheral Pin Select: le periferiche interne non sono Il dsPIC, cuore dell’elicottero collegate a pin specifici, ma possono essere riconfigurate per quasi ogni pin; in fase di sbroglio del PCB, è così possibile scegliere dei percorsi più brevi e agevoli per le piste; 118 vettori di interrupt: ogni interrupt ha la sua routine, non si è limitati solo alle routine di alta e bassa priorità come nei PIC18; L’ADC integrato arriva a 500ksamples al secondo con una risoluzione di 12bit, addirittura ad 1 milione se usato a 10bit. Inoltre la presenza del core DSP permette di implementare filtri ed algoritmi in modo molto veloce, senza gravare particolarmente sulla velocità di esecuzione del programma principale. Il PCB della scheda di controllo dell’elicottero La scheda installata a bordo - 20 - Lo schema elettrico della scheda a bordo dell’elicottero - 21 - Per analizzare lo schema partiamo dalla sezione di alimentazione, in alto: il primo integrato è un regolatore switching (LM2596) in configurazione step-down, che abbassa la tensione della batteria (11v) a 5v, una tensione adatta ai servomotori ed al sensore ad ultrasuoni. In questo caso uno switching è indispensabile, in quanto i quattro servomotori consumano anche 800mA l’uno in stallo; la potenza dissipata in calore da un regolatore lineare sarebbe: ( ) ( ) E’ evidente che con una ventina di watt in calore il regolatore avrebbe bisogno di un dissipatore notevole, cosa improponibile da montare su di un elicottero. Le resistenze R5 ed R11 impostano la tensione di uscita: sul pin FB (feedback) devono essere presenti 1.23v alla tensione di uscita desiderata (5v); imponendo R11 a 22k, si ricava R5: ( ) ( ) Quindi abbiamo optato per una resistenza da 68k. Lo stesso concetto è stato usato per le resistenze R1 ed R2, le quali formano un partitore che divide la tensione in ingresso per 4.57, in modo che quando la batteria è completamente carica (12.6v) all’A/D del micro arrivi una tensione massima di 12.6v/4.57 = 2.76v, entro i 3.3v dell’alimentazione, usata come riferimento superiore dal convertitore. La seconda parte della sezione di alimentazione è costituita dallo stesso regolatore a 3.3v che è stato impiegato nel telecomando; in questo caso è alimentato dai 5v dell’LM2596. Il condensatore C6 serve a stabilizzare la tensione di alimentazione del core del dsPIC: sebbene sia alimentato a 3.3v, questo chip contiene un regolatore interno a 2.5v per alcune parti sensibili che non sopportano tensioni superiori. L’accelerometro ed il giroscopio sono collegati al micro tramite resistenze da 100Ω, per prevenire eventuali corti circuiti quando, durante l’inizializzazione del micro, le porte sono ancora temporaneamente configurate come uscite. JP12 è il connettore ICSP (In-Circuit Serial Programming), ovvero l’interfaccia necessaria a programmare il micro senza rimuoverlo dalla scheda (fattibile con i PIC con package DIP, impossibile con quelli in SMD come in questo caso). Sulla destra si notano i collegamenti al modulo radio ed al sensore ad ultrasuoni, oltre ad un LED per il debug ed alle connessioni per i servomotori e l’ESC. I relativi connettori, per carenza di spazio, sono posti su una piccola scheda ausiliaria montata sopra alla principale. - 22 - Il firmware è stato scritto con il Microchip C30, un linguaggio sviluppato appositamente per i PIC32 ed i dsPIC; come per il C18, anch’esso è disponibile in versione gratuita a uso personale. Il codice parte con le dovute inizializzazioni, tra cui il settaggio del convertitore A/D (Init_ADC()) e del modulo SPI (Init_SPI()), che verrà configurato con gli stessi parametri già visti per il telecomando. La radio sarà questa volta configurata come ricevente, abilitando la ricezione (il primo true): nrf24l01_initialize_debug(true, 10, true); Prima di entrare nel loop principale, si imposta il fattore di correzione del giroscopio: esso infatti, quando non vi è movimento, non presenta una tensione di uscita esattamente a metà della tensione di alimentazione; è quindi necessario introdurre manualmente una correzione: gyro_drift = 113; Una volta in loop, il programma legge prima di tutto i comandi inviati dal telecomando, con il codice seguente (raggruppato per comodità nella funzione radio_get()): if(nrf24l01_irq_rx_dr_active()) { LED = 1; nrf24l01_read_rx_payload(stream_rx, 10); //get the payload auto_en = stream_rx[0]; mot_en = stream_rx[1]; pitch = stream_rx[2] - 128; pitch = pitch / 128; rudder = stream_rx[3] - 128; rudder = - rudder / 128; elevator = stream_rx[4] - 128; elevator = elevator / 128; aileron = stream_rx[5] - 128; aileron = aileron / 128; } else { LED = 0; mot_en = false; auto_en = false; aileron = 0; elevator = 0; rudder = 0; pitch = 0; esc = 0; } nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01 Brevemente, se nel buffer della radio ci sono dei dati (le posizioni dei joystick), la funzione nrf24l01_read_rx_payload() li sposta nell’array stream_rx[], da dove saranno poi spostati a loro volta nelle relative variabili; il valore di ogni asse viene poi convertito da una variabile ad 8 bit senza segno (0 ~ 255) ad una in virgola mobile, con uno span che va da 1 a +1: questo permette di avere il valore di ogni asse sottoforma di coefficiente, per agevolare e rendere più immediate anche all’occhio umano le successive operazioni. Nel caso in cui non si sia ricevuto nulla dalla radio, tutti i comandi sono portati alla posizione - 23 - neutra ed il motore è arrestato; questo per prevenire che l’elicottero vada fuori controllo in assenza di segnale, non solo distruggendosi ma soprattutto recando danni a cose e persone (le dimensioni e la velocità del rotore sono sufficienti a decapitare una persona!). Per lo stesso motivo, il motore dipende anche da uno dei due interruttori a levetta montati sul telecomando: si può così disabilitarlo pur mantenendo gli altri comandi attivi, per effettuare veloci operazioni a terra senza il rischio che un urto accidentale della leva del gas possa mettere in rotazione le eliche. Nella fase successiva del programma, viene fatta una media di 30 letture per ciascun asse dell’accelerometro, così da avere un risultato meno influenzato da rumore o vibrazioni; l’accelerazione viene poi inserita nelle apposite variabili (acc_x, acc_y, acc_z), portando la gamma di valori da -1 a +1. Con il codice seguente si introduce il pilota automatico, ma solo se è attivato il relativo switch sul telecomando; in pratica viene sommata ai comandi di aileron ed elevator impartiti dal pilota (che governano gli spostamenti laterali) l’accelerazione rilevata, che andrà ad agire in maniera opposta, contrastando la tendenza del velivolo a scivolare: if (auto_en == true) { elevator = 0.5*acc_x + 0.5*elevator; aileron = 0.5*acc_y + 0.5*aileron; } Gli addendi sono dimezzati perché il valore finale non deve superare il campo -1 ~ +1, altrimenti porterebbero in saturazione i calcoli successivi. Il passo successivo è la lettura del giroscopio; viene effettuata anche in questo caso una media tra 30 letture, ed al risultato viene applicato il fattore di correzione impostato in precedenza; il tutto è moltiplicato per 6 per aumentare la sensibilità: gyro = 6*(media_letture - 512 + gyro_drift) / 512; if (gyro < gyro if (gyro > gyro -1) = -1; +1) = +1; Quando le accelerazioni angolari sono molto elevate, il valore di gyro può eccedere la gamma -1 ~ +1: le due istruzioni “if” fanno in modo che questo caso non si verifichi mai. Adesso è possibile inviare alla coda il comando per correggere la rotazione della fusoliera: coda = 0.5*gyro + 0.5*rudder; Anche in questo caso gli addendi sono stati dimezzati per prevenire valori esterni a -1 ~ +1. Una volta ottenuti i valori di aileron, elevator, pitch e coda con cui pilotare i servi, è necessario implementare quello che in gergo è chiamato CCPM (Cyclic-Collective Pitch Mixing). - 24 - Il principio per cui è necessario il CCPM I servomotori sono infatti collegati allo swashplate con angoli di 120° l’uno dall’altro; il comando dell’aileron però deve agire sull’asse destra-sinistra, e l’elevator sull’avanti-indietro. Il pitch invece deve alzare o abbassare il piatto agendo in contemporanea sui 3 servomotori. Per ottenere questo mix, si procede con tre formule, una per ogni servomotore; per ciascuno si moltiplicano aileron ed elevator per il coseno dell’angolo formato tra il comando stesso e la posizione del servo lungo i 360° del piatto: quando l’angolo tra i due è 0° il comando avrà incidenza massima, a 90° non influirà sul movimento di quel servomotore; ogni fattore è moltiplicato per un coefficiente, in modo da variare il peso di un comando rispetto all’altro. Per il passo collettivo, è sufficiente aggiungere a tutti i servomotori lo stesso valore di pitch, anche in questo caso ridotto per non mandare in saturazione la formula. servo_a = 0.5 * ( 0.7*elevator * COS_0 + 0.7*aileron * COS_90 ) + 0.6 * pitch; servo_b = 0.5 * ( 0.7*elevator * COS_120 + 0.7*aileron * COS_210 ) + 0.6 * pitch; servo_c = 0.5 * ( 0.7*elevator * COS_240 + 0.7*aileron * COS_330 ) + 0.6 * pitch; Come per tutte le variabili precedenti, anche il risultato di queste formule è compreso tra -1 e +1; non resta che preparare il segnale di controllo per i servi, espresso in microsecondi: servo_a = servo_a * 300; servo_b = servo_b * 300; servo_c = servo_c * 300; Adesso le variabili assumono un valore da -300 a +300 uS; il prossimo passo è aggiungere il valore di centratura del servocomando: out_servo_a = 1500 - (signed int)(servo_a + 0.5); out_servo_b = 1500 + (signed int)(servo_b + 0.5); out_servo_c = 1500 - (signed int)(servo_c + 0.5); Le variabili out_servo_a, out_servo_b e out_servo_c sono intere a 16bit senza segno; con le espressioni sopra riportate vi si adattano i valori in virgola mobile di servo_a, servo_b e servo_c; in questo modo gli interi assumono un valore che può andare da 1200 a 1800 uS, ovvero le posizioni di massimo e minimo volute per i servocomandi. Nel nostro caso si è reso necessario invertire il servo A ed il C (anteponendo il segno “-“ nella formula), in quanto agivano specularmente a come avrebbero dovuto: questo è da ricondursi alla posizione del servo stesso nel montaggio sulla fusoliera. Adesso, dopo un veloce controllo per evitare di inviare comandi fuori scala al servo, si generano gli impulsi: si mette a 1 il pin collegato al servocomando (SERVO_A), si attende il tempo specificato in out_servo_a e si torna mettere a 0 il pin SERVO_A. - 25 - if (out_servo_a > out_servo_a if (out_servo_a < out_servo_a 1900) = 1900; 1100) = 1100; SERVO_A = 1; delay_us(out_servo_a); SERVO_A = 0; Questo procedimento va ripetuto per tutti e 4 i servi e per il controllo della velocità del rotore principale, che come limiti ha però 1000 e 1900 (gas da 0 a 90%). 5) Conclusioni (la prova sul campo) Nel complesso il progetto si è rivelato molto affidabile; nella scrittura dei vari software si è cercato di tenere in considerazione ogni possibile circostanza, prevedendo le relative risposte da parte del sistema. La comunicazione radio, di cruciale importanza, ha dimostrato di essere robusta e di garantire un discreto range: nelle distanze di test, non superiori ai 40 metri, non si sono mai verificate cadute di segnale o interferenze. L’uso della porta USB, sebbene abbia richiesto ricerche approfondite prima di trovare delle librerie valide ed al contempo di facile utilizzo, è stato molto importante, perché ha permesso di effettuare debugging in tempo reale, inviando e ricevendo i parametri necessari con un semplice click del mouse. Purtroppo, nei primi test, alcuni problemi meccanici hanno causato una flessione anomala di una delle pale del rotore principale, che è finita per collidere ad alta velocità con il tubo di coda, causando seri danni alla coda stessa e ad altri particolari; nulla di irreparabile, ma sicuramente un segnale di come queste macchine, seppur di dimensioni contenute, possano rendersi estremamente pericolose se non perfettamente funzionanti. Il tubo di coda piegato Per quanto riguarda la stabilizzazione, il sistema si è dimostrato valido, offrendo una notevole riduzione degli sforzi al pilota, che ora deve solamente preoccuparsi di indirizzare l’elicottero nella direzione desiderata, senza dover controllare continuamente i micro-spostamenti del velivolo. Con ulteriori studi è ipotizzabile la creazione di un vero pilota automatico, che sfrutti anche il sensore ad ultrasuoni per seguire in completa autonomia delle sequenze e delle rotte programmate da terra; per quanto concerne il progetto corrente, possiamo ritenerci soddisfatti dello sforzo compiuto e del tempo speso. - 26 - 6) Ringraziamenti Questo progetto mi ha tenuto impegnato per tutto l’anno scolastico, e con me anche chi mi stava vicino; innanzitutto ringrazio la mia famiglia per il (notevole) contributo economico conferito, ed in particolar modo mio padre, che con i suoi consigli (e la sua diffidenza verso l’elettronica) mi ha aiutato a migliorare continuamente il prototipo (pur di smentire i suoi timori!). Inoltre desidero ringraziare i docenti Visentin Michele, per l’assistenza generale e soprattutto nella programmazione, e Severin Diego, per i pratici consigli conferiti (e per aver riportato alla base l’elicottero diverse migliaia di volte durante i test!). Un ringraziamento particolare va anche ad Alessandro Della Libera, che mi ha sopportato come (pericoloso) “compagno di bancone” durante i primi esperimenti in laboratorio. - 27 - 7) Bibliografia http://en.wikipedia.org/wiki/Helicopter http://www.align.com.tw/alignhtml/EN/index.html http://www.bellhelicopter.com/ http://blog.diyembedded.com/ http://www.microchip.com/ http://www.hobbyking.com - 28 -