Mig-mag kaynak makinesi modifikasyonu.

semih_s

Kıdemli Üye
Katılım
16 Aralık 2020
Mesajlar
1,515
Kullandığım gazaltı kaynak makinesinde eksikliğini gördüğüm iki konuda iyileştirme yapmaya karar verdim. Bunlar:

1- Tel besleme hızının daha iyi kontrol edilmesi
2- Koruyucu gazın kaynak başlamadan önce (preflow) ve kaynak bittikten sonra (postflow) ne kadar süre açık kalacağını ayarlayacak kontrollerin eklenmesi

Makinenin kontrol kartı torç voltajını tetiğe basıldığında veriyor ve aynı anda gaz selenoidini açıp tel besleme motorunu sürüyor. tetik bırakıldığında kaynak akımını, tel beslemesini ve koruyucu gazı yine aynı anda kesiyor.


ön.jpg
iç.jpg

Makine bu; Bursa'da merdiven altı tekniğiyle üretiliyor. Kasası ve fotoğraftaki membran tuş takımı Türkiye'de üretiliyor, gerisi Çin'den geliyor. 1 yıl merdiven altı garantisi var. İlk arızası garanti kapsamında onarıldı bile :) . Arıza vesilesiyle montaj ve tamiratını yapanlarla da tanıştım...

Motor devrini okumanın zor olacağını düşünmüştüm ama kolay oldu. Koyu kıvamlı akrilik yapıştırıcı ile mıknatıs yapıştırdım. Yapıştırıcının mil yatağına sızıp bozmaması için nitril eldivenle operasyon bölgesini(!) izole ettim.

motor.jpg
motor-2.jpg
motor-3.jpg


Lineer Hall sensörü çıkışını osiloskopla kontrol ettiğimde 5V beslemede, 3V 2V (2V ila 4V arasında) bir salınım yaptığını gözlemledim ve sadece scmitt triger ile mcuya beslemeye karar verdim. Aşağıda montajlanmış devre, hall sensör çıkışı ve schmitt trigger çıkışı görünüyor. Fotoğraflardaki time base ve frekans tutmuyor ama motor aynı devirde dönüyor .

devir okuma.jpg
osiloskop-hall output.jpg
osiloskop-schmitt trigger output.jpg


Kontrol kartı, tetik inputunu, motor kontrolünü ve gaz selenoidi kontrolünü orjinal kontrolcüden alıp ilave ayarlara göre manipule edecek. Kartı bastım, program sığarsa atmega48 sığmazsa atmega168 lehimleyeceğim. Bu uygulamanın en güzel tarafı geliştirme sırasında kaynak makinesini kullanmama engel olmayacak olması oldu. Kartı devreye almak veya devreden çıkarmak 5 dakika bile sürmeyecek.

speed-pre-postv2_şema.jpg


baskı.jpg
kontrol kartı.jpg
baskı alt.jpg


Düzenleme: devre şeması.
 

Ekler

  • speed-pre-postv2_şema.jpg
    speed-pre-postv2_şema.jpg
    242.7 KB · Görüntüleme: 119
Son düzenleme:
Çok iyi duruyor. Cihazı internette bulamadım, eski bir model mi? Ayrıca evde baskı devre üretebilmek gelişim için müthiş faydalı, kartın arka kısmını da ekleyebilir misin?
 
Cihazı zaman zaman sahibinden'den satıyorlar. Daha da yeni yeni oturtacaklar işi. Biraz karambole yürüyorlar, anladığım kadarıyla pazarlama kanalına karar verememişler, toptan pazarlamaları zor olur gibi geldi bana, nakit çalışmak zorundalar. Ekip ve organizasyon işini de çözmeleri lazım. Ama talep fazlaymış.

Bastığım kartın arka yüzünü ekleyeyim.
 
Merak ettim cihaz orjinalinde denetleyici ile mi kontrol ediliyor yoksa analog bir düzeni mi var?
 
Orjinalinde denetleyiciyle kontrol ediliyor. İnverter ve kontrolcü ayrı
 
Orjinalinde denetleyiciyle kontrol ediliyor. İnverter ve kontrolcü ayrı
bu mig kaynağında da örneğin 3 volt 500A olarak mı çalışıyor vfd yoksa yüksek frekansda elektron hareket ettirip bu hareketten ortaya çıkan ısıyla vs.'mi çalışıyor.
 
Mig modu sabit voltajla çalışır. Voltajı ayarlanabilir. Tel besleme hızına göre de akım değişir. Kaynaklanacak malzemeye göre ayar yapılıyor.
 
PWM için olan MOSFET bağlantısı doğru değil gibime geliyor. Gate'in üzerine NPN koymuşsun. Bu durumda NPN'in bereketini alman için +5V un 0.7V üzerinde bir voltaj vermen lazım. Alttaki PNP ise hiçbir zaman ON olmayacak. Doğrusu, PNP yukarıda, NPN aşağıda olması lazım.
 
