Modelli tridimensionali con Eagle3D
Link Articolo Originale: http://www.grix.it/viewer.php?page=9321
Eagle3D è un add-in di Eagle, un diffuso programma per la progettazione di circuiti stampati.
Mentre la versione freeware di Eagle consente di realizzare circuiti stampati doppia faccia non più grandi di 100 x 80 mm (per circuiti più estesi e/o con più strati bisogna usare le versioni commerciali), Eagle3D è un programma opensource senza limitazioni che può essere scaricato da qui.
Questa guida utilizza la versione 20110101 dello scorso gennaio.
Esistono altre guide per l'utilizzo di Eagle3D, compresa questa che è stata pubblicata su Grix.
Esse sono utilissime a chi vuole utilizzare Eagle3D partendo da zero, perchè spiegano passo dopo passo tutte le azioni necessarie a ottenere un'immagine di un circuito.
Non ho tuttavia trovato informazioni utili ottenere i risultati avanzati che mi servivano (es. prototipo virtuale del prodotto finito, analisi delle interferenze, personalizzazioni del contenitore...).
Questa guida spiega ciò che le altre guide non spiegano a sufficienza (a mio parere), sperando che i grixiani possano apprezzarla e trarne vantaggio.
A differenza delle altre guide, che utilizzano semplici progetti, ho scelto un progetto reale: un modem GSM che sto realizzando con un modulo Cinterion MC55i.
Per questo motivo troverete solo i file POV-Ray del progetto.
Il modem GSM è progettato per un contenitore da un modulo DIN, le cui caratteristiche si trovano qui.
Il modem GSM è formato da due schede perpendicolari tra loro e tenute insieme da connettori a pettine.
La scheda di base utilizza componenti a foro passante, per la necessità di usare morsetti a vite compatibili con il contenitore.
La scheda verticale utilizza invece solo componenti a montaggio superficiale, perché altrimenti i pin presenti sul lato saldature ridurrebbero lo spazio a disposizione.
Eseguendo l'user language program 3d40.ulp (versione di Eagle precedente alla 4.1) o 3d41.ulp oppure 3d50.ulp (versione Eagle 4.1 e successive), Eagle3D processa il layout della scheda e crea un file .pov per POV-Ray.
Aprendo tale file con POV-Ray ed eseguendolo, si ottiene una prima immagine della scheda.
Il risultato è poco incoraggiante...
I cilindri rossi che Eagle3D colloca al centro dei componenti sconosciuti indicano che bisogna creare il modello 3D di tutti i componenti!
La prima alternativa per creare un modello 3D consiste nel "riciclare" uno già presente nella libreria di Eagle3D ma che ha un altro nome.
Come ben spiegato nella guida già presente in Grix, il "riciclo" viene attivato selezionando l'opzione "modelli assegnati dall'utente". In questo caso è possibile riutilizzare tre modelli, ottenendo il seguente risultato.
Mancano all'appello un connettore MiniDIN a 9 poli, un supercondensatore e un PTC (fusibile auto-ripristinabile).
La definizione di nuovi modelli 3D scoraggia i nuovi utenti perché bisogna utilizzare il linguaggio di descrizione della scena di POV-Ray (l'uso di alcuni layer di Eagle per definire nuovi modelli lo ho scartato perché il risultato non è adatto alle mie esigenze).
Se si è fortunati, si possono scaricare ed usare modelli scritti da qualcun altro (es. display led a 7 segmenti), ma purtroppo ciò non è possibile in questo caso...
Questa è l'unica vera limitazione di Eagle3D: una libreria con pochi componenti rispetto a quelli in commercio.
Invece di "gettare la spugna" come accade a molti neofiti, creiamo il modello tridimensionale dei componenti mancanti.
Iniziamo da quello più semplice: il supercondensatore.
Per creare il modello, sono necessarie le dimensioni del componente che si trovano spesso in fondo al relativo datasheet o che vanno ricavate da un componente "reale".
E' anche possibile "ispirarsi" alle macro di Eagle3D che, in questo caso, sono contenute in cap.inc
La macro CAP_DIS_ELKO_GRND
sembra adatta ai nostri scopi, dato che definisce un "normale" condensatore elettrolitico di cui possiamo indicare rispettivamente:
- la scala del testo (espansione/compressione lungo l'asse corrispondente)
- la dimensione del testo (altezza in mm)
- la distanza tra i pin
- il raggio del corpo cilindrico del condensatore
- l'altezza del corpo cilindrico del condensatore
- il raggio dei pin
- il valore del condensatore
Superata la difficoltà nell'interpretare i commenti scritti in tedesco (un altro difetto di Eagle3D), aggiungendo le seguenti righe a cap.inc, si ha il modello 3D del supercondensatore.
#macro CAP_DIS_SG_H(value)
object{CAP_DIS_ELKO_GRND(<6.39,20,6.39>,1,10,9.5,5,0.5,value)}
#end
Tale modello va bene per la versione orizzontale del supercondensatore, ma non per la versione verticale che è stata usata.
Dopo aver studiato (ed interpretato) il codice scritto dagli altri, bisogna quindi "darsi da fare" con tastiera...
Il risultato non sarà identico a quello di chi è più esperto di noi; tuttavia per i nostri scopi è sufficiente che gli ingombri siano giusti.
#macro CAP_DIS_SG_BODY(d,h)
#local r = 0.5 * d;
union{
difference{
union{
torus{r-.5,.5 translate<0,0.5*h-.25,0>}
cylinder{<0,-0.5*h+.25,0><0,.5*h-.25,0> r}
torus{r-.5,.5 translate<0,-.5*h+.25,0>}
cylinder{<0,-0.5*h,0><0,0.5*h,0> r-1}
}
cylinder{<0,.5*h-.25,0><0,.5*h+.25,0> r-2}
cylinder{<0,-.5*h-.25,0><0,-.5*h+.25,0> r-2}
pigment{Gray20}
}
cylinder{<0,.5*h-.25,0><0,.5*h,0> r-2 texture{col_silver} }
cylinder{<0,-.5*h,0><0,-.5*h+.25,0> r-2 texture{col_silver} }
}
#end
#macro CAP_DIS_SG_V(value)
union{
object{CAP_DIS_SG_BODY(19,4.5) rotate<0,0,90> translate<0,10.25,0> }
box{<-2.5,0,-3><-2.25,9.5,3> texture{col_silver} }
box{<-2.6,-4,-.5><-2.4,0,.5> texture{col_silver} }
box{<2.25,0,-3><2.5,9.5,3> texture{col_silver} }
box{<2.4,-4,-.5><2.6,0,.5> texture{col_silver} }
}
#end
La macro CAP_DIS_SG_V
realizza il modello 3D del supercondensatore. Essa utilizza la macroCAP_DIS_SG_BODY
per il corpo cilindrico e quattro istruzioni per i terminali.
Per comprendere i listati, bisogna accennare a due operatori di geometria solida costruttiva.
L'operatore union
permette di "incollare" due o più solidi, cioè il solido risultante sarà dato dall'unione dei solidi originari.
L'operatore difference
sottrae al primo solido (o composizione di solidi) i restanti solidi. Per esempio, un foro in un solido può essere ottenuto dalla differenza con un cilindro.
Detto ciò, analizziamo la macro CAP_DIS_SG_BODY
.
#local r = 0.5 * d;
definisce la variabile locale r
e la inizializza con il raggio del corpo cilindrico (metà del diametro).
Il corpo del supercondensatore è definito come l'unione del corpo cilindrico (Gray20
= 80% di nero) con i due terminali metallici superiore ed inferiore (gli ultimi due cilindri dell'unione).
Il corpo cilindrico è dato da un cilindro con gli spigoli arrotondati a cui sono stati eliminati 0.25 mm di materiale per fare spazio ai terminali metallici.
Il cilindro con gli spigoli arrotondati è ottenuto sommando un toro, un cilindro di raggio r
, un altro toro ed un cilindro di raggio r-1
.
Il seguente disegno dovrebbe chiarire perché è stata usata questa apparentemente strana definizione.
clicca per ingrandire |
I due cerchi magenta sono la sezione verticale del toro superiore, quelli verdi sono relativi al toro inferiore, mentre i rettangoli blu e rosso sono le sezioni dei restanti cilindri.
Per completare il modello 3D del supercondensatore vanno aggiunti i due terminali. Essi sono dati semplicemente dall'unione di due parallelepipedi (istruzione box
).
Anche se è possibile migliorare ulteriormente l'aspetto estetico (es. estremità dei pin arrotondate, scritte sul corpo del condensatore, ...), è meglio sfruttare subito quello che si ha.
Per aggiungere il modello alla libreria di Eagle3D, è sufficiente aggiungere una riga al file 3Dusrpac.dat
Dato che la struttura della riga è complicata, per non sbagliare è sufficiente attivare nuovamente l'opzione "modelli assegnati dall'utente" e scegliere un condensatore elettrolitico qualsiasi.
Terminata la generazione del file .pov, in fondo al file 3dusrpac.dat ci sarà la riga che ci interessa modificare.
SG_V:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:CAP_DIS_ELKO_AXIAL_15MM_5MM(:Elko 15,24mm Pitch, 5mm Durchmesser:Elko 15,24mm Pitch, 5mm Diameter
Dato che bisogna chiamare la nostra macro al posto di CAP_DIS_ELKO_AXIAL_15MM_5MM
, è sufficiente modificare il nome della macro, ottenendo:
SG_V:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:CAP_DIS_SG_V(:Panasonic SG V:
SG_H:0:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:CAP_DIS_SG_H(:Panasonic SG H:
Il risultato di queste modifiche è incoraggiante...
Per completare l'immagine del circuito, passiamo al PTC.
Il modello 3D del PTC è formato dalla macro RES_DIS_RECT_BODY
che è chiamata dalla macroRES_DIS_POLYFUSE
.
Rispetto al modello del supercondensatore, la struttura è un po' più complicata.
Il corpo del PTC è realizzato dall'istruzione superellipsoid
che crea un parallelepipedo con i bordi arrotondati.
Le restanti istruzioni aggiungono i terminali al corpo componendo i cilindri associati ai tratti lineari ed i tori associati ai tratti ad arco con delle sfere che rappresentano i punti di raccordo.
// L = body length
// W = body width
// H = body height
// P = wire pitch
// S = wire spacing
// R = wire radius
// D = distance from board
// T = terminal wire type (0 = straight, 1 = round stops)
// C = body colour
#macro RES_DIS_RECT_BODY(L,W,H,P,S,R,D,T,C,value)
union{
#local dx = 0.5*sqrt(S*S-P*P);
#local dy = 0.5*H-(H/L)*dx;
#local dz = 0.5*P;
// body
superellipsoid{<0.2,0.2> scale<L/2,H/2,W/2> pigment{C}}
// wires from body to terminals
cylinder{<-.25*L,.25*H,.5*(R-W)><dx,-dy,-dz> R pigment{C}}
cylinder{<dx,-.5*H,.5*(R-W)><dx,-dy,-dz> R pigment{C}}
sphere{<dx,-dy,-dz> R pigment{C}}
cylinder{<.25*L,.25*H,dz><-dx,-dy,dz> R pigment{C}}
cylinder{<-dx,-.5*H,dz><-dx,-dy,dz> R pigment{C}}
sphere{<-dx,-dy,dz> R pigment{C}}
// terminals
#if ( T = 0 )
cylinder{<-dx,-.5*H-D-pcb_height-pin_length,dz><-dx,-.5*H,dz> R texture{col_silver}}
cylinder{<dx,-.5*H-D-pcb_height-pin_length,-dz><dx,-.5*H,-dz> R texture{col_silver}}
#else
cylinder{<-dx,-.5*H-.1*D,dz><-dx,-.5*H,dz> R texture{col_silver}}
sphere{<-dx,-.5*H-.1*D,dz> R texture{col_silver}}
intersection{
torus{.4*D,R rotate<90,0,0>}
box{<0,-.5*D,-R><D,.5*D,R>}
translate<-dx,-.5*(H+D),dz>
texture{col_silver}
}
cylinder{<-dx,-.5*H-D-pcb_height-pin_length,dz><-dx,-.5*H-.9*D,dz> R texture{col_silver}}
sphere{<-dx,-.5*H-.9*D,dz> R texture{col_silver}}
cylinder{<dx,-.5*H-.1*D,-dz><dx,-.5*H,-dz> R texture{col_silver}}
sphere{<dx,-.5*H-.1*D,-dz> R texture{col_silver}}
intersection{
torus{.4*D,R rotate<90,0,0>}
box{<-D,-.5*D,-R><0,.5*D,R>}
translate<dx,-.5*(H+D),-dz>
texture{col_silver}
}
cylinder{<dx,-.5*H-D-pcb_height-pin_length,-dz><dx,-.5*H-.9*D,-dz> R texture{col_silver}}
sphere{<dx,-.5*H-.9*D,-dz> R texture{col_silver}}
#end
// value
text{
ttf besch_font value 0.01, 0 scale<2,2,2> translate<-.4*L,.3*H,-.5*W>
}
rotate<0,90,0>
translate<0,.5*H+D,0>
}
#end
#macro RES_DIS_POLYFUSE(value)
object{RES_DIS_RECT_BODY(11,2.4,13.2,2.54,5,.3,4,1,Orange,value)}
#end
Modificando opportunamente il file 3dusrpac.dat, si otterrà la seguente immagine.
Per completare il modello, è necessario descrivere il connettore MiniDIN a 9 poli.
#macro CON_MINI_DIN_BODY_H(pins)
union{
difference{
union{
box{<-7.5,0,0><7.5,13,2>}
box{<-7,0,2><7,12.75,12.9>}
}
difference{
cylinder{<0,6.5,-.1><0,6.5,6> 6}
cylinder{<0,6.5,-.2><0,6.5,7> 4.75}
}
box{<-4.25,4,-.1><-2.75,2.25,6>}
box{<4.25,4,-.1><2.75,2.25,6>}
box{<-4,10,-.1><4,11,6>}
box{<-3,11,-.1><3,11.75,6>}
#switch (pins)
#case (9)
box{<-1.5,3.5,-.1><-.5,4.5,6>}
box{<.5,3.5,-.1><1.5,4.5,6>}
box{<-3.5,5.5,-.1><-2.5,6.5,6>}
box{<-1.5,5.5,-.1><-.5,6.5,6>}
box{<.5,5.5,-.1><1.5,6.5,6>}
box{<2.5,5.5,-.1><3.5,6.5,6>}
box{<-3,7.5,-.1><-2,8.5,6>}
box{<-1,7.5,-.1><0,8.5,6>}
box{<2,7.5,-.1><3,8.5,6>}
#break;
#end
pigment{Gray20}
}
difference{
cylinder{<0,6.5,0><0,6.5,6> 5.75 }
cylinder{<0,6.5,-.1><0,6.5,7> 5.5 }
box{<-2,8,-1><2,15,7>}
texture{col_silver}
}
difference{
prism{ -.1, .1,
9,
<-1,1>,<-1,-1>,<-1.5,-2>,<-.5,-3.5>,<.5,-3.5>,<1.5,-2>,<1,-1>,<1,1>,<-1,1>
}
box{<-.25,-.5,-4><.25,.5,2>}
rotate<-90,0,0>
translate<0,0,4.7>
texture{col_silver}
}
superellipsoid{<.25,.25> scale<.25,2,1> translate<-7.25,-1.5,5.5> texture{col_silver}}
superellipsoid{<.25,.25> scale<.25,2,1> translate<7.25,-1.5,5.5> texture{col_silver}}
box{<-7.25,0,2><-7,12.75,9> texture{col_silver}}
box{<-7.25,12.75,2><7.25,13,9> texture{col_silver}}
box{<7,0,2><7.25,12.75,9> texture{col_silver}}
#switch (pins)
#case (9)
cylinder{<4,-3.5,8.5><4,0,8.5> .45 texture{col_silver}}
cylinder{<.7,-3.5,8.5><.7,0,8.5> .45 texture{col_silver}}
cylinder{<-.7,-3.5,8.5><-.7,0,8.5> .45 texture{col_silver}}
cylinder{<-4,-3.5,8.5><-4,0,8.5> .45 texture{col_silver}}
cylinder{<4,-3.5,11><4,0,11> .45 texture{col_silver}}
cylinder{<2,-3.5,11><2,0,11> .45 texture{col_silver}}
cylinder{<0,-3.5,11><0,0,11> .45 texture{col_silver}}
cylinder{<-2,-3.5,11><-2,0,11> .45 texture{col_silver}}
cylinder{<-4,-3.5,11><-4,0,11> .45 texture{col_silver}}
#end
}
#end
#macro CON_MINI_DIN_9()
object{CON_MINI_DIN_BODY_H(9) }
#end
La macro CON_MINI_DIN_BODY_H
gestisce (per ora) solo il caso con 9 pin, dato che gli altri sono gestiti dalla macro "ufficiale" di Eagle3D.
La struttura di CON_MINI_DIN_BODY_H
è tuttavia complicata per ottenere un sufficiente realismo.
Per non appesantire questa guida, non descriverò i dettagli di CON_MINI_DIN_BODY_H
.
Chiunque fosse interessato ad essi, può chiederli a me, oppure può usare il metodo con cui ho fatto le mie prove.
Aprendo ogni file .inc di Eagle3D con POV-Ray e facendone il ray-tracing, si visualizza il modello contenuto nelle ultime righe dello stesso.
Commentando quello contenuto originariamente nel file ed aggiungendo
object{ CON_MINI_DIN_9() rotate<0,0,0> translate<0,0,0>}
si seleziona la macro CON_MINI_DIN_9
, si ruota il risultato come indicato dall'istruzione rotate
e lo si trasla come indicato da translate
.
In questo modo è possibile osservare il risultato sotto ogni punto di vista (un effetto analogo effetto può essere ottenuto modificando la posizione del punto di vista agendo su camera
elook_at
).
A questo punto, per capire l'effetto di ogni istruzione, è sufficiente commentare il codice della macro che non interessa e vedere il risultato delle modifiche.
Il modello 3D della scheda base è ora completo.
Per ottenere l'immagine che ci interessa è possibile agire sul punto di vista e sulle luci della scena.
Il procedimento è un po' macchinoso (e lento se eccediamo con la risoluzione dell'immagine finale), ma è dovuto alla scelta di utilizzare il ray-tracing per produrre immagini foto-realistiche.
Anche per la scheda verticale, il risultato iniziale prodotto da Eagle3D non è incoraggiante...
Il "riciclo" dei modelli di Eagle3D consente di non preoccuparsi di un SC70_5, ma il risultato cambia poco...
Come al solito, iniziamo dalle cose più semplici: il condensatore nel package CKG45N che si trova in basso.
Tale condensatore è formato da due condensatori ceramici sovrapposti tenuti insieme da una lamierina metallica forma di L.
Con le dimensioni del datasheet e con la macro CAP_SMD_CHIP_GRND
a disposizione, non è complicato creare la macro CAP_SMD_CKG45N
.
#macro CAP_SMD_CKG45N(color_sub)
union{
object{CAP_SMD_CHIP_GRND(5,4,2.5,.5) rotate<0,90,0>translate<0,.5,0>}
object{CAP_SMD_CHIP_GRND(5,4,2.5,.5) rotate<0,90,0>translate<0,3,0>}
box{<-2,0,1.75><2,.25,2.75> texture{col_silver}}
box{<-2,.25,2.5><2,5.5,2.75> texture{col_silver}}
box{<-2,0,-2.75><2,.25,-1.75> texture{col_silver}}
box{<-2,.25,-2.75><2,5.5,-2.5> texture{col_silver}}
}
#end
Il risultato della macro è il seguente.
Il modello dell'induttore SMD consente di spiegare l'istruzione prism
.
Dato che un induttore WE_TPC_XLH è essenzialmente un prisma a base ottagonale, per i nostri fini (controllo interferenze) è inutile avere un modello molto dettagliato (es terminali, punto di incollaggio, scritta, ...), ma è sufficiente rappresentare l'involucro esterno a forma ottagonale.
#macro L_WE_TPC_XLH(value)
prism{ 0 3.8 9
<-5,2.5>,<-2.5,5>,<2.5,5>,<5,2.5>,<5,-2.5>,<2.5,-5>,<-2.5,-5>,<-5,-2.5>,<-5,2.5>
pigment{Gray10}
}
#end
L'istruzione prism
genera un prisma estrudendo nella direzione Y una polilinea definita nel piano XZ.
Essa ha vari parametri: il primo è la quota iniziale (in Y) del prisma, il secondo è la quota finale (in Y) del prisma, il terzo è il numero di vertici della polilinea.
Seguono le coordinate dei vertici nel piano XZ.
L'immagine della scheda verticale diventa quindi
Il successivo passo consiste nel modellare i connettori a pettine.
Essi sono a montaggio superficiale e corrispondono al modello 800-xx-008_40_001101 dalla PreciDip.
#macro CON_PRECIDIP_800_XX_BODY(N)
union{
// body
box{<-1.27*N,0,-2.95><1.27*N,2.54,0> pigment{Gray05}}
// pins
#local qx=-1.27*N+1.27;
#local i = 0;
#while ( i < N )
cylinder{<qx,1.27,-7.42><qx,1.27,-2.95> .38 texture{T_Gold_1A}}
sphere{<qx,1.27,-7.42> .38 texture{T_Gold_1A}}
sphere_sweep{ linear_spline 4,
<qx,1.27,0>, .3,
<qx,1.27,.5>, .3,
<qx,0,1.5>, .3,
<qx,0,2.85>, .3
texture{col_silver}
}
#local qx = qx + 2.54;
#local i = i + 1;
#end
}
#end
#macro CON_PRECIDIP_800_XX_008_40_001101()
object{CON_PRECIDIP_800_XX_BODY(8)}
#end
Dato che con poco è possibile modellare un connettore generico con N pin, il modello 3D utilizza la macro specifica CON_PRECIDIP_800_XX_008_40_001101
e la macro generica CON_PRECIDIP_800_XX_BODY
.
La struttura della macro CON_PRECIDIP_800_XX_BODY
è semplice.
Oltre al corpo (istruzione box
) comprende un ciclo che genera un pin alla volta.
Esso è formato da due parti: il contatto dorato (istruzioni cylinder
e sphere
) e il terminale (istruzione sphere_sweep
).
L'effetto dell'istruzione sphere_sweep
è identico alla costruzione manuale dei terminali che è stata utilizzata in RES_DIS_RECT_BODY
: un filo a sezione circolare dato da una sfera che si muove lungo la polilinea indicata.
Per completare l'immagine, concentriamo l'attenzione su i due led ad emissione laterale.
Volendo riciclare il massimo possibile di quello che Eagle3D mette a disposizione, è necessario creare una macro con gli stessi parametri di un led standard, per poter consentire all'utente la scelta del colore del led.
La macro DIODE_SMD_LED_MICROSIDELED
è tutto quello che resta da implementare.
//***************
// Micro SIDELED
//***************
// C = colour
// T = transparency
// H = height
#macro DIODE_SMD_LED_MICROSIDELED(C,T,H)
union{
// body
difference{
prism{0,1.2,7,<.65,1.1>,<-.1,1.1>,<-.35,1>,<-.35,-.9>,<-.1,-1.1>,<.65,-1.1>,<.65,1.1>}
prism{.25,.95,5,<.7,.9>,<.25,.7>,<.25,-.7>,<.7,-.9>,<.7,.9>}
pigment{Gray85}
}
// LED
prism{ .25,.95,5,<.6,.9>,<.25,.7>,<.25,-.7>,<.6,-.9>,<.6,.9> pigment{C filter T}}
// pins
box{<-.125,0,1.125><.125,.7,1.75> texture{col_silver}}
box{<-.125,0,-1.75><.125,.7,-1.255> texture{col_silver}}
}
#end
Il corpo del led è ottenuto dalla differenza di due prismi: il primo è il corpo esterno, il secondo è la zona occupata dal corpo riflettente che successivamente sarà "riempito" con un materiale semi-trasparente del colore del led.
I terminali metallici (due box) completano il modello 3D del led.
Le cose si complicano quando bisogna descrivere il porta-SIM.
#macro SIM_M20_PIN()
union{
box{<-2,0,-.4><-.5,.25,.4> texture{col_silver}}
box{<-.5,0,-.4><-.25,.75,.4> texture{col_silver}}
box{<-.5,.75,-.4><3,1,.4> texture{col_silver}}
union{
box{<3,.75,-.4><6,1,.4>}
difference{
cylinder{<6.9,1,-.4><6.9,1,.4> .9}
cylinder{<6.9,.75,-.4><6.9,1,.4> .65}
box{<5,-1,-.5><8,.75,.5>}
}
texture{T_Gold_1A}
}
}
#end
#macro SIM_TRAY()
union{
difference{
box{<0,-1.9,-9.4><27.35,0,9.4>}
cylinder{<7.25,-2,.2><7.25,.1,.2>3}
}
box{<-.95,-2.5,-10><0,.6,10>}
pigment{Gray10}
}
#end
#macro CON_SIM_M20(sim)
union{
box{<0,0,0><26,3,1> pigment{Gray10}}
box{<0,2.25,1><26,3,1.5> pigment{Gray10}}
difference{
box{<5.4,0,1><26,1.4,22>}
box{<8,-.1,13.9><13.4,2,15.3>}
box{<5,.75,13.9><14,2,15.3>}
box{<18,-.1,13.9><23.4,2,15.3>}
box{<23,.75,13.9><27,2,15.3>}
box{<8,-.1,11.36><13.4,2,12.76>}
box{<5,.75,11.36><14,2,12.76>}
box{<18,-.1,11.36><23.4,2,12.76>}
box{<23,.75,11.36><27,2,12.76>}
box{<8,-.1,8.82><13.4,2,10.22>}
box{<5,.75,8.82><14,2,10.22>}
box{<18,-.1,8.82><23.4,2,10.22>}
box{<23,.75,8.82><27,2,10.22>}
box{<8,-.1,1.52><13.4,2,2.92>}
box{<5,.75,1.52><14,2,2.92>}
box{<18,-.1,1.52><23.4,2,2.92>}
box{<23,.75,1.52><27,2,2.92>}
pigment{Gray10}
}
box{<26,0,4><28,3,6> pigment{Gray10}}
box{<0,0,4><5.4,1.4,6> pigment{Gray10}}
box{<0,0,16.5><5.4,1.4,22> pigment{Gray10}}
box{<26,0,18.5><31,3,25> pigment{Gray10}}
box{<11,0,22><26,3,25> pigment{Gray10}}
box{<0,1.4,20><26,3,22> pigment{Gray10}}
box{<0,2.25,19><26,3,20> pigment{Gray10}}
// positioning pins
cylinder{<12.5,-.7,5.86><12.5,0,5.86> 1 pigment{Gray10}}
cylinder{<12.5,-.7,22><12.5,0,22> 1 pigment{Gray10}}
// eject button
difference{
union{
box{<-1.4,0,22><4.6,3,25>}
cylinder{<-2.6,1.5,23.5><-1.4,1.5,23.5> 1}
box{<-2.6,1.5,22.5><-1.4,3,24.5>}
}
sphere{<-2.6,1.5,23.5> .6}
pigment{SlateBlue}
}
// eject spring
object{t_coil(<4.6,1.5,23.5>,<16.5,1.5,23.5>,1,.1,20) texture{col_silver}}
// eject lever
box{<4,1.4,23><26,1.6,24> texture{col_silver}}
box{<28,2,18><31,2.5,25> texture{col_silver}}
intersection{
cylinder{<28,2,18><28,2.5,18> 3}
box{<28,1.9,18><31,2.6,15>}
texture{col_silver}
}
cylinder{<26.75,2,15.75><26.75,2.5,15.75> .75 texture{col_silver}}
box{<26.75,2,15><28,2.5,16.5> texture{col_silver}}
// contact pins
object{SIM_M20_PIN() translate<5.4,0,14.6>}
object{SIM_M20_PIN() rotate<0,180,0> translate<26,0,14.6>}
object{SIM_M20_PIN() translate<5.4,0,12.06>}
object{SIM_M20_PIN() rotate<0,180,0> translate<26,0,12.06>}
object{SIM_M20_PIN() translate<5.4,0,9.52>}
object{SIM_M20_PIN() rotate<0,180,0> translate<26,0,9.52>}
object{SIM_M20_PIN() translate<5.4,0,2.22>}
object{SIM_M20_PIN() rotate<0,180,0> translate<26,0,2.22>}
#if ( sim != 0 )
object{ SIM_TRAY() translate<-1.35,3,10.5>}
#end
// traslation to eagle reference point
translate<-16,0,-12.4>
}
#end
Come è evidente dal suo listato, la macro CON_SIM_M20
è formata da molte istruzioni.
Essa utilizza t_coil.inc per realizzare la molla del pulsante di espulsione.
t_coil.inc può essere scaricato Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.%3E/" style="color: #003399;">da questo sito.
CON_SIM_M20
ha un parametro che controlla la creazione del vassoio porta-SIM.
Se esso vale 1, CON_SIM_M20
genera il vassoio porta-SIM.
Per generare sempre il vassoio porta-SIM, senza creare un dialogo per consentire all'utente la scelta, è sufficiente aggiungere la seguente riga a 3dusrpac.dat
SIM-M20:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:CON_SIM_M20(1:SIM Holder:SIM Holder
Per rimuovere il vassoio porta-SIM, è sufficiente modificare l'argomento della macro nel file .pov
#ifndef(pack_SM1) #declare global_pack_SM1=yes; object {CON_SIM_M20(0)translate<0,0,0> rotate<0,0.000000,0>rotate<0,-270.000000,0> rotate<0,0,0> translate<29.060000,0.000000,31.500000>}#end
La descrizione dei dettagli del codice appesantirebbe eccessivamente questa guida sottraendo spazio agli aspetti avanzati che verranno presentati nella parte finale.
Per questo motivo lo studio del codice è lasciato al lettore come esercizio.
Il modello del modulo Cinterion MC55i completa la scheda.
Questo modulo è una scheda che è collegata alla scheda verticale da un connettore HIROSE DF12 a 50 pin.
Il connettore femmina DF12, da saldare sulla scheda verticale, consente di fissare la distanza tra le schede a 3.5, 4 o 5 mm.
Per motivi di ingombro, è stata scelta la distanza massima.
E' anche stato scelto di fissare il modulo Cinterion con colonnine e viti poiché il telaietto in plastica suggerito dal costruttore non è compatibile con le dimensioni del contenitore.
Fatte queste premesse, la seguente macro implementa il modello 3D del modulo MC55i.
#macro CON_MC55I()
union{
object{CON_MC55I_PILLAR() translate<-14.3,0,1.2>}
object{CON_MC55I_PILLAR() translate<17.2,0,0.2>}
object{CON_MC55I_PILLAR() translate<17.2,0,-19.8>}
object{CON_MC55I_SCREW() translate<-14.3,6,1.2>}
object{CON_MC55I_SCREW() rotate<0,15,0> translate<17.2,6,0.2>}
object{CON_MC55I_SCREW() rotate<0,10,0> translate<17.2,6,-19.8>}
object{CON_MC55I_BOARD()}
object{CON_HIROSE_DF12_HDR(50)}
}
#end
La macro CON_MC55I_PILLAR
realizza una colonnina. Il suo codice è semplice:
#macro CON_MC55I_PILLAR()
lathe{ 9,
<1.35,0>,<2.5,0>,<2.5,.5>,<1.6,1>,<1.6,5.1>,<1,5.1>,<1,-1>,<1.35,-1>,<1.35,0>
pigment{P_Brass4}
}
#end
L'istruzione lathe
è una primitiva di POV-Ray che genera un solido facendo ruotare lungo l'asse y una polilinea (chiusa o aperta) definita nel piano xy.
I suoi argomenti sono il numero di punti e loro coordinate.
Per dare alla colonnina l'aspetto dell'ottone, è stata usata l'istruzione pigment{P_Brass4}
.
La macro CON_MC55I_SCREW
realizza una vite. Il suo codice è leggermente più complicato perché il suo intaglio è di tipo torx.
#macro CON_MC55I_SCREW()
union{
// head
difference{
#local h = 1.2;
union{
cylinder{<0,0,0><0,0.8,0> 2}
cylinder{<0,0.8,0><0,1.2,0> 1.6}
torus{1.6,0.4 translate<0,0.8,0>}
}
// driving slot
cylinder{<0,.5*h,0><0,1.1*h,0> .875}
//box{<-2.2,0.5*h,-0.3><2.2,1.1*h,0.3>}
}
// torx
cylinder{<0,.5*h,.875><0,1.2,.875> .3}
cylinder{<0,.5*h,.875><0,1.2,.875> .3 rotate<0,60,0>}
cylinder{<0,.5*h,.875><0,1.2,.875> .3 rotate<0,120,0>}
cylinder{<0,.5*h,.875><0,1.2,.875> .3 rotate<0,180,0>}
cylinder{<0,.5*h,.875><0,1.2,.875> .3 rotate<0,240,0>}
cylinder{<0,.5*h,.875><0,1.2,.875> .3 rotate<0,300,0>}
// body
cylinder{<0,-3.5,0>,<0,0,0> 1.0}
texture{ pigment{Gray15} finish{Metal} }
}
#end
La macro CON_HIROSE_DF12_HDR
realizza un connettore femmina DF12. Dato che esistono vari modelli, si è preferito realizzare una macro più generica di quella necessaria (versione a 50 pin).
#macro CON_HIROSE_DF12_HDR(w)
union{
// body
difference{
box{<-1.1-w/8,0,-1.9><1.1+w/8,4.3,1.9>}
box{<-.35-w/8,.5,-1.25><.35+w/8,5,1.25>}
box{<-2-w/8,2,-.75><2+w/8,5,.75>}
pigment{Gray90}
}
// contacts
#local i = 0;
#local qx = -.5*w/4+.25;
#while ( i < w/2 )
box{<qx-.125,0,1.2><qx+.125,.25,2.3> texture{T_Gold_1A}}
box{<qx-.125,0,1.2><qx+.125,4.25,1.45> texture{T_Gold_1A}}
box{<qx-.125,0,-2.3><qx+.125,.25,-1.2> texture{T_Gold_1A}}
box{<qx-.125,0,-1.2><qx+.125,4.25,-1.45> texture{T_Gold_1A}}
#local qx = qx + .5;
#local i = i + 1;
#end
// positioning pins
cylinder{<-.8-w/8,-.55,1.5><-.8-w/8,0,1.5> .25 pigment{Gray90}}
sphere{<-.8-w/8,-.55,1.5> .25 pigment{Gray90}}
cylinder{<.8+w/8,-.55,1.5><.8+w/8,0,1.5> .25 pigment{Gray90}}
sphere{<.8+w/8,-.55,1.5> .25 pigment{Gray90}}
}
#end
Considerate le precedenti spiegazioni, il codice di CON_HIROSE_DF12_HDR
dovrebbe essere chiaro, così come quello di CON_HIROSE_DF12_SCK
che realizza il connettore DF12 maschio presente sul modulo MC55i.
#macro CON_HIROSE_DF12_SCK(w)
union{
// body
box{<-1.05-w/8,0,-1.8><1.05+w/8,1,1.8> pigment{Gray90}}
box{<-1.05-w/8,1,-.75><-.35-w/8,3,.75> pigment{Gray90}}
box{<1.05+w/8,1,-.75><.35+w/8,3,.75> pigment{Gray90}}
box{<-.35-w/8,1,-1.2><.35+w/8,2.7,1.2> pigment{Gray90}}
// contacts
#local i = 0;
#local qx = -.5*w/4+.25;
#while ( i < w/2 )
box{<qx-.125,0,1.2><qx+.125,.25,2.3> texture{T_Gold_1A}}
box{<qx-.125,0,1.2><qx+.125,2.75,1.45> texture{T_Gold_1A}}
box{<qx-.125,0,-2.3><qx+.125,.25,-1.2> texture{T_Gold_1A}}
box{<qx-.125,0,-1.2><qx+.125,2.75,-1.45> texture{T_Gold_1A}}
#local qx = qx + .5;
#local i = i + 1;
#end
// positioning pins
cylinder{<-.8-w/8,-.55,1.5><-.8-w/8,0,1.5> .25 pigment{Gray90}}
sphere{<-.8-w/8,-.55,1.5> .25 pigment{Gray90}}
cylinder{<.8+w/8,-.55,1.5><.8+w/8,0,1.5> .25 pigment{Gray90}}
sphere{<.8+w/8,-.55,1.5> .25 pigment{Gray90}}
}
#end
Il codice di CON_MC55I_BOARD
è il seguente:
#macro CON_MC55I_BOARD()
union{
// board
difference{
box{<-16.3,5.1,-29.3><18.7,5.95,3.2>}
cylinder{<18.7,5,3.2><18.7,6,3.2> 1}
cylinder{<-10,5,3.2><-10,6,3.2> 1}
cylinder{<17.2,5,.2><17.2,6,.2> 1}
box{<17.2,5,-.8><19,6,1.2>}
cylinder{<17.2,5,-19.8><17.2,6,-19.8> 1}
box{<17.2,5,-18.8><19,6,-20.8>}
cylinder{<-14.3,5,1.2><-14.3,6,1.2> 1}
texture{col_brd}
}
// upper gold plating
difference{
box{<-15.8,5.95,-28.8><18.2,6,2.7>}
cylinder{<18.7,5,3.2><18.7,6.1,3.2> 1.4}
cylinder{<-10,5,3.2><-10,6.1,3.2> 1.4}
cylinder{<17.2,5,.2><17.2,6.1,.2> 1.4}
box{<17.2,5,-1.2><19,6.1,1.6>}
cylinder{<17.2,5,-19.8><17.2,6.1,-19.8> 1.4}
box{<17.2,5,-18.4><19,6.1,-21.2>}
cylinder{<-14.3,5,1.2><-14.3,6.1,1.2> 1.4}
box{<-6,5,-14><-20,6.1,-30>}
box{<10.8,5,-24.7><16,6.1,-30>}
texture{T_Gold_1A}
}
// lower shield
box{<-15.8,3.05,-28.8><13.2,5.1,-3.8> texture{col_silver}}
box{<13.2,3.05,-17.3><18.2,5.1,-3.8> texture{col_silver}}
// antenna
cylinder{<16.1,3.85,-26.4><16.1,5.1,-26.4> .25 texture{T_Gold_1A}}
difference{
cylinder{<16.1,3.85,-26.4><16.1,5.1,-26.4> 1}
cylinder{<16.1,3.5,-26.4><16.1,5.1,-26.4> .9}
texture{T_Gold_1A}
}
superellipsoid{<.25,.25> scale<1.75,.35,1.75> translate<16.1,4.75,-26.4> pigment{Gray90}}
// socket
object{ CON_HIROSE_DF12_SCK(50) rotate<180,0,0> translate<0,5.1,0>}
// upper antenna pad
box{<12.5,5.95,-26.5><14.6,6,-27.5> texture{T_Gold_1A}}
// upper text
text{ ttf "Arial.ttf" "MC55i" 0.01, 0 rotate<90,90,0> scale<4,4,4> translate<-10,6,-15> pigment{White}}
}
#end
Il modello tridimensionale del MC55i che CON_MC55I_BOARD
implementa è semplificato (mancano il codice a barre e le iscrizioni sul lato inferiore, un condensatore ed altri componenti esterni), ma rispecchia fedelmente gli ingombri meccanici.
Mettendo tutto insieme, si ha infine il modello tridimensionale della scheda verticale.
Gli sforzi per creare il modello tridimensionale sono immediatamente ripagati dalla possibilità di controllare se due oggetti interferiscono meccanicamente tra loro.
Negli strumenti più sofisticati, tale controllo viene fatto automaticamente.
Nel caso di strumenti hobbystici o semi-professionali (ma free, come Eagle, Eagle3D e POV-Ray), tale controllo va fatto "ad occhio".
Per capire con un esempio cosa significa questa affermazione, rimuoviamo il MC55i ed il vassoio porta-SIM agendo sul file POV-Ray.
clicca per ingrandire |
Osservando bene l'immagine della scheda a 1280x1204, si nota che un diodo melf potrebbe interferire con il meccanismo di espulsione del vassoio porta-SIM.
Per controllare meglio, spostiamo la posizione della camera in (10,10,-40) e modifichiamo il punto di vista in (10,-4,0) agendo sulle righe:
#local cam_x = 10;
#local cam_y = 10;
#local cam_z = -40;
#local cam_a = 20;
#local cam_look_x = 10;
#local cam_look_y = -4;
#local cam_look_z = 0;
L'immagine ottenuta evidenzia una possibile interferenza, perché è possibile che la sovrapposizione sia un effetto dell'ombra.
Per eliminare ogni dubbio, modifichiamo il colore del connettore porta-SIM da Gray10 a Gray90.
Non c'è dubbio, è proprio un'interferenza!
Questo semplice controllo sul prototipo "virtuale" ha evitato di dover buttare il circuito stampato dopo aver scoperto che è impossibile saldare un componente...
Modificato il circuito stampato, verifichiamo se l'interferenza persiste generando un'altra immagine ravvicinata.
Tutto ok, "rimontiamo" il modulo MC55i e passiamo ad altro.
Il condensatore a tantalio sulla destra potrebbe "toccare" il MC55i, ma dall'alto non è chiaro se c'è un'interferenza.
Spostando la camera in (100,10,10) ed il punto di vista in (10,4,10), si ha la seguente immagine.
Per fortuna, per qualche decimo di millimetro non c'è collisione!
Il tempo investito nel creare un modello tridimensionale delle schede ha un'altra ricaduta positiva.
Come Eagle3D aveva "montato" il MC55i sulla scheda chiamando un'opportuna macro, allo stesso modo possiamo "montare" le schede per scoprire in anticipo se ci sono problemi meccanici.
Per fare ciò, bisogna estrarre la macro GSM_BASE
da GSM_Base.pov e la macro GSM_CARD
da GSM_Card.pov
Per comodità metteremo queste macro rispettivamente in GSM_Base.inc e GSM_Card.inc
Per "montare" le schede bisogna creare un nuovo file POV-Ray dove mettere le chiamate alle macro e tutte le altre cose accessorie (es. definizione sfondo, posizione camera, luci, ...).
In fondo a ModemGSM.pov c'è la chiamata a GSM_BASE
e GSM_CARD
.
#include "GSM_Base.inc"
#include "GSM_Card.inc"
union{
object{GSM_BASE(-42.75,10,-7.25,0,0,0)}
object{GSM_CARD(-28.75,-5.27,10,-90,0,0)}
}
I parametri di GSM_BASE
indicano la traslazione e la rotazione dei suoi oggetti.
Per avere l'origine al centro della scheda, l'offset x e z corrispondono rispettivamente a metà della lunghezza e della larghezza della scheda.
Per sollevare la scheda rispetto alla superficie dell'acqua, l'offset y è 10 mm. Non è invece prevista alcuna rotazione.
I parametri di GSM_CARD
indicano che la scheda deve essere ribaltata (ruotata di -90 gradi rispetto all'asse x).
L'offset z è 10 mm perché la rotazione ha fatto scambiare le y con le z.
L'offset y è stato calcolato in modo da far combaciare i connettori femmina della base con i corrispondenti connettori maschio della scheda verticale.
Ponendo la camera in (-200,80,-200) ed il punto di vista in (0,30,0), l'immagine che si ottiene ripaga il tempo investito...
clicca per ingrandire |
E' comunque necessario fare alcune verifiche: le schede potrebbero non essere montate perfettamente ed il supercondensatore potrebbe interferire con il MC55i.
Per verificare il montaggio delle schede, è sufficiente nascondere la morsettiera a vite ed osservare di lato i connettori.
L'allineamento sembra ok, ma è meglio sollevare la scheda verticale di qualche millimetro...
Avvicinando la camera e mettendo 15 al posto di 10 nella chiamata di GSM_CARD, si ottiene:
Tutto sembra ok, bisogna però guardare i connettori frontalmente...
Non c'è dubbio che è un montaggio perfetto!
Riportiamo a 10 l'offset z di GSM_CARD e verifichiamo se il supercondensatore tocca il MC55i guardando le schede dall'altro lato.
Cambiato il colore del supercondensatore per osservare meglio il punto di contatto, notiamo che il supercondensatore ed il MC55i sono praticamente in contatto tra loro.
Fortunatamente ciò non è un problema perché l'armatura del supercondensatore in contatto è collegata a massa, così come la superficie superiore del MC55i!
Personalizzazione del contenitore
Un altro beneficio del modello tridimensionale è la possibilità di definire con precisione le lavorazioni da eseguire sul contenitore.
Per "inscatolare" le schede nel contenitore, è necessario creare un suo modello tridimensionale.
Partendo dalle dimensioni del produttore, sono state scritte le macro MR_CB_BODY
e MR_CB_1
contenute in MR_CB.inc
Quest'ultima è predisposta per la sottrazione di solidi, cioè per inserire le lavorazioni necessarie a personalizzare il contenitore.
Escludendo quelle già presenti, si ottiene la seguente immagine.
Come è possibile osservare nell'immagine, il pulsante di espulsione ed il vassoio porta-SIM "emergono" dal contenitore, mentre mancano i fori per i led, per il connettore MiniDIN, per i fili da avvitare nei morsetti e per il connettore SMA dell'antenna.
Tutte queste cose possono essere ottenute con le istruzioni che sono state escluse.
Abilitando tutte queste istruzioni, si ottiene il risultato finale...
clicca per ingrandire |
Sezioni
Il modello tridimensionale permette di realizzare con pochissime istruzioni cose impensabili pochi anni fa.
Osservando la posizione del connettore SMA, si nota che potrebbe interferire con la scheda verticale.
Questa possibile collisione potrebbe emergere quando si realizza il primo prototipo, ma è difficile individuare il punto di contatto perché il contenitore non è trasparente.
Una soluzione al problema potrebbe essere ottenuta "tagliando" il contenitore in alcuni punti e vedere dove si presenta l'inconveniente.
Trasformando la parte finale di ModemGSM.pov nel seguente modo, si ottiene una sezione del contenitore adatta allo scopo.
union{
object{GSM_BASE(-42.75,10,-7.25,0,0,0)}
object{GSM_CARD(-28.75,-5.27,10,-90,0,0)}
//object{ MR_CB_1() rotate<0,-90,0> translate<0,4.4,0>}
intersection{
object{ MR_CB_1() rotate<0,-90,0> translate<0,4.4,0>}
box{<-100,0,0><100,100,100>}
pigment{White}
}
// Connettore SMA
object{CON_SMA_ADAPTER() rotate<-90,-90,0>translate<29.25,41,0>}
rotate<90,90,0>
}
L'immagine generata ponendo la camera
in (40,60,-35) ed osservando il punto (40,5,-30), mostra che non dovrebbero esserci problemi...
Conclusioni
Eagle3D è un utile accessorio di Eagle che permette risultati ottenibili con programmi molto costosi.
Chi realizza i propri circuiti con millefori o con schede "fatte in casa" può trovare inutile questo accessorio e questa guida in cui non ci sono schemi, realizzazioni, firmware e cose simili.
Quando però ci si spinge ai limiti della miniaturizzazione, anche un appassionato di elettronica o un progettista semi-professionale può ottenere risultati professionali con questo strumento free che, nonostante i suoi limiti, è davvero impagabile!