Realizzazione circuito stampato

Salve, ho creato un progetto con Arduino mega, su banco, con i fili volanti è funzionante(più o meno). Vedo spesso la pubblicità di PCB, mi piacerebbe creare una scheda e farmela stampare, mi potete indicare, in linea di massima, come passare dai fili volanti ad una scheda finita?

Prima di tutto devi scegliere un programma che ti permetta di disegnare schema elettrico e il PCB(Tracce, fori, ecc.) alcuni usano Eagle (molti utilizzando ancora vecchie versioni quando il prodotto era della CadSoft, prima che fosse acquistato da Autodesk insomma) altri KiCad.
Se non hai mai usato un CAD per questo scopo intanto scegli quale dei due utilizzare e inizia a guardare tutoria, guide, ecc. per imparare ad utilizzarlo. Quando sarai riuscito a impostare il progetto sul CAD e quindi ad avere il PCB pronto da inviare a qualche service dovrai esportare i file, solitamente nel formato gerber, in base alle specifiche del service.
Intanto direi di affrontare lo scoglio del CED che quasi certamente ti porterà via molto tempo, almeno per me è stato così :wink:

Quali dei due consigli? Una volta disegnato lo schema come si farebbe sulla carta, il circuito stampato viene creato automaticamente?

Eagle NON esiste più ... Autodesk ne ha decretato la morte a favore di altro suo prodotto :rage:

Probabilmente si trovano ancore in giro le vecchie versioni, prima appunto dell'acquisizione da parte di Autodesk ... l'ultima di tali versioni era la 7.7.0 e, gratuitamente (senza la registrazione), permetteva di realizzare schede della dimensione dell'Arduino MEGA :slight_smile:

Guglielmo

Ho usato entrambe in modo superficiale e posso dire che entrambe hanno le loro regole e conviene provare per capire quale dei due torna meglio. Forse lo kicad e più facilmente reperibile perché open source. Per il discorso del PCB la risposta è assolutamente no, devi fare praticamente tutto a meno tu o quasi, e occorre tempo e pratica. Quei pochi PCB che ho disegnato per scopo personale se li vedesse qualcuno di esperto sarebbe come "film di orore" :grin:



Per ora ho creato così, ma come puoi vedere il mio è più orrore del tuo.

Assemblando il tutto ho scoperto che la parte software relativa al funzionamento della scheda relè non mi funziona.
In pratica, da menù, dico: quale uscita attivare, dopo quanti secondi dall'inizio della prima fase deve accendersi e dopo quanti secondi dall'accensione deve spegnersi.
Nel loop ci sono sei fasi che controllano i moduli driver, i tempi delle sei fasi li decido sempre da menù e funzionano. Il loop parte dalla prima fase, quando finisce la sesta inizia dalla prima fase.
La parte che accende e spegne i relè funziona, non funziona la parte relativa ai tempi, mica mi potreste dare un suggerimento?

Dai è anche bello ordinato, almeno da cellulare non sembra male. Per il programma postalo seguendo le regole e io e altri una mano te la diamo per quanto ci è possibile

Il programma è lunghissimo, mi interessa solo un suggerimento su come implementare i tempi per accensione e spegnimento dei relè, logicamente per farlo ho usato millis.