Aynı durum Q5 için de geçerli. Emitter takipçisi modunda transistör, o yüzden röleye 5V gelmesi için transistör bazına 5.7 V gelmesi gerekir. Röleyi kollektöre almak daha mantıklı.
 
Aynı durum Q5 için de geçerli. Emitter takipçisi modunda transistör, o yüzden röleye 5V gelmesi için transistör bazına 5.7 V gelmesi gerekir. Röleyi kollektöre almak daha mantıklı.
Mosfet geytini daha yüksek akımla sürebiliyorum böyle. Hem de transistörler aynı anda iletime geçmemiş oluyor. Q5 dizgide kolaylık olduğu için o şekilde bağlandı, öncesinde denedim kolayca açıyor röleyi.
 
Devre bu hali ile de çalışır, ama MOSFET gate tam olarak 5 V ile sürülmemiş oluyor. 4.3 V ile sürülmüş oluyor. Yeterince iletime geçiyorsa MOSFET mesele yok.

Röleyi de gene aynı şekilde 4.3 V ile sürmüş oluyorsun. 5 V luk röle 4.3 V da da çeker mi? Demekki sendeki röle çekiyor. Ama 5 V luk bir rölenin bobinine 5 V vermek her zaman daha iyidir.
 
Devre bu hali ile de çalışır, ama MOSFET gate tam olarak 5 V ile sürülmemiş oluyor. 4.3 V ile sürülmüş oluyor. Yeterince iletime geçiyorsa MOSFET mesele yok.

Röleyi de gene aynı şekilde 4.3 V ile sürmüş oluyorsun. 5 V luk röle 4.3 V da da çeker mi? Demekki sendeki röle çekiyor. Ama 5 V luk bir rölenin bobinine 5 V vermek her zaman daha iyidir.
Röleyi 3.3V ile denedim ve açıldı. Anahtarlanan bacaktan kayda değer akım geçmiyor. Düşük voltajla sürünce kontak direnci biraz artıyordur diye tahmin ediyorum, akım geçecek olsa 5V ile sürmeyi tercih ederdim.
Motor da yüksek akım çekmiyor. 24V 800mA yazıyor üzerinde. mosfet 4.5V gate geriliminde 15mOhm Rds diyor datasheette. 4 V ile bile sorun olmayacak grafiklere bakılırsa.(mosfetler: 09N03LA )
 
Hız kontrol için uğraşmaktan vazgeçtim. Biraz zor olacak o çalışma, modifiye kartı makineye takmaya karar verip sadece gaz selenoidini kontrol edecek şekilde bağladım. Şu halde ön-gaz ve son gaz sürelerini kontrol edebiliyorum. Pid ile hız kontrolü için ayrı bir çalışma yapıp sonuca göre ekleyeceğim programa.

Uygulamada tahmin ettiğimden farklı şeyler oldu ve projede değişiklikler gerekti. Makine motor ve selenoidi çalıştıracak voltajı kaynak voltajı ile beraber üretiyormuş. Bu nedenle kaynak voltajını açmadan önce gaz selenoidini açmak için ayrı bir güç kaynağına gerek oldu. 20V bir laptop adaptörü ekledim. 7805 lineer regülatörü minik buck çevirici ile değiştirdim.

Sonra masamda doğru çalışan da devre makinede çalışmadı. Kaynak torcundaki tetiğin kabloları kaynak kablosu boyunca uzanıyor. Buradan parazait kaptığını düşünüyorum. Bunun etkisi kaynak sırasında motorun kesikli çalışması ve kaynağın da kesikli devam etmesi oldu. Tetik inputuna 1K direnç ve 100nF kondansatörle lowpass ekledim. Problem çözüldü. Sonra röleyi de söktüm ve tetik çıkışını da transistörle yaptım. Makinenin kontrol katı ve modifiye kart ortak ground çalışıyor şimdi.

Kart üzerinde bu şemaya göre değşiklik yaptım. lm7805 yerine buck bağlandı.
speed-pre-postv4-rölesiz-şema.jpg


