Schema e Codice per Realizzare una Stazione Saldante a Partire da un Saldatore con Termocoppia e attacco GX16 di qualsiasi Marca…
INTRO
In questo articolo vedremo come realizzare una stazione saldante a partire da uno stelo saldante di qualsiasi marca. Potremmo realizzare in modo economico una stazione saldante di alta qualità in quanto il saldatore ovviamente va acquistato mentre possiamo risparmiare sul sistema di controllo realizzandolo noi.
Io ho usato una versione economica di un saldatore a 24V per HAKKO 907, ESD 936, 937, 928 oppure 926. Potete usare un qualsiasi saldatore a 24V con connettore GX16 che dispone di termocoppia di tipo k internamente.
Potete capire dove si trova la termocoppia misurando la resistenza tra i diversi pin del connettore. La termocoppia avrà una resistenza di 4 Ohm mentre la resistenza che riscalda avrà una resistenza di circa 12 Ohm se il saldatore ha una potenza di 50W. Per quanto riguarda la termocoppia potete fare dei test per capire quale è il positivo e il negativo.
Detto questo potete usare qualsiasi tipo di stelo, io vi consiglio di comprarne uno decente perché quelli da 5 euro di ebay durano 5 giorni. Anche con connettore diverso o di potenza maggiore, l’importante è la termocoppia.
Per alimentare questo progetto ho usato un alimentatore switching 24V 3A. se usate un saldatore di maggiore potenza ovviamente serviranno 5A.
CODICE
La base per il codice è il PID con microcontrollore realizzato al seguente articolo https://www.ne555.it/controllo-pid-pi-microcontrollore/ inoltre ho scelto di usare un display 7 segmenti a 3 cifre per la visualizzazione della temperatura.
Il codice è il seguente:
#define CS portc.f3 //Definisci CS PORTC.F3
#define DT 0.2 //Tempo di ripetizione PID (non più piccolo altrimenti il max6675 non funziona)
#define Kp 2 //Costante proporzionale (2 1 1)
#define Ki 1 //Costante integrale
#define Kd 2 //Costante derivativa
#define MAXout 255 //Massimo valore uscita
#define MINout 1 //Minimo valore uscita
#define Epsilon 2 //Errore massimo tra setpoint e input
int prev_error = 0; //Variabile errore iterazione precedente
int integrale = 0; //Variabile azione integrale
int error, derivata, output, abserror, input; //Variabili utili
sbit SoftSpi_SDI at RC4_bit; //Definisci connessione SPI
sbit SoftSpi_SDO at RA4_bit;
sbit SoftSpi_CLK at RC5_bit;
sbit SoftSpi_SDI_Direction at TRISC4_bit;
sbit SoftSpi_SDO_Direction at TRISA4_bit;
sbit SoftSpi_CLK_Direction at TRISC5_bit; //Fine connessione SPI
char temp_lsb=0, temp_msb=0, DutyCycle=0, i; //Variabili provvisore
unsigned int temp=0, temperatura=0, temp_display=0, temp_set=350; //Variabili temp
char text[5]; //Variabile testo
unsigned short int cifra; //iniz. variabile cifra
char segm[10] = {0b10000001, 0b11110011, 0b01001001, 0b01100001, //iniz. il vettore segmenti
0b00110011, 0b00100101, 0b00000101, 0b11110001,
0b00000001, 0b00100001};
void tre_cifre(unsigned int numero){ //sottoprogramma (dura 16.76mS)
cifra = numero % 10u; //estrae dal numero le unità
PORTA = 0b00000010; //accensione unità con buffer(con transistor 0b00000100)
PORTB = segm[cifra]; //inizializza la cifra unità
delay_ms(5);
cifra = (numero / 10u) % 10u; //estrae dal numero le decine
PORTA = 0b00000100; //accensione decine con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra decine
delay_ms(5);
cifra = (numero / 100u) % 10u; //estrae dal numero le centinaia
PORTA = 0b00001000; //accensione centinaia con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra centinaia
delay_ms(5);
}
unsigned int arrotonda (unsigned int numero){ //numero = valore da arrotondare
short resto = 0; //inizializza resto a 0
resto = numero % 10; //trova il resto della divisione per 10
if (resto > 5) numero = numero + (10 - resto); //se resto > 5 approssima per eccesso
else numero = numero - resto; //altrimenti approssima per difetto
return numero; //ritorna il valore arrotondato
}
int PID(int setpoint, int input){ //Funzione PID
error = setpoint - input; //calcola l'errore tra input e setpoint
if(abs(error) > Epsilon){ //Se l'errore è maggiore di epsilon
integrale = integrale + error*DT; //Calcola l'azione integrale
}
derivata = (error - prev_error)/DT; //Calcola l'azione derivativa
output = Kp*error + Ki*integrale + Kd*derivata; //Calcola output PID
if(output > MAXout) { //Se l'uscita supera il valore massimo
output = MAXout; //Satura l'uscita
integrale=0; //Azzera l'azione integrale
}
else if(output < MINout) { //Se l'uscita invece è troppo piccola
output = MINout; //Satura alla minima uscita
integrale=0; //Azzera anche in questo caso l'azione integrale
}
prev_error = error; //Salva il valore dell'uscita
return output; //Restituisci uscita PID
}
void EXT_INT() iv 0x0004 ics ICS_AUTO { //0018h per bassa priorità, 0008h per alta priorità
for(i=0; i < 100; i++){
if((temp_set < 450) && (PORTC.F6 == 1)){
delay_ms(200);
temp_set += 10;}
if((temp_set > 200) && (PORTC.F7 == 1)){
delay_ms(200);
temp_set -= 10;}
cifra = temp_set % 10u; //estrae dal numero le unità
PORTA = 0b00000010; //accensione unità con buffer(con transistor 0b00000100)
PORTB = segm[cifra]; //inizializza la cifra unità
delay_ms(5);
cifra = (temp_set / 10u) % 10u; //estrae dal numero le decine
PORTA = 0b00000100; //accensione decine con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra decine
delay_ms(5);
cifra = (temp_set / 100u) % 10u; //estrae dal numero le centinaia
PORTA = 0b00001000; //accensione centinaia con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra centinaia
delay_ms(5);
}
INTCON.INTF = 0;
}
void main(){ //Programma principale
INTCON.GIE = 1; //attivo gli interrupt
OPTION_REG.INTEDG = 1; //interrupt sul fronte di salita
INTCON.INTE = 1; //interrupt attivo
TRISA = 0; //ingressi e uscite
TRISB = 0x01;
TRISC.F3 = 0; //CS chip select uscita
Soft_SPI_Init(); //Inizializza SPI
PWM1_Init(271); //Inizializzazione pwm
PWM1_Start();
PWM1_Set_Duty(255);
while (1) { //Ciclo infinito
CS=0; //CS=0 avvia lettura
temp_msb = Soft_SPI_Read(170); //Leggi MSB temperatura
temp_lsb = Soft_SPI_Read(170); //Leggi LSB temperatura
temp =((unsigned int )temp_msb <<5) | (temp_lsb>>3 ); //Unisci LSB e MSB
CS=1;
temperatura = (temp >> 2)/2; //Condiziona temperatura
temp_display = arrotonda(temperatura);
output = PID(temp_set, temperatura); //Richiama la funzione PID
PWM1_Set_Duty(output);
for(i=0; i < 12; i++){ //Mostra temperatura
tre_cifre(temp_display);
}
}
}
Prima di tutto definisco le costanti del PID, variabili, e connessioni del protocollo SPI per il sensore di temperatura. La funzione tre_cifre riceve il numero da visualizzare sul display 7-segmenti, lo divide in unità decine e centinaia e li visualizza uno per volta.
La funzione arrotonda serve solo per arrotondare la temperatura in multipli interi di 5. La funzione PID genera il valore da inviare al PWM ed il suo funzionamento è spiegato nella guida sul PID. La funzione di interrupt EXT_INT serve per incrementare o decrementare la temperatura di settaggio del saldatore. Con il pulsante su PORTC.F6 si incrementa e con il pulsante su PORTC.F7 si decrementa. Ho discretizzato a passi da 10, è inutile controllare con precisione di 1 grado. Inoltre quando si preme uno dei pulsanti si va a visualizzare la temperatura di set sul display.
Nel main inizializzo interrupt, ingressi e uscite, la comunicazione SPI software e il PWM. Nel ciclo infinito vado a leggere la temperatura e la condiziono in modo tale che sia correttamente visualizzata, e la invio alla funzione di arrotondamento. Richiamo poi la funzione del PID dalla quale ottengo il valore di PWM d inviare sul PWM1 e vado a richiamare per 12 volte la funzione di stampa su display. 12 volte in modo tale che la funzione funga da delay di 200mS come specificato nel PID.
SCHEMA
Lo schema è il seguente:
Nello schema è rappresentato un display 7 segmenti a 4 cifre, a noi ne basta uno a 3 cifre. Bisogna usare un display a basso consumo, con corrente di funzionamento di qualche mA per ogni segmento visto che non ho usato un buffer ma il pin (1, 2 o 3) in comune è direttamente connesso al PIC. Io ho usato un display ad anodo comune.
Vi sono 7 resistori da 1.5KOhm sui 7 segmenti in modo tale da avere una corrente di circa 2mA per ogni segmento. Non ridurre questo valore o rischiate di bruciare il PIC. Cambiando il codice si può usare un display a catodo comune senza cambiare lo schema.
La tensione di alimentazione a 5V per il circuito di controllo viene generata da un 7805 che trasforma i 24V in 5V. Il positivo dei 5V va connesso al pin 20 del microcontrollore mentre il pin 8 e 19 del microcontrollore sono connessi a massa. Il pin 1 del microcontrollore è connesso a 5V tramite la resistenza di pull-up R3 mentre il circuito di oscillazione è formato da un quarzo da 4MHz e due condensatori da 22pF.
D1, D2 ed R6 formano una porta or in modo tale che quando premo uno dei pulsanti si attiva l’interrupt. Mentre R4 ed R5 sono i resistori di pull-down che mantengono a 0 gli ingressi PORTC.B6 e B7 se non si preme il pulsante.
La termocoppia va connessa al modulo MAX6675 con la giusta polarità. R1 ed R2 potrebbero essere interne al modulo, quindi controllate bene il modulo e se sono già presenti non le aggiungete anche esternamente. Il condensatore C4 da 220p l’ho aggiunto io per ridurre possibile rumore sulla tensione della termocoppia.
La resistenza del saldatore va connessa con un capo ai 24V positivi e l’altro capo al drain del MOSFET Q1 che funge da switch per il PWM. Il PIN 3 del saldatore andrebbe connesso a massa visto che è il case.
Ho realizzato il controller per il saldatore ma purtroppo ho perso il disegno del PCB. Potete realizzarne uno migliore del mio e con la forma del case che andrete ad usare. L’ho realizzato molto piccolo ma non guasterebbe avere una dimensione maggiore ma con più ordine. In foto potete vedere il mio controller per saldatore prima di essere inscatolato con saldatore e con l’oscilloscopio connessi per controllarne il funzionamento.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS e il codice scritto con MIKROC al seguente LINK!!!
ciao ho realizzato il disegno del pcb, realizzato un prototimo col sistema incisione laser , ma ho dei problemi con caricare il firmware sul pic, ha disposizione ho un Tl866 II plus, ma non so se la conversione del listato sia corretto, alla programmazione non mi comunica errori , ma non vedo nulla sul displai, controllo se il quarzo osclla e mi da uno strano segnale, allinterno di una onda quadra, una sorta di dente di segna, ed sui pin destinati i segmenti le uno strani segnale a bassisima tensione, non vorrei che mi avessero rifilato un chip tarocco,
suggerimenti ?
Ciao,
tu usi il TI866 come programmatore ma poi usi il pic 16F72 giusto?
Io ho avuto brutte esperienze con i programmatori universali, infatti mi sono comprato un pic-kit3 alla fine.
Se usi il pic16f72 allora potrebbe essere effettivamenete il programmatore
Ciao grazie per la risposta dovrei avere anche un pickit3 comprato quasi 20 anni fa Proverò a programmarlo con quello per ora grazie per l’imput
ciao , ho realizzato un bel pcb, vuoi tel lo mando da pubblicare, mi sono realizzato pure un pcb per Max6675
ho realizzati 3 unita, di cui 2 li uso per il upgrade della mia stazione realizzata una 30 si anni fa , ed una la tengo come muletto
la stazione che avevo realizzato una trentina di anni fa montava degli stilo cerruti, un saldatore, ed un dissaldatore , il dissaldaore non e mai andato tanto bene , quindi ho pensato di prenderne un nuovo, stilo Pro’skit 1pk-SS-331H, va veramente molto bene, ma la sonda termica non viene riconosciuta , pensavo fosse una K, a temperatora ambiente ha qualche Kohm, si potrebbe modificare il fromware del pic ? grazie