void controlla_uscita(){ // Controlla quale uscita è stata attivata e l'accende e spegne in base ai tempi impostati

  if (fase_pin[0] !=0){ // Se l'uscita zero è stata attivata da menù
    if (millis()-mil_out0 > (inizio_pin[0]*1000) && digitalRead(pin_out[0]) == 0) {  // controlla dopo quanto tempo dall'inizio della prima fase deve accendere l'uscita zero 
      digitalWrite(pin_out[0],1);  // accende l'uscita zero
      mil_out0 = millis();  // azzera il contatore
    }
    else if (millis()-mil_out0 > (fine_pin[0]*1000) && digitalRead(pin_out[0]) == 1) {  // controlla dopo quanto tempo deve spegnere l'uscita zero da quando è stata accesa
      digitalWrite(pin_out[0],0);  // spegne l'uscita zero
      mil_out0 = millis();  // azzera il contatore
    }
  }
  if (fase_pin[1] !=0){ // Se l'uscita 1 è stata attivata da menù
    if (millis()-mil_out1 > (inizio_pin[1]*1000) && digitalRead(pin_out[1]) == 0 ) {  // controlla dopo quanto tempo dall'inizio della prima fase deve accendere l'uscita 1 
      digitalWrite(pin_out[1],1);  // accende l'uscita 1
      mil_out1 = millis();  // azzera il contatore
    }
    else if (millis()-mil_out1 > (fine_pin[1]*1000) && digitalRead(pin_out[1]) == 1) {  // controlla dopo quanto tempo deve spegnere l'uscita 1 da quando è stata accesa
      digitalWrite(pin_out[1],0);  // spegne l'uscita 1
      mil_out1 = millis();  // azzera il contatore
    }
  }

E così via per le altre uscite.
Il problema è che se io attivo la prima uscita e gli dico che deve accendersi dopo 10 secondi dalla prima fase e spegnersi dopo 5 secondi, lo fa, però dovrebbe restare spenta fino a quando non finisce la sesta fase. Quando inizia di nuovo la prima fase, si riattivano le accensioni secondo i tempi impostati. Invece come ho fatto io, una volta che la prima uscita si spegne, si riaccende dopo 10 secondi e si spegne dopo 5 secondi anche se la fase sta a 2 o 3 o 4 o 5 o 6.
Nel loop ho la variabile fase che mi indica in quale fase sto. All'inizio l'avevo usata con un and nel primo if, però se la prima fase mi durava 15 secondi ed io dicevo di accendersi dopo 20 secondi, logicamente non si accendeva, perchè dopo 20 secondi si trovava nella seconda fase e dato che nel primo if avevo messo:

if (millis()-mil_out0 > (inizio_pin[0]*1000) && digitalRead(pin_out[0]) == 0 && fase == 1) {

non si sarebbe acceso.

Sito come implementare la logica con millis sarebbe poco utile perché di esempi ne trovi a tonnellate, sono da cellulare e non riesco a mettere i link sull'uso di millis. Dirti come mai il tuo programma non funziona senza vederlo e al limite dell'impossibile, servirebbe una sfera di cristallo USB.

Lo so, ma è anche impossibile postare qui tutto il codice dato la sua lunghezza, anche se lo postassi poi ci vorrebbe tempo per capirne il funzionamento, per questo ho postato solo la routine interessata.
Ho risolto in questo modo:
All'inizio ho dichiarato 8 variabili booleane, una per ogni uscita e le ho poste a zero.
Alla fine della sesta fase imposto le 8 variabili a zero.
La routine è stata cambiata così:

void controlla_uscita(){ // Controlla quale uscita è stata attivata e l'accende e spegne in base ai tempi impostati

  if (fase_pin[0] !=0){ // Se l'uscita zero è stata attivata da menù
    if (millis()-mil_out0 > (inizio_pin[0]*1000) && digitalRead(pin_out[0]) == 0 && pin_spento0 == 0) {   
      digitalWrite(pin_out[0],1);  // accende l'uscita zero
      mil_out0 = millis();  // azzera il contatore
    }
    else if (millis()-mil_out0 > (fine_pin[0]*1000) && digitalRead(pin_out[0]) == 1) {  // controlla dopo quanto tempo deve spegnere l'uscita zero da quando è stata accesa
      digitalWrite(pin_out[0],0);  // spegne l'uscita zero
      mil_out0 = millis();  // azzera il contatore
      pin_spento0 = 1;
    }
  }
  if (fase_pin[1] !=0){ // Se l'uscita 1 è stata attivata da menù
    if (millis()-mil_out1 > (inizio_pin[1]*1000) && digitalRead(pin_out[1]) == 0 && pin_spento1 == 0) {  // controlla dopo quanto tempo dall'inizio della prima fase deve accendere l'uscita 1 
      digitalWrite(pin_out[1],1);  // accende l'uscita 1
      mil_out1 = millis();  // azzera il contatore
    }
    else if (millis()-mil_out1 > (fine_pin[1]*1000) && digitalRead(pin_out[1]) == 1) {  // controlla dopo quanto tempo deve spegnere l'uscita 1 da quando è stata accesa
      digitalWrite(pin_out[1],0);  // spegne l'uscita 1
      mil_out1 = millis();  // azzera il contatore
      pin_spento1 = 1;
    }
  }

Imposto la variabile pin_spento0 a 1 l'uscita 1 viene spenta, così nelle altri fasi non si accenderà. Quando arriva alla fine dell'ultima fase, viene messa a zero.

Oltre a Kicad ho trovato un altro software Fritzing, tra i componenti ci sono anche i vari Arduino

Ciao.
Eagle non l'ho mai provato, ma uso spesso kicad e posso dirti che è un buon programma.
la comunità è molto vasta ed è molto utile per risolvere i vari problemi che si incontano.

Inoltre kicak ha la possibilità di farti vedere l'anteprima della scheda in 3D che è molto utilie per farsi un idea degli ingombri.

inoltre puoi esportare la scheda in formato step e importarla in un programma cad 3D per eventualmente fare il case, anche questo lo faccio molto spesso.

in passato usavo orcad ma sinceramente non lo rimpiango.
Ciao.

Lascia stare, va bene per "giocare" con le breadboard NON per fare circuiti stampati.

Scaricati KiCAD, studiati le decine di tutorials che trovi in giro e sperimenta ...

Guglielmo

Io ho usato kicad che è un cad open source sviluppato e mantenuto al cern della svizzera ormai è giunto alla versione 7,x. Ci sono una marea di video su youtube cè un utility che ti permette di creare i file geber perfettamente configurati per pcway per far fare il pcb in cina.

In linea di massima mi viene da suggerirti di gestire anche la parte del controllo uscita a stati in modo da separare totalmente la logica di attivazione/disattivazione dai tempi magari con due funzioni separate.
In questo modo all'interno della funzione controllo_uscita ti resterebbe un codice pulito, facilmente comprensibile e mantenibile, es:

void controlla_uscita(){
   switch(STATO_CORRENTE){
	case ATTIVA1:
		if (millis()-mil_out0 > (inizio_pin[0]*1000)) {
			digitalWrite(pin_out[0],1);  // accende l'uscita zero
			mil_out0 = millis();
			STATO_CORRENTE = ATTESA_DISATTIVA_USCITA1;
		}
		break;
	case ATTESA_DISATTIVA_USCITA1:
		if (millis()-mil_out0 > (fine_pin[0]*1000){
			digitalWrite(pin_out[0],0);  // spegne l'uscita zero
			...
			STATO_CORRENTE = PROSSIMO_STATO_DA_IMPOSTARE;
		}
		break;
	...
   }
}

A parte i commenti e consigli che già ti hanno fatto gli altri, volevo aggiungere che se questo è il tuo primo progetto diciamo di una certa dimensione devo farti i complimenti! In genere si vedono grovigli di fili e saldature "ad minchiam", il tuo circuito, anche se un po' esagerato nelle dimensioni, è ordinatissimo.
L'unica cosa per me un po' "strana" è che hai in pratica realizzato un enooorme "shield" per il Mega visto che questo sta "sotto" al circuito! :slight_smile: Io per maggiore praticità lo avrei messo sopra, fissandolo con un paio di bulloncini, e tramite connettori e flat riportare sulla basetta i pin. Ma è solo una questione secondaria, complimenti comunque!

L'Ho messo sotto perchè per le mani mi ritrovavo quei connettori presi da una shield per arduino mega mai montata. Per metterlo sopra che tipo di connettori devo prendere? Vorrei fare un circuito come si deve, se funzionerà nella pratica e non solo sul tavolo.
Per risparmiare spazio, potrei non usare schede già pronte ma usare i componenti singoli, per farlo devo ricavare gli schemi da queste schede.
Si, è il mio primo progetto con arduino. Se funzionerà vorrei farne un'altro comandato dal telefono anzichè con display ed encoder.
Dal lato software mi resta da fare un'altra cosa, memorizzare i valori inseriti dall'utente in modo che quando si riaccende arduino non deve inserirli di nuovo.
Qui ci sto ancora studiando. Ho visto che c'è la libreria Eeprom per fare questo. Avevo pensato di mettere queste righe nel setup:

  tempo[0] = EEPROM.get(0); //  Legge il valore contenuto nella posizione zero (2 byte)
  if (tempo[0]==0) tempo[0]=20; // Imposta tempo a 20 secondi qualora nella posizione zero non ci fosse nulla

Faccio così per ogni tempo che voglio memorizzare. Quando esco dal menù, se ho fatto dei cambiamenti li memorizzo nella Eeprom

 for (int i=0; i<7; i++) {
   if (tempo[i] != EEPROM.get(i*2)) EEPROM.put(i*2,tempo[i]); // Se il valore del tempo contenuto nella posizione  zero è cambiato, scrive il nuovo valore
}

Che ne dite, potrebbe andare bene?

Ti rispondo limitatamente al discorso EEPROM, per la scrittura non ti serve fare il controllo con l'if se usi la put perché il metodo usa al suo interno il metodo update che già verifica se il valore da scrivere è identico a quello presente in EEPROM, se si non scrive altrimenti scrive

Anzi ora che ci penso la put gestisce da sola l'array quindi ti basta una sola put:

int indirizzo = 0;
EEPROM.put(indirizzo, tempo);

La variabile indirizzo l'ho messa solo a scopo di leggibilità, se hai un solo dato da salvare puoi mettere direttamente l'indirizzo da utilizzare.
Se hai più dati dopo l'array ti basta fare

indirizzo += sizeof(tipo_dell_array)*dimensione_dell'array;

Quindi il codice sopra posso trasformalo in questo:

 for (int i=0; i<7; i++) {
    EEPROM.put(i*2,tempo[i]); 
 }