Mig-mod:
/*
 * mig-mod.cpp
 *
 * Created: 19.05.2023 17:50:08
 * Author : sem
 * Mig-mag kaynak makinesi için tel hızı kontrolü ve postflow ve preflow ayar fonksiyonlarını ekler
 * Kaynak makinesi kontrol katı ve inverter katından oluşuyor.
 * Bu kod kullanıcı inputları ile kontrol kartı inputları ve outputları arasında çalışıyor.
 *
 * Kullanıcının tetik inputunu okumak,
 * Kullanıcının tetik inputunu kontrol kartına iletmek.
 * Gaz selenoidini kontrol etmek
 * Tel sürme motorunu kontrol etmek
 * Ayar potlarını okumak.
 *
 *State machine olarak çalıştırmak daha kolay olacak
 
 * 1. durum bekleme durumu
 *        -tüm outputlar kapalı.
 *        -sürekli inputları okuma
 *        -Bu durumdan tek çıkış preflow durumuna (tetiğe basılmasıyla)
 *        -Bu modda hızlı tel besleme tuşu çalışır, kaynak tli değişiminde kolaylık için
 * 2. preflow durumu
 *        -Gaz selenoidi açılır.
 *        -preflow süresi boyunca;
 *            -tetik inputu okunur, tetik kapanırsa bekleme durumuna dönülür
 *            -preflow süresi dolunca kaynak yapma durumuna geçilir
 * 3. kaynak yapma durumu
 *        -Buraya geçildiğinde gaz selenoidi zaten açıktır.
 *        -tetik-out çıkışı açılır. orjinal kontrol katının inverteri etkinleştirmesi sağlanır
 *        -motor sürülür.
 *        -tetik sürekli okunur.
 *        -tetik bırakıldığında postflow durumuna geçilir.
 *    4. postflow durumu
 *        -motor durdurulur
 *        -tetik-out çıkışı kapatılır.
 *        -postflow süresi boyunca;
 *            -tetik inputu okunur.
 *            -tetik tekrar basılırsa kaynak yapma durumuna geçilir
 *            -postflow süresi dolunca bekleme durumuna geçilir.
 *
 */

#define F_CPU 8000000        // dahili osilatörle
#include <avr/io.h>
#include <avr/interrupt.h>
#include <ctype.h>
#include <util/delay.h>

// Debugging için uart ayarları
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

// durumlar
#define BEKLEME 0
#define PREFLOW 1
#define KAYNAK 2
#define POSTFLOW 3

#define motor_on
#define    motor_off

#define    gaz_on        PORTD|=1<<PIND6
#define gaz_off        PORTD&=~(1<<PIND6)

#define tetik_on    PORTD|=1<<PIND7
#define tetik_off    PORTD&=~(1<<PIND7)
#define tetik_oku    !((PIND>>2)&1)

#define post_oku    ADMUX&=~0b1111;    ADMUX|=0b1;    ADCSRA|= (1<<ADSC);        //ADC1
#define pre_oku        ADMUX&=~0b1111;    ADCSRA|= (1<<ADSC);                    //ADC0
#define spd_oku        ADMUX&=~0b1111;    ADMUX|=0b10;    ADCSRA|= (1<<ADSC);    //ADC2

#define devir_oku    ((PIND>>PIND5)&1)

uint8_t durum,gaz,devir_durum;
uint16_t post,pre;        //    spd;
uint8_t spd;
uint8_t u8buffer;
int8_t i8buffer;

uint16_t devir_per[8];
uint32_t per_top;

void timer1_init(uint8_t on_off);
void USART_Init( unsigned int ubrr);            //datasheet'ten olduğu gibi alındı
void USART_Transmit( unsigned char data );        //datasheet'ten olduğu gibi alındı

