To je univerzalno vezje za krmiljenje MIG/MAG varilnih aparatov narejeno na osnovi ATmega328.
Osnovno vezje krmilji motor za potiskanje žice, ventil za plin in transformator za varjenje. Ima 4 načine delovanja o katerh bom povedal več kasneje. Vezje ima 7 digitalnih in 3 analogne dodatne pine, ki jih lahko sprogramirate sami. Mikrokrmilnik pa ima še 93,7% flash in 99,4% RAM spomina.
Preden začnem z delovanjem vezja moram najprej predstaviti kako poteka samo varjenje. Varjanje z žico delimo na 2 glavna postopka:
- MIG/MAG: Varilna žica je narejena iz materiala, ki ga varimo in nekaj primesi. Za zaščito vara uporablja različne pline.
- FCAW - Flux Cored Arc Welding: Vari se z žico, ki je polnjena s "fluxom" ki ščiti var. Včasih se za dodatno zaščito uporablja tudi plin.
MIG varjenje pomeni Metal Inert Gas oziroma "interni plin". Ta plin ščiti var pred oksidacijo in drugimi vplivi okolja. V MIG postopku se po navadi vari kovine, ki niso železo. Zaščitni plin je večinoma argon (Ar2) včasih pa tudi helij (He2).
MAG pa pomeni Metal Active Gas ali "aktivni plin" po naše. Deluje enako kot MIG varjenje samo da uporablja drugi plin. Ta plin je oglikov dioksid (CO2) ali mešanica z argonom (Ar2). V tem postopku se načeloma vari samo železo.
Varjenje poteka v 3 fazah:
1. Začetek varjenje
2. Varjenje
3. Konec varjenja
V 1. fazi najprej začne pritekati plin. Po določenem času (kasneje "pred plin") pa se prične samo varjenje. Varjenje pa se prične tako, da se najprej vklopi transformator za varilni tok. Potem mora preteči vsaj nekaj ms da se napetost stabilizira in je pripravljena za varjenje. Nato šele lahko začnemo dodajati žico.
V 2. fazi pa se ne dogaja nič posebnega čeprav je to najpomembnejši del. V tem delu naredimo var. "Nezanimiv" je za to, ker se nič ne spreminja.
V 3. fazi pa se varjenje zaključi. Konec varjenja pa se odvija v nasprotnem vrstnem redu od začetka. Najprej se izklopi motor in nato po nekem kratkem času še transformator. Ta čas je namenjen dejstvu, da se žica ne bo ustavila v isti sekundi, ko varilni tok. To bo žico potisnislo v "mehek" var česar pa nočemo. Ta zamik omogoča, da se žica, ki se dotakne vara v tem času razstopi. Nato se izklopi še transformator za varilni tok. Ker pa je ver še žareč lahko oksidira. Zato nekaj časa po koncu varjenja pustimo teči plin.
- Navadno varjenje
Navadno varjenje je najbolj preprosto izmed vseh. Ko pritisnemo tipko na gorilniku aparat spusti plin, počaka nekaj časa in začne z varjenjem. Ko pa tipko spustimo pa se varilni tok in pogon žice izklopita in po določenem času še plin.
- Točkovno varjenje
Točkovno varjenje je varjenje po točkah, ki so časovno določene. Vsakič ko pritisnemo tipko bo varjenje potekalo točno za nastavljen čas. Tudi če jo prej spustite. Če pa držite tipko tudi po koncu pulza se nov pulz ne bo pričel, dokler ne spustite tipke.
- Pulzno varjenje
Pulzno varjenje je enako točkovnemu z dodatkom ponavljanja pulzov. Dokler držite tipko se bo odvijal cikel pulznega varjenja z zamakom, ki ga nastavite.
Vezje za delovanje potrebuje napetosti 5V in 12V enosmernega toka. 5V služi napajanju mikrokrmiljnika. 12V veja pa je namanjena relejem in predvsem motorju.
Iz transformatorja za napajanje krmiljenja dobimo izmenično napetost, ki jo je potrebno najprej usmeriti. To stori Greatzov mostič CR1. Pri teh mostičih je zelo pomembna izbira toka. Nazivni tok mora biti vsaj 1x večji (Inaz > 2*I da ne bo nesporazuma) od realnega. Za usmerniškim mostičem sta kondenzatorja C8 in C9. Ta služita za glajenje napetosti.
5V veja deluje na istem principu, samo da ima dodan še lnearni regulator napetosti 78M05. Zraven nejga sta še 2 kondenzatorja vrednosti 100nF, ki preprečiti morebitne oscilacije regulatorja.
Tukaj so povzave za napajanje mikrokrmiljnika. Povezan je tudi kristalni oscilator frekvence 16MHz. Pri napajanju ADCja je potrebno paziti na motnje visokih frekvenc. Zaradi tega je potrebno AVCC povezati na 5V prek ferita (EMI). Ferid je za enosmerne tokove zelo dober prevodnik, pri višjih frekvencah pa se mu pojavi upornost. Dobro je še, če se med konec ferida in GND povežete kondenzator nekaj nF.
Na pin 29 pa je povezan na 10k pull up upor, ki skrbi da se mikrokrmiljnik ne bi resetirl zaradu zunanjuh vplivov.
Če dobro opazujete ste opazili, da je mikrokrmiljnik na shemi ATmega8. Na vezje pašeta oba krmiljnika saj imata enako rasporeditev pinov. Razika je le v spominu.
Za vklapljanje in izklaplanje ventila za plin in transformatorja zavarilni tok sem izbral releje, zato da bo vezje čim bolj univezalno.
Releja delujeta na napetosti 12V zaradi toka. 5V rele potrebuje več toka kot ga lahko odda mikrokmiljnik. Ker pa je izhodna napetost mikrokrmiljnika mannjša od delavne napetosti releja ta vklaplja trantistor tipa BC817-16. Vzporedno releju pa je povezana dioda tipa 1N4004. Ta dioda odstrani napetost, ki se inducira v tuljavi po podrtju magnetnega polja. Ta napetost je lahko visoka nekaj 100V in lahko poškoduje tranzistor.
Program je napisan v Arduino jeziku, ki je mešanica C in C++. Uporabil sem standardno Arduino knjižnico.
Koda uporablja vse 3 vgrajene timerje. Prvi TIMER0 je uporabljen s strani Arduino.h knjižnice za časovne funkcie. TIMER1 je 8 bitni kar pomeni, da lagko šteje do 255. Drugi TIMER1 pa genrerira PWM signl za krmiljenje motorja. To je edini 16 bitni timer na ATmega238 in lahko šteje do 65 535. TIMER2 pa je uporabljen za izklop plina po določenem času.
#define START_UP_PULSE_LENGHT_ms 100
#define MOTOR_TO_CURRNET_STOP_TIME 50
#define CURRENT_TO_MOTOR_START_TIME_ms 50
#define PRE_GAS_TIME_ms 20000
#define AFTER_GAS_TIME_ms 30000
#define DOT_WELD_TIME_ms 20000
#define PULSE_WELD_TIME 20000
//PINS:
#define WELDING_TOARCH 2
#define RELEASE_GAS_SWITCH 5
#define PUSH_WIRE_SWITCH 6
#define PRE_GAS_POTENTIOMETER A3
#define AFTER_GAS_POTENTIOMETER A2
#define PULSE_POTENTIOMETER A4
#define DOT_POTENTIOMETER A5 //
#define SPEED_POTENTIOMETER A6
#define DEBUG_LED 10
#define MOTOR_OUTPUT 9
#define GAS_OUTPUT 0
#define TRANSFORMATOR_OUTPUT 1
#define REAL_AFTER_GAS_TIME_ms (AFTER_GAS_TIME_ms / 10)
//Global variables
volatile uint16_t after_gas_time_count = 0;
volatile uint16_t after_gas_time = 0;
Tukaj so definirani vsi parametri, ki jih program potrebuje za delovanje.
#define REAL_AFTER_GAS_TIME_ms (AFTER_GAS_TIME_ms / 10)
Ker TIMER2 naredi programsko prekinitev na 10ms je potrebno deliti nastavljen maksimalni čas z 10, da dobimo pravilen čas.
void setup(){
pinMode(WELDING_TOARCH, INPUT);
pinMode(RELEASE_GAS_SWITCH, INPUT);
pinMode(PUSH_WIRE_SWITCH, INPUT);
pinMode(MOTOR_OUTPUT, OUTPUT);
digitalWrite(MOTOR_OUTPUT, 1);
pinMode(GAS_OUTPUT, OUTPUT);
pinMode(TRANSFORMATOR_OUTPUT, OUTPUT);
//Timmer1 setup (PWM driver)
TCCR1A = 0;
TCCR1B = 0;
ICR1 = 267; //PWM frequency
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM13) | (1 << WGM12);
//Timer 2 setup (after gas delay)
TCCR2A = 0;
TCCR2B = 0;
TCCR2A = (1 << WGM21);
OCR2A = 156;
TIMSK2 = (1 << OCIE2A);
sei();
}
Inicijalizacija se izvaja na začetku programa v funkciji loop(). Ta funkcija steče samo enkrat in to na začetku programa. V tej funkciji je potrebno nastaviti registre, definirati vrste pinov in podobno.
Na začetku so definirane vrste pinov. To lahko dosežemo tudi z nastavljanjem vrednosti v DDRx register. Logična 1 pomeni, da je pin izhod logična 0 pa da je vhod.
Najprej počisti vrednosti registrov, da se izogne morebitnim težavam. Nato nastavi TIMER2 v funkcio Fast PWM. Register ICR1 je vrh ob katerem gre timer nazaj na zečetek cikla. S tem registrom določamo frekvenco.
OCR1A pa služi za nastavljanje delavnega cikla PWM signala. Frekvenco PWM signala se izračuna po naslednji enačbi:
\[ F_{\text{pwm}} = \frac{F_{\text{clk}}}{N \cdot (1 + \text{TOP})} \]
- Fpwm – izhodna frekvenca PWM signala
- Fclk – vhodna ura (clock) mikrokontrolerja
- N – prednastavljeni delilnik frekvence (prescaler)
- TOP – največja vrednost števca (ICR1)
sei() je del knjižnice avr/interrupt.h. Ta funkcija nastavi I bit v SREG, ki omogoči programske prekinitve.
Frekvenca je v tem primeru okoli 60kHz. Frekvenco lahko spreminjate tudi s prescalerkem in uporabo drugega timerja. TIMER2 pa je nastavljen, da kadar je vklopljen naredi sistemsko prekinitev na vsakih 10ms.
ISR(TIMER2_COMPA_vect){
after_gas_time_count++;
if(after_gas_time_count > after_gas_time){
after_gas_time_count = 0;
TCCR2B = 0; //Turn timer off
TCNT2 = 0; //Clear timer
digitalWrite(GAS_OUTPUT, 0);
}
}
ISR() oziroma Interrupt Service Rutine je funkcija v knjižnici avr/interrupt.h. Kod vhodni parameter vzame vektor programske prekinitve. Ko se zgodi neka prekinitev bo klicana funkcija pod ustreznim vektorjem. Ko se zgodi najprej za 1 poveča število 10ms. Če je to število večje kot nastavljeno število, ki se spremija s potenciometrom se število 10ms nastavi nazaj na 0. Nato izklopi timer in resetira njegovo vrednost na 0.
void startMotor(){
TCCR1A &= ~(1 << COM1A1); //Normal pin function
digitalWrite(MOTOR_OUTPUT, 0);
delay(START_UP_PULSE_LENGHT_ms);
digitalWrite(MOTOR_OUTPUT, 1);
TCCR1A |= (1 << COM1A1); //Pin to timer
TCCR1B |= (1 << CS10); //Start pwm
}
Ta funkcija zažene motor. Ker se motor težje zažene na nizkem delavnem ciklu najprej spusti nekaj ms dolg pulz za njegov zagon. Za tem pritrdi izhodni pin nazaj na timer in ga vklopi. Od tukaj naprej bo motor deloval z nastavljeno hitrostjo.
void startWelding(unsigned int pre_gas_time){
digitalWrite(GAS_OUTPUT, 1);
delay(pre_gas_time);
digitalWrite(TRANSFORMATOR_OUTPUT, 1);
delay(CURRENT_TO_MOTOR_START_TIME_ms);
startMotor();
}
Najprej se vklopi pred plin, ki bo tekel do kocna vajenja oziroma še dlje. Ko ta čas preteče se bo vklopil še transformator za varilni tok. Potem je nekaj ms pavze in nato se vklopi še motor.
char getMode(uint16_t pulse_val, uint16_t dot_val){
if(pulse_val <= 500 && dot_val <= 500){
return 'n'; //Normal welding mode
}
if(pulse_val <= 500 && dot_val > 500){
return 'd'; //Dot mode
}
if(pulse_val > 500 && dot_val > 500){
return 'p'; //Pulse mode
}
else{
return 'w'; //Wrong parametrs
}
}
Ta funkcija vrne znak, ki pomeni nek način dela. Funkcija določi način dela na podlagi dolžine pulza pri točkovnem varjenju in dolžine premora pri pulznem varjenju. Če so vnešeni napačni parametri, ki jih kmiljenje ne more izvesti pa se prižge statusna lučka.
void stopWelding(){
TCCR1A &= ~(1 << COM1A1); //Normal pin function
digitalWrite(MOTOR_OUTPUT, 1);
delay(MOTOR_TO_CURRNET_STOP_TIME);
digitalWrite(TRANSFORMATOR_OUTPUT, 0);
after_gas_time_count = 0; //Reset timmer
TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); //Start countdown for after gas
}
Ta funkcija se kliče čisto na koncu varjenja. Najprej odstrani pin za motor iz PWM timerja. Nato izklopi motor tako, da nastavi izhod na logično 1. Na tem počaka za nastavljen čas in izklopi še transformator. Zadjna stvar ki jo naredi je pa, da vklpi časovnik za po plin tako, da mu vklopi uro. Vrednost prescalerja je v tem primeru 1024
unsigned int pre_gas_delay = map(analogRead(PRE_GAS_POTENTIOMETER), 0, 1023, 0, PRE_GAS_TIME_ms);
after_gas_time = map(analogRead(AFTER_GAS_POTENTIOMETER), 0, 1023, 0, REAL_AFTER_GAS_TIME_ms);
unsigned int dot_weld_time = map(analogRead(DOT_POTENTIOMETER), 0, 1023, 0, DOT_WELD_TIME_ms);
unsigned int pulse_weld_time = map(analogRead(PULSE_POTENTIOMETER), 0, 1023, 0, PULSE_WELD_TIME);
OCR1A = map(analogRead(SPEED_POTENTIOMETER), 0, 1023, 0, ICR1);
char mode = getMode(pulse_weld_time, dot_weld_time);
bool disable_weld = false;
if(mode == 'w'){
digitalWrite(DEBUG_LED, 1);
disable_weld = true;
}
Ta kode se že izvaja v void loop(). loop() se začne po setup() in se ponavlja, dokler ima procesor napajanje.
Tukaj program pridobi spremeljive parametre, ki jih bo kasneje uporabljal za spreminjanje poteka varjenja. Z funkcijo map() določi pravo vrednost gledena lego drsnika v potenciometru. Če pa so nastavljeni neveljavni parametri pa se prižge debuging LED dioda in onemogoči varjenje.
if(!digitalRead(WELDING_TOARCH) && !disable_weld){
digitalWrite(DEBUG_LED, 0);
switch(mode){
case 'n':
startWelding(pre_gas_delay);
while(!digitalRead(WELDING_TOARCH)); //Waith
stopWelding();
break;
case 'd':
startWelding(pre_gas_delay);
delay(dot_weld_time);
stopWelding();
while(!digitalRead(WELDING_TOARCH));
break;
case 'p':
startWelding(pre_gas_delay);
delay(dot_weld_time);
while(!digitalRead(WELDING_TOARCH)){
TCCR1A &= ~(1 << COM1A1); //Normal pin function
digitalWrite(MOTOR_OUTPUT, 1);
delay(MOTOR_TO_CURRNET_STOP_TIME);
digitalWrite(TRANSFORMATOR_OUTPUT, 0);
if(digitalRead(WELDING_TOARCH)){
break;
}
delay(pulse_weld_time);
if(digitalRead(WELDING_TOARCH)){
break;
}
digitalWrite(TRANSFORMATOR_OUTPUT, 1);
delay(CURRENT_TO_MOTOR_START_TIME_ms);
startMotor();
if(digitalRead(WELDING_TOARCH)){
break;
}
delay(dot_weld_time);
}
stopWelding();
break;
}
}
Ta koda je tudi del loop()-a. Najprej preveri, če je pritisnjena tipka na gorilniku in če sploh lahko začne z varjenjem. Če sta oba pogoja izpolnjena switch() case določi, kaj se bo zgodilo.
- Normalno varjenje
Najprej pokliče funkcijo startWelding() za pričetek varjenja. Ko se ta funkcija izvede pa preide v prazno zanko. V tej zanki ostane, dokler je tipka na gorilniku pritisnjena. Ko pa jo spustimo izvede še zanko stopWelding().
- Točkovno varjenje
Kot pri normalnem varjenju se najprej izvede funkcija startWelding(). Nato počaka za nastavljen čas in kliče funkcijo stopWelding(). Nato pa preide v prazno zanko v kateri ostane dokler držimo tipko.
- Pulzno varjenje
Tukaj se kot pri prejšnjih 2 funkcijah najprej kliče startWelding(). Ko se ta funkcija konča počaka za dolžino pulza in preide v zanko, ki deluje dokler držimo tipko. Ta zanka na začetku vgasne moto in varilni tok in nato počaka za čas pavze. Nato ga spet prižge in to se ponavlja dokler držimo tipko. Ker so zamiki tukaj precej dolgi mora tudi sproti preverjat stanje tupke. Zato so v zanki if stavki, ki prekinejo zanko bo sprmembi stanja tipke. Po izhodu iz zanke pa še pokliče stopWelding().
CO2 bo s časoma uničil tesnila v ventilu in reducionem ventilu za verjenje. Zato ga je po koncu varjenja vedno potrebno izpustiti iz sistema. Na nekaterih varilnih aparatih se to naredi tako, da odstranite držalo za žico in pritisnete tipko na gorilniku. Tukaj je za to dodatno stikalo. Problem je tudi napeljevanje žice v gorilnik. Pri nekaterih varilnih aparath morate ročno nastaviti hitrost potiskanja žice in potem morate ponovno poiskati idelano hirost. Tuakj je dodana tipka, ki potisne žico z maksimalno hitrostjo
if(!digitalRead(PUSH_WIRE_SWITCH)){
TCCR1A &= ~(1 << COM1A1); //Normal pin function
digitalWrite(MOTOR_OUTPUT, 0); //Satrt motor at max speed
while(!digitalRead(PUSH_WIRE_SWITCH)); //Waith
digitalWrite(MOTOR_OUTPUT, 1); //Stop motor
}
//Release gas
if(!digitalRead(RELEASE_GAS_SWITCH)){
digitalWrite(GAS_OUTPUT, 1);
while(!digitalRead(RELEASE_GAS_SWITCH));
digitalWrite(GAS_OUTPUT, 0);
}
Koda uporablja zanke, da za čas pritisnjen tipke onemogoči ostalo izvajanje programa.
Projekt je preprost za samogradnjo. Vezja lahko dobite pri meni ali pa jih naredite sami. Več o tem bom povedal kasneje.
Ker se bo MOSFET za krmiljenje motorja malo grel ga je potrebno ustrezno hladiti. Načeloma bi zadoščala navadna ALU plošča ali pritrditev na ohišje varilnega aparata. Paziti je potrebno da je MOSFET izoliran. Priklopite lahko tudi motor za napetost 24V vendar morate prilagoditi tudi relja, ki delujeta na isti veji. Pazite tudi na vhodne napetosti v vezje.
Mikrokrmiljnik se sprogramira z namenskim programatorjem. Lahko uporabite tudi drug Arduino z kodo ArduinoISP. Program za nalaganje je AVRdude oziroma AVRdudes če hočete imetu GUI.
Nastavitve mikrokrmiljnika
Za morebitna vprašanja me kontaktirajte na e-mail
Komponente na zgornji strani
Komponente na spodnji strani
Vezje je enostransko dimenzij 104x87,3mm. Prilagojeno je za izdelavo v domači delavnici. Vsi upori in keramični kondenzatorji so v 0805 ohišju, kar jih naredi preproste za spajkanje. Samo kondenzatorja pri oscilatorju sta v 1206 ohišju, ker sem jih ravno imel na zalogi. Vezje ima nekaj kratkih jumperjev, ki jih njlažje naredite iz nogic za komponente. Za daljše povezave pa lahko uporabite žice iz UTP kabla.
Na sliki vezja je nekaj povezav na zgornji strani. Namesto teh pri samogradnji napeljete žico.
Shema
Zrcaljena zgornja stran vezja
Koda za PlarformIO
Koda v .hex formatu