int main(void)
{
    DDRB|=0b111111;
    
    //while(1);
    // I/O ayarla
    DDRD |= 0b11001000;
    PORTD |= 1<<PIND2 ; // tetik inputunun pullup direncini açar
    
    DDRC =0; // sadece ADC inputları var
    
    //ADC ayarla 8 bit okunacak frekans yüksek olabilir
    
    
    ADMUX|= 1<<REFS0 | 1<<ADLAR;    //    8 bit ADC için left adjust, referans voltajı AVCC
    ADCSRA |= 1<<ADEN | 1<<ADPS2 ;    //   
    DIDR0 |= 0b111111;                //
    ADCSRA|= (1<<ADSC);                //    İlk adc çevrimini başlat
    
    //Timer2 motor pwm için OC2B'ye bağlı
    
    TCCR2A|= 1<< COM2B1 | 1<<WGM21 | 1<<WGM20 ;            // fazst PWM OC2B non-inverting
    TCCR2B |= 0b10;                                        // 0b10: prscl FCPU/8 yaklaşık 4KHz pwm frekansı
    OCR2B=0;
    
    USART_Init(MYUBRR);
    
    while (1)
    {
        spd_oku;
        /*
        timer1_init(1);
        
        while(1) // pid geliştirme
        {
            
            
            if((ADCSRA & (1<<ADIF)))//    Eğer adc çevrimi tamamlanmışsa çalışır
            {
                 spd=ADCH;            //    Pot oku
                 OCR2B=ADCH;
                 ADCSRA|= (1<<ADSC);    //    Yeni çevrim başlat
            }
            
            if((devir_oku>0)&&(devir_durum<1))
            {
                devir_durum=devir_oku;
                
                
                
                u8buffer=TCNT1;
                TCNT1=0;
                //timer1_init(1);   
                
                
            }
            USART_Transmit(u8buffer);
            //USART_Transmit(255);
            devir_durum=devir_oku;
            //_delay_us(100);
            
            
            
        }
        
        */
        while(durum==BEKLEME)
        {
            PORTB=0b111; // debugging için portb'ye bağlı led dizisini yakar önemsiz
            // adc 8 bit okunacak, left adjust yapılandırılacak
            // ADC sinyallerinin birbirine etkisini azaltmak için ardışık üç ölçümden sonuncusunu örnekliyorum.
            spd_oku;
            ADCSRA|= 1<<ADSC;                //ADC okuma başlat
            while(!(ADCSRA & (1<<ADIF)));    //okuma tamamlanana kadar bekle
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            spd=ADCH;   
            
            post_oku;
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            // postlow değeri 0-5 saniye olması için bir sabitle çarpılmalı
            // TCNT1 sayacı 65535 tikte 8,39 saniye oluyor 5 saniye için 39.055 tik
            // postlow potunun 255 olan max değerini 39.055/255=153 ile çarpmak gerek
            post=ADCH*153;
            
            pre_oku;
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            // preflow değeri 0-5 saniye olması için bir sabitle çarpılmalı
            // TCNT1 sayacı 65535 tikte 8,39 saniye oluyor 5 saniye için 39.055 tik
            // preflow potunun 255 olan max değerini 39.055/255=153 ile çarpmak gerek
            pre=ADCH*153;
            
            gaz_off;
            if(tetik_oku>0)
            {
                _delay_ms(25);
                if(tetik_oku>0)
                {
                    durum=PREFLOW;
                    gaz_on;
                    timer1_init(1);  // timeri burada etkinleştiriyorum çünkü preflow durumu eksta while döngüsü eklemek istemiyorum
                }
            }
        }
        
        while(durum==PREFLOW)
        {
            PORTB=0b100;
            
            if(TCNT1>=pre)
            {
                durum=KAYNAK;
                tetik_on;   
                _delay_ms(25);
            }
            if(!tetik_oku) //tetik oku 0 dönerse beklemeye geç
            {
                _delay_ms(25);
                if(!tetik_oku)
                {
                    durum=BEKLEME;
                    gaz_off;        //gaz kapat
                    timer1_init(0); //timer1 kapat
                }
            }
        }
        
        while(durum==KAYNAK)
        {
            PORTB=0b10000;
            tetik_on;
            while(tetik_oku)
            {
                // motor devir okuma ve pwm pid kontrolü
                // devir sinyali frekansı düşük ve yapılacak çok iş yok
                // bu nedenle sinyal periyodunu sürekli okuma ile ölçmek hataya sebep olmayacak
                // yazılımla pin change test edip zaman damgasıyla kontrol edilebilir.
                // burada da timer1'i kullanmak mümkün. precale daha uygun seçerek.
                // timer1_init
    /*
                devir_durum=devir_oku;
                if(devir_durum!=deviroku)
                {
                    devir_per[i]=TCNT1;
                    timer1_init(2);    //
                }
        */       
                
                
            }
    
            // döngüden çıkıldığında postflowa geçilir
            
            tetik_off;
            motor_off;
            timer1_init(1);
            durum=POSTFLOW;
        }
        
        while(durum==POSTFLOW)
        {
            PORTB=0b111000;
            if(TCNT1>=post)
            {
                timer1_init(0);
                durum=BEKLEME;
                gaz_off;
            }
            if(tetik_oku)
            {
                _delay_ms(25);
                if(tetik_oku)
                {
                    timer1_init(0);
                    durum=KAYNAK;
                }
            }
        }
    }
}

void timer1_init(uint8_t on_off)
{
    // onoff=0 timer kapalı
    // on_off=1 timer pre-post flow sürelerine göre yapılandırılır.
    // on_off=2 timer kaynak durumunda motor devir periyodunu ölçecek şekilde yapılandırılmış.
    if(on_off==0)//timer kapat
    {
        TCCR1B &= ~(0b111); // prescale kapat
        TCNT1=0;            // sayacı resetle
    }
    
    else if(on_off==1)// süre ölçümü için
    {
        // 65.535*1.024/8.000.000=8,39 saniye taşım süresi preflow ve postflow sınırları için yeterli
        // 7.812,5 tik/saniye
        TCCR1B&=~0b111; // timer prscl önce resetlenir
        TCNT1=0;
        TCCR1B|= 0b101; //prescaler 0b1101 için 1024
        
    }
    else if(on_off==2)// hız ölçümü için
    {
        // motor devir ölçümü için 100hz ila 10hz arasında sinyal sürelerini ölçeceğim.
        // en az 0,1 saniyede taşım oluşmalı
        // 0,1*8.000.000/65.535=12,2 prescaler bundan büyük olmalı 64 olabiliyor en yakın
        // 65535*64/80000000=0,525 yaklaşık yarım saniyede sayaç taşar.
        // 8000000/64/1000=125 tik/ms
        // 256 prscl için 31,25 tik/ms
        TCCR1B&=~0b111; // timer prscl önce resetlenir
        TCNT1=0;
        TCCR1B |= 0b100; // prscl 0b11 için 64 -prscl 0b100 için 256
        
    }
}

void USART_Init( unsigned int ubrr)
{
    /*Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    //Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);
}
    
void USART_Transmit( unsigned char data )
{
    /* Wait for empty transmit buffer */
    if( ( UCSR0A & (1<<UDRE0)) )
    {
        UDR0 = data;
    }
    /* Put data into buffer, sends the data */
    
}   

/*
            ADCSRA|= 1<<ADSC;                //ADC okuma başlat
            while(!(ADCSRA & (1<<ADIF)));    //okuma tamamlanana kadar bekle
            spd=ADCH;
            OCR2B=ADCH;
*/

Kod, hız kontrol-pid fonksiyonları hariç 1KB altında derlendi. Atmega48 lehimledim karta. 3kb devamı için hayli hayli yeter..


mig-tambur.jpg

mig-inverter.jpg


mig-panel.jpg
 
Hız kontrol için uğraşmaktan vazgeçtim. Biraz zor olacak o çalışma, modifiye kartı makineye takmaya karar verip sadece gaz selenoidini kontrol edecek şekilde bağladım. Şu halde ön-gaz ve son gaz sürelerini kontrol edebiliyorum. Pid ile hız kontrolü için ayrı bir çalışma yapıp sonuca göre ekleyeceğim programa.

Uygulamada tahmin ettiğimden farklı şeyler oldu ve projede değişiklikler gerekti. Makine motor ve selenoidi çalıştıracak voltajı kaynak voltajı ile beraber üretiyormuş. Bu nedenle kaynak voltajını açmadan önce gaz selenoidini açmak için ayrı bir güç kaynağına gerek oldu. 20V bir laptop adaptörü ekledim. 7805 lineer regülatörü minik buck çevirici ile değiştirdim.

Sonra masamda doğru çalışan da devre makinede çalışmadı. Kaynak torcundaki tetiğin kabloları kaynak kablosu boyunca uzanıyor. Buradan parazait kaptığını düşünüyorum. Bunun etkisi kaynak sırasında motorun kesikli çalışması ve kaynağın da kesikli devam etmesi oldu. Tetik inputuna 1K direnç ve 100nF kondansatörle lowpass ekledim. Problem çözüldü. Sonra röleyi de söktüm ve tetik çıkışını da transistörle yaptım. Makinenin kontrol katı ve modifiye kart ortak ground çalışıyor şimdi.

Kart üzerinde bu şemaya göre değşiklik yaptım. lm7805 yerine buck bağlandı.
24415 eklentisine bak

Mig-mod:
/*
 * mig-mod.cpp
 *
 * Created: 19.05.2023 17:50:08
 * Author : sem
 * Mig-mag kaynak makinesi için tel hızı kontrolü ve postflow ve preflow ayar fonksiyonlarını ekler
 * Kaynak makinesi kontrol katı ve inverter katından oluşuyor.
 * Bu kod kullanıcı inputları ile kontrol kartı inputları ve outputları arasında çalışıyor.
 *
 * Kullanıcının tetik inputunu okumak,
 * Kullanıcının tetik inputunu kontrol kartına iletmek.
 * Gaz selenoidini kontrol etmek
 * Tel sürme motorunu kontrol etmek
 * Ayar potlarını okumak.
 *
 *State machine olarak çalıştırmak daha kolay olacak
 
 * 1. durum bekleme durumu
 *        -tüm outputlar kapalı.
 *        -sürekli inputları okuma
 *        -Bu durumdan tek çıkış preflow durumuna (tetiğe basılmasıyla)
 *        -Bu modda hızlı tel besleme tuşu çalışır, kaynak tli değişiminde kolaylık için
 * 2. preflow durumu
 *        -Gaz selenoidi açılır.
 *        -preflow süresi boyunca;
 *            -tetik inputu okunur, tetik kapanırsa bekleme durumuna dönülür
 *            -preflow süresi dolunca kaynak yapma durumuna geçilir
 * 3. kaynak yapma durumu
 *        -Buraya geçildiğinde gaz selenoidi zaten açıktır.
 *        -tetik-out çıkışı açılır. orjinal kontrol katının inverteri etkinleştirmesi sağlanır
 *        -motor sürülür.
 *        -tetik sürekli okunur.
 *        -tetik bırakıldığında postflow durumuna geçilir.
 *    4. postflow durumu
 *        -motor durdurulur
 *        -tetik-out çıkışı kapatılır.
 *        -postflow süresi boyunca;
 *            -tetik inputu okunur.
 *            -tetik tekrar basılırsa kaynak yapma durumuna geçilir
 *            -postflow süresi dolunca bekleme durumuna geçilir.
 *
 */

#define F_CPU 8000000        // dahili osilatörle
#include <avr/io.h>
#include <avr/interrupt.h>
#include <ctype.h>
#include <util/delay.h>

// Debugging için uart ayarları
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

// durumlar
#define BEKLEME 0
#define PREFLOW 1
#define KAYNAK 2
#define POSTFLOW 3

#define motor_on
#define    motor_off

#define    gaz_on        PORTD|=1<<PIND6
#define gaz_off        PORTD&=~(1<<PIND6)

#define tetik_on    PORTD|=1<<PIND7
#define tetik_off    PORTD&=~(1<<PIND7)
#define tetik_oku    !((PIND>>2)&1)

#define post_oku    ADMUX&=~0b1111;    ADMUX|=0b1;    ADCSRA|= (1<<ADSC);        //ADC1
#define pre_oku        ADMUX&=~0b1111;    ADCSRA|= (1<<ADSC);                    //ADC0
#define spd_oku        ADMUX&=~0b1111;    ADMUX|=0b10;    ADCSRA|= (1<<ADSC);    //ADC2

#define devir_oku    ((PIND>>PIND5)&1)

uint8_t durum,gaz,devir_durum;
uint16_t post,pre;        //    spd;
uint8_t spd;
uint8_t u8buffer;
int8_t i8buffer;

uint16_t devir_per[8];
uint32_t per_top;

void timer1_init(uint8_t on_off);
void USART_Init( unsigned int ubrr);            //datasheet'ten olduğu gibi alındı
void USART_Transmit( unsigned char data );        //datasheet'ten olduğu gibi alındı

int main(void)
{
    DDRB|=0b111111;
   
    //while(1);
    // I/O ayarla
    DDRD |= 0b11001000;
    PORTD |= 1<<PIND2 ; // tetik inputunun pullup direncini açar
   
    DDRC =0; // sadece ADC inputları var
   
    //ADC ayarla 8 bit okunacak frekans yüksek olabilir
   
   
    ADMUX|= 1<<REFS0 | 1<<ADLAR;    //    8 bit ADC için left adjust, referans voltajı AVCC
    ADCSRA |= 1<<ADEN | 1<<ADPS2 ;    //  
    DIDR0 |= 0b111111;                //
    ADCSRA|= (1<<ADSC);                //    İlk adc çevrimini başlat
   
    //Timer2 motor pwm için OC2B'ye bağlı
   
    TCCR2A|= 1<< COM2B1 | 1<<WGM21 | 1<<WGM20 ;            // fazst PWM OC2B non-inverting
    TCCR2B |= 0b10;                                        // 0b10: prscl FCPU/8 yaklaşık 4KHz pwm frekansı
    OCR2B=0;
   
    USART_Init(MYUBRR);
   
    while (1)
    {
        spd_oku;
        /*
        timer1_init(1);
       
        while(1) // pid geliştirme
        {
           
           
            if((ADCSRA & (1<<ADIF)))//    Eğer adc çevrimi tamamlanmışsa çalışır
            {
                 spd=ADCH;            //    Pot oku
                 OCR2B=ADCH;
                 ADCSRA|= (1<<ADSC);    //    Yeni çevrim başlat
            }
           
            if((devir_oku>0)&&(devir_durum<1))
            {
                devir_durum=devir_oku;
               
               
               
                u8buffer=TCNT1;
                TCNT1=0;
                //timer1_init(1);  
               
               
            }
            USART_Transmit(u8buffer);
            //USART_Transmit(255);
            devir_durum=devir_oku;
            //_delay_us(100);
           
           
           
        }
       
        */
        while(durum==BEKLEME)
        {
            PORTB=0b111; // debugging için portb'ye bağlı led dizisini yakar önemsiz
            // adc 8 bit okunacak, left adjust yapılandırılacak
            // ADC sinyallerinin birbirine etkisini azaltmak için ardışık üç ölçümden sonuncusunu örnekliyorum.
            spd_oku;
            ADCSRA|= 1<<ADSC;                //ADC okuma başlat
            while(!(ADCSRA & (1<<ADIF)));    //okuma tamamlanana kadar bekle
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            spd=ADCH;  
           
            post_oku;
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            // postlow değeri 0-5 saniye olması için bir sabitle çarpılmalı
            // TCNT1 sayacı 65535 tikte 8,39 saniye oluyor 5 saniye için 39.055 tik
            // postlow potunun 255 olan max değerini 39.055/255=153 ile çarpmak gerek
            post=ADCH*153;
           
            pre_oku;
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            ADCSRA|= 1<<ADSC;
            while(!(ADCSRA & (1<<ADIF)));
            // preflow değeri 0-5 saniye olması için bir sabitle çarpılmalı
            // TCNT1 sayacı 65535 tikte 8,39 saniye oluyor 5 saniye için 39.055 tik
            // preflow potunun 255 olan max değerini 39.055/255=153 ile çarpmak gerek
            pre=ADCH*153;
           
            gaz_off;
            if(tetik_oku>0)
            {
                _delay_ms(25);
                if(tetik_oku>0)
                {
                    durum=PREFLOW;
                    gaz_on;
                    timer1_init(1);  // timeri burada etkinleştiriyorum çünkü preflow durumu eksta while döngüsü eklemek istemiyorum
                }
            }
        }
       
        while(durum==PREFLOW)
        {
            PORTB=0b100;
           
            if(TCNT1>=pre)
            {
                durum=KAYNAK;
                tetik_on;  
                _delay_ms(25);
            }
            if(!tetik_oku) //tetik oku 0 dönerse beklemeye geç
            {
                _delay_ms(25);
                if(!tetik_oku)
                {
                    durum=BEKLEME;
                    gaz_off;        //gaz kapat
                    timer1_init(0); //timer1 kapat
                }
            }
        }
       
        while(durum==KAYNAK)
        {
            PORTB=0b10000;
            tetik_on;
            while(tetik_oku)
            {
                // motor devir okuma ve pwm pid kontrolü
                // devir sinyali frekansı düşük ve yapılacak çok iş yok
                // bu nedenle sinyal periyodunu sürekli okuma ile ölçmek hataya sebep olmayacak
                // yazılımla pin change test edip zaman damgasıyla kontrol edilebilir.
                // burada da timer1'i kullanmak mümkün. precale daha uygun seçerek.
                // timer1_init
    /*
                devir_durum=devir_oku;
                if(devir_durum!=deviroku)
                {
                    devir_per[i]=TCNT1;
                    timer1_init(2);    //
                }
        */      
               
               
            }
   
            // döngüden çıkıldığında postflowa geçilir
           
            tetik_off;
            motor_off;
            timer1_init(1);
            durum=POSTFLOW;
        }
       
        while(durum==POSTFLOW)
        {
            PORTB=0b111000;
            if(TCNT1>=post)
            {
                timer1_init(0);
                durum=BEKLEME;
                gaz_off;
            }
            if(tetik_oku)
            {
                _delay_ms(25);
                if(tetik_oku)
                {
                    timer1_init(0);
                    durum=KAYNAK;
                }
            }
        }
    }
}

void timer1_init(uint8_t on_off)
{
    // onoff=0 timer kapalı
    // on_off=1 timer pre-post flow sürelerine göre yapılandırılır.
    // on_off=2 timer kaynak durumunda motor devir periyodunu ölçecek şekilde yapılandırılmış.
    if(on_off==0)//timer kapat
    {
        TCCR1B &= ~(0b111); // prescale kapat
        TCNT1=0;            // sayacı resetle
    }
   
    else if(on_off==1)// süre ölçümü için
    {
        // 65.535*1.024/8.000.000=8,39 saniye taşım süresi preflow ve postflow sınırları için yeterli
        // 7.812,5 tik/saniye
        TCCR1B&=~0b111; // timer prscl önce resetlenir
        TCNT1=0;
        TCCR1B|= 0b101; //prescaler 0b1101 için 1024
       
    }
    else if(on_off==2)// hız ölçümü için
    {
        // motor devir ölçümü için 100hz ila 10hz arasında sinyal sürelerini ölçeceğim.
        // en az 0,1 saniyede taşım oluşmalı
        // 0,1*8.000.000/65.535=12,2 prescaler bundan büyük olmalı 64 olabiliyor en yakın
        // 65535*64/80000000=0,525 yaklaşık yarım saniyede sayaç taşar.
        // 8000000/64/1000=125 tik/ms
        // 256 prscl için 31,25 tik/ms
        TCCR1B&=~0b111; // timer prscl önce resetlenir
        TCNT1=0;
        TCCR1B |= 0b100; // prscl 0b11 için 64 -prscl 0b100 için 256
       
    }
}

void USART_Init( unsigned int ubrr)
{
    /*Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    //Enable receiver and transmitter
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);
}
   
void USART_Transmit( unsigned char data )
{
    /* Wait for empty transmit buffer */
    if( ( UCSR0A & (1<<UDRE0)) )
    {
        UDR0 = data;
    }
    /* Put data into buffer, sends the data */
   
}  

/*
            ADCSRA|= 1<<ADSC;                //ADC okuma başlat
            while(!(ADCSRA & (1<<ADIF)));    //okuma tamamlanana kadar bekle
            spd=ADCH;
            OCR2B=ADCH;
*/

Kod, hız kontrol-pid fonksiyonları hariç 1KB altında derlendi. Atmega48 lehimledim karta. 3kb devamı için hayli hayli yeter..


24417 eklentisine bak
24416 eklentisine bak

24418 eklentisine bak

Hocam merhaba. Peki tetiğe basıldığında çıkışı aktifleştirmek için nasıl bir şey yaptın? smps trafosunu süren mosfetleri sürmeye başlayarak yapılabilir, tetik bırakıldığında mosfetler kapalı olur ama bu sefer de çıkış tarafındaki kapasitörlerdeki enerji sıkıntı olmaz mı? Yani tetik bırakılmış vaziyette torcun ucundaki tel şaseye değdiğinde kapasitördeki depolanmış enerjiden kaynaklı küçük bir punto gibi çıtlak atmaz mı? Yoksa çıkış için kapasitörden sonraya ekstra mosfet anahtar mı koyuldu?
 
Hocam merhaba. Peki tetiğe basıldığında çıkışı aktifleştirmek için nasıl bir şey yaptın? smps trafosunu süren mosfetleri sürmeye başlayarak yapılabilir, tetik bırakıldığında mosfetler kapalı olur ama bu sefer de çıkış tarafındaki kapasitörlerdeki enerji sıkıntı olmaz mı? Yani tetik bırakılmış vaziyette torcun ucundaki tel şaseye değdiğinde kapasitördeki depolanmış enerjiden kaynaklı küçük bir punto gibi çıtlak atmaz mı? Yoksa çıkış için kapasitörden sonraya ekstra mosfet anahtar mı koyuldu?
Her makine aynı olmuyor sanırım. Bu makinede tetiğe basıldığında inverter çalışmaya başlıyor ve kaynak voltajıyla beraber gaz selenoidini ve motoru sürecek voltaj üretilmeye başlıyordu. Ben de bu nedenle tetiği mcuyla okuyup gazı açıp sonrasında ayarlanan zamanda mcu çıkışından makinenin anlaycağı şekilde tetiği simule ederek inverteri etkinleştirip kapatıyorum. Çıkış kapasitörlerinde bir şey kalmıyor. Hatta galiba çıkışta yüksek bir kapasite de yoktu.
 
@semih_s hocam atmega48 ye program yazarken hangi ide yi kullanıyorsunuz.
Konu başlığından bağımsız bir soru ama :(
 
Her makine aynı olmuyor sanırım. Bu makinede tetiğe basıldığında inverter çalışmaya başlıyor ve kaynak voltajıyla beraber gaz selenoidini ve motoru sürecek voltaj üretilmeye başlıyordu. Ben de bu nedenle tetiği mcuyla okuyup gazı açıp sonrasında ayarlanan zamanda mcu çıkışından makinenin anlaycağı şekilde tetiği simule ederek inverteri etkinleştirip kapatıyorum. Çıkış kapasitörlerinde bir şey kalmıyor. Hatta galiba çıkışta yüksek bir kapasite de yoktu.
Belki de tetik bırakılırken kapasitördeki enerji tükenmiş oluyor.. çıkış kapasitesini büyük tutmamak daha iyi olur demek ki
 
Belki de tetik bırakılırken kapasitördeki enerji tükenmiş oluyor.. çıkış kapasitesini büyük tutmamak daha iyi olur demek ki
Evet bana da öyle gibi geliyor. İnverterdaki sürücü mosfetler anahtarlamayı kestiğinde çıkışta kapasite olsa dahi kaynak akımı çok yüksek olduğundan insanın algılayamayacağı bir sürede ark söner. Kontrol kartının kaynak akımına anahtarlama yaptığını düşünmüyorum, ucuz bir alet bu, primer tarafından sürüyordur, çünkü anlık yüzlerce amper geçer arktan, bunu anahtarlamak pahalı olsa gerek.
Bunu düşünmemin bir sebebi de açık devre voltajının yüksek olması, 57 volt ölçüyorum açık devrede, yüksek bir kapasite olsa ince sac kaynatmam çok zor olurdu herhalde, voltaj ayarlanan 12-13 volta inene kadar, geçecek yüksek akım kontrolsüzce eritirdi başlangıç noktasını. Makinenin inverter kartını da pek yakından incelemedim, bu dediklerim biraz varsayım oluyor.
 

Çevrimiçi üyeler

Forum istatistikleri

Konular
5,885
Mesajlar
100,432
Üyeler
2,493
Son üye
cym247

Son kaynaklar

Son profil mesajları

gruptaki arkadaşlara selamlar. sıteyi bu gün fark ettim. Asansör için 2x7 segment LCD gösterge üretmek istiyorum. acaba bu sayfadaki arkadaşlardan destek alabilirmiyim. LCD nin mantık açılımı ektedir.
deneyci wrote on TA3UIS's profile.
Selam.
Amatör telsiz lisansı nasıl alınıyor?
Lisansı olmayanı forumlarına almıyorlar. :)
Bilgi alamıyoruz.
cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Back
Top