pwm dc motor hız kontrolü devresi çalışmıyor

Başlatan dgkn, 30 Ocak 2024, 18:04:18

dgkn

merhabalar. pwm ile dc motor hız kontrolü için bir devre kurdum. devremde 16f877a kullanıyorum. 4MHz kristal osilatör ile. kodumu ve devre şemasını aşağıya bırakıyorum. benim sorunum şu şekilde sürücü olarak l298n kullanıyorum. sürücüye 12V ve gnd bağlıyorum adaptör ile ve sürücüden bir gnd alıp bunu breadboardın gnd sine bağlıyorum (birkaç araştırmam sonucu önemli bir nokta olduğu söyleniyordu.). konuya gelecek olursam eğer devreyi eksiksiz kurduğuma eminim çünkü son 3 gündür uğraştığım tek şey bu devre. devrede pwm sinyalinin gönderileceği ve sürücünün enable A pinine bağlı jumper'ı ölçtüğümde sabit 2.5V var ve bu voltaj potansiyometreden değeri değiştirmeye çalıştığımda da aynı kalıyor (pot bacaklarını ölçtüm ve pot bozuk değil). aynı zamanda in1 ve in2 bacaklarını da ölçtüğümde herhangi bir gerilim alamıyorum. kısaca enable A sabit voltaj (2.5V) ve in1, in2 bacaklarında 0,01-0,02 volt gerilim var sadece. normalde olması gereken 10V (maks. çalışmada) civarı bir şey.
sorum şu buradaki hata nerede?
birçok kontroller yaptım fakat halen başaramadım. koddan çok emin olduğum için şuan son ihtimalle yapay zeka destekli bir kod yazdırıp onu deneyeceğim.
yardımcı olursanız çok sevinirim.
motoru döndürmeyi başardığımda, hız sensörü ve lcd ile rpm değerini okutup yazdıracağım ve son aşama olarakta motora yük bindiğinde istenilen hıza geri dönmesini sağlamam gerekiyor.
proteus görüntüsünde pic16f877 fakat ben 16f877a ya göre kodu ve pic bacaklarını düzenledim yani proteus ekran görüntüsü birebir devrem ile aynı değil.
kullandığım sürücü l298n (kırmızı).
burada yapmam gereken nedir bir yol gösterin lütfen kafayı yemek üzereyim. normalde kesin çok basit bir şeydir fakat bu arlar kafam yerinde değil göremiyorum.
kod (micro C)

#include <16f877a.h>
#device adc=8
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPUT,NOLVP,NOCPD,NOPROTECT,NODEBUG,NOBROWNOUT,NOWRT

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)

#define use_portb_lcd TRUE
#include <lcd.c>

unsigned int deger;
float voltaj;

void main()
{
   setup_psp(PSP_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_4,255,1);

   
   setup_CCP1(CCP_PWM);
   setup_CCP2(CCP_OFF);
   
   setup_adc(adc_clock_div_32);
   setup_adc_ports(ALL_ANALOG);
  
   set_tris_a(0x20);
   set_tris_b(0x00);
   set_tris_c(0x00);
   
   
   
   set_adc_channel(4);
   delay_us(20);
   
   output_c(0x00);
   lcd_init();
   printf(lcd_putc,"\fDC Motor\nHiz Kontrolu");
   delay_ms(1000);
   
   set_pwm1_duty(0);
   
   while(true){
   
   deger=read_adc();
   delay_us(20);
   voltaj=deger/51.0;
  

   
   output_high(pin_c3);
   output_low(pin_c4);
   
   set_pwm1_duty(deger);
   
   printf(lcd_putc,"\fVoltaj=%f V",voltaj);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Deger=%u",deger);
   delay_ms(1000);

   
   }
   
   
   
   }
   











 

ete

Programını simulasyonda çalıştırmayı denedinmi?.
En azından ADC ölçümünün ve motor kontrolünün doğru olup olmadığını oradan anlayabilirdin.
Hatta hex dosyasını ve simulasyon dosyasınıda buraya koyup bizimde görmemizi sağlayabilirdin.

Programda mantıksal bir hata görmedim. Ancak o kadar boş pinvar iken tutup da POT'u AN4 pinine bağlaman bence yanlış. 16F877A nın analog pinleri bağımsız olarak pek kullanılamıyor.
Örnek vereyim,
Senin AN4 pinini Analog olarak kullanabilmen için aşağıdaki seçenekler mevcut.
- Bütün anolog pinler aktif iken
- AN0-AN4 pinleri analog diğerleri digital
- AN7 ve AN6 pinleri digital diğerleri analog
Şemada PORTA pinleri boşta gözüküyor ama sen onları başka amaçlar için kullanıyor olabilirsin.
Normalde pinleri ADCON1 registeri ayarlıyor ama Micro-C de set_adc_channel(4) komutu verildiğinde derleyici ADCON1 registeri üzerinden bunu ayarlıyor ama acaba nasıl ayarladı bunu bilmiyoruz. Sİmulasyondan watch windowdan ADCON1 registerini izleyerek anlaşılabilirdi.

Şayet PORTA pinleri boşta ise tavsiyem AN0 pinini analog olarak kullanman. Çünki bu pini yalnız başına analog olarak tanımlayabiliyorsun.

Ete

dgkn

temelde yapmak istediğim ve izlediğim adımlar bu videoda;
https://www.youtube.com/watch?v=ee-oFts-AFY&t=896s

*bu videodaki uygulamayı yapmak istiyorum sadece. ben temelde motorun hız kontrolünü yapmak istiyorum ilk adımda hedefim bu kalan süreçte ise lcd, sensör, motor yükteyken istenilen hıza yükselme vs. vs. devam edeceğim
dosyalar ise şunlar (ek-1)

ete

Simulasyonda deneyince program ve devren çalışıyor.
Gerçekte de çalışmaması için bir sebep görmüyorum.

Tabiiki gerçek devre ile simulasyon devresi bazı farklılıklar içerir.
Genelde simulasyonda bir besleme voltajı temini ve bunun gerekli yerlere bağlanması gösterilmez.
Umarım sen işlemcinin istediği 5V tu bir şekilde üretip işlemciye ve L298'e bağlamışsındır.

Yine İşlemciye 4Mhz lik bir kristal (veya rezonatör) de bağlaman gerekiyor.
MCLR pininde 10K lık pullup direncinin olması gerekir bunuda kontrol et.
Bu dediklerim tamam ise işlemci ile L298 in bağlantılarını teker teker kontrol. Özellikle kontrol pinlerinin yanlış bacaklardan alınmamış olmasına dikkat et.
Sonuçta bütün bağlantıların şemaya uygun ise sisteminin çalışması gerekir.
Bu arada nasıl bir motor kullanıyorsun buda önemli tabiiki. L298'in akım değerlerine uygun bir motor olması gerekir. Fazla güçlü bir motor entegrenin yanmasına sebep olabilir.

Başka da söyleyecek bir şey bulamıyorum. e sorunun var ise kurduğun devre ile alakalı olduğundan bağlantılara voltajlara odaklanmanda yarar var.

Ete

dgkn

kontrol etmemi önerdiğiniz her şeyi kontrol ettim. fakat herhangi bir sonuç alamıyorum. mikrodenetleyici pwm sinyal üretmiyor olabilir mi gibi saçma sapan sorular geliyor aklıma.
ama en aklıma yatan şey akım olabilir 5V aldığım adaptör 5V 1A bu besleme ile breadboard üzerindeki mikrodenetleyiciyi besliyorum. l298n için ise 12V gerekiyor onuda başka bir adaptör ile sağlıyorum. o adaptör ise 12V 2A.

voltaj ölçümlerimde beslemelerde herhangi bir sıkıntı yok sıkıntı şurada ccp1 pinindeki değer sabit. kodları değiştiriyorum bu paylaştığım ilk kodda sabit 2.5V verdi ve pot ayarıyla oynamama rağmen değişmedi in1 ve in2 ise 0.01V gibi bir şey verdi.
normalde ccp1 pot ayarına göre ayarlanmalı ve in1, in2 pinlerinden birisi high birisi low vermeliydi. birçok kod değiştirdim 3 tane kod denedim hatta ve hatta chatgpt ile uzun bir istişare sonucu ona bile kod yazdırıp denedim fakat sınuç hüsran.

l298n sürücüsü eski bir sürücü 5 yıl önce alınmış bir sürücü o yüzden çalışmıyor olabilir diye denedim. enable bacağını 5v ile kitledim ve max verdim yani ve aynı şekilde 5v ile in1 bacağına güç verdim ve motorların ikisi de maks. hızda döndüler.

2 farklı motorum var birisi çok küçük bir DC motor birisi ise bazı sitelerde satılan araba şaftı gibi bir sistemdeki sarı tekerli motorlardan, şuan tam ismini hatırlayamadım.

gerçekten çok kötüyüm kaç gündür tek bir amaç var motorun hız ayarı sonrası yağ gibi akıp gelecek lakin çözüm bulamadım halen

ete

Bu gibi durumlarda öncelikle işlemciden şüphe edilir. Ben genelde işlemcinin boş olan bir bacağına bir led bağlarım (220 ohm seri direnç ile) programa da ekleme yapıp ilk açılışta bu ledin yanıp sönmesini sağlarım. Yanıp sönüyor ise işlemci çalışıyor demektir.
Daha sonra L298 den emin olmak gerekir ki onu yapmışsın zaten.
ELinde bir skop olsa sorunu bulmak çok kolay elbette. Ama ibreli bir ölçü aletin var ise direk CCP1 çıkışına 2V kadamesine alarak voltaj ölçümü olarak bakabilirsin. Skop olsa direk bu bacağa bakıp kare dalga varmı görmen gerekirdi. Sİmulasyonda bu sinyal çıkıyor. Çalışıyor olması gerekirdi. Bazı garip tanımlamalar var programda. Bütün pinleri analog olarak seçiyor ama yalnızca PORTA.5 pinini giriş yapıyor. Bence TRISA registerine $20 yerine $FF vermesi gerekirdi.

Yapılabilecek diğer bir şey de aynı programı birde ben PBP ile yazıp sana hex dosyası vermem ve bu hex ile devreyi yeniden test etmen olabilir. Bunu gün içinde yapmaya çalışacağım.
Benim program çalışır ise senin programdan şüphe edeceğiz demektir. Program çalışmaz ise kurduğun devreden şüphe edeceğiz.

Bu arada açıklamandan iki ayrı güç kaynağı kullandığını söylemişsin. Bu iki güç kaynağının GND lerini bir yerde birleştirmen gerekir bunu yaptın umarım. Son olarak bunuda test et.
Ete

ete

Programı yazdım ve test ettim.
Motor hz kontrolünü simulasyonda daha iyi görebilmek için Motor üzerine tıklayın ve açılan pencerede 6 olan motor devir sayısını 200 yapın.

Şimdi yapman gereken dosya içindeki hx dosyasını işlemcine yüklemek ve aynı devrede durumu test etmek.

Sonucu bildir lütfen.

Ete

dgkn

sayın ete gönderdiğiniz hex dosyasını yazdırıyorum(write) pickit3 ile fakat doğrulama(verify) yapmak istediğimde programda ''verification of program memory failed at address 0x000000'' hatası alıyorum. elimde 2 adet 16f877a var ikisinde de aynı sorun ile karşılaştım.
ikisinde de hiçbir şey yoktu şuan çok şaşkınım. onlarca kod yükledim ve bugün bu yaşanıyor.

farklı bir kod denedim onda da aynı hatayı verdi

dgkn

silip read yaptığımda 3FFF olması gerekirken şuan 0000 görüyorum

dgkn

"configuration: 0ECF" nin altında kırmızı ile ALL PROTECT yazıyor bu daha öncesinde yoktu ilk kez karşılaşıyorum

dgkn

SORUNU ÇÖZDÜM BİRAZDAN KODU DENEYECEĞİM

alisumer

kod koruma aktif olduğunda pickit doğrulama yapamaz ama program genede yüklenir ve hata yoksa çalışır.pickit ten de bu ayarlar yapılabiliyor bi kontrol edin tools bölümünden
Hep meraktan

dgkn

sayın ete kodu yükledim ve çalıştırdım. bilin bakalım ne oldu. ÇALIŞTI. çok mutluyum inanılmaz hemde. acaba kodda neler yaptınız neler değişti nasıl oldu gerçekten çok meraklar içerisindeyim.

 ben kodu micro C ile yazıyorum. acaba bu hex dosyasındaki kodu bana micro C için yollayabilir misiniz ya da siz nereden yazdıysanız ben de oradan yazabilirim sorun değil.

bu koda lcd, sensör ile rpm okutup yazdırma, yük bindiğinde istenilen devire yükselme azalma gibi kodlar ekleyeceğim çünkü
@ete

ete

Demekki MicroC de yazılan kodlar çalışmıyor. Derleme doğru değil ve bana göre programda da bazı eksikler var.

Benim yazdığım program aşağı yukarı senin yazdıklarının karşılığı ama bazı farklar var.
Dosya için uzantısı PBP olan dosya basic dosyasıdır. Bu dosyayı text editör ile açabilirsin.
Senin kod'a göre benim yaptığım değişiklikler şunlar;
- ADC okumasını 10 bit yapıyorum. Bunun sebebi 1Khz olan PWM frekansının maksimum duty değerinin 1000 olmasıdır. Yani pot dan bir şekilde 0-1000 arası değer elde etmeliyimki bunu DUTY değeri olarak kullanabileyim. Pot adc karşılığı olarak en fazla 1023 verir. Bunu basit bir formül ile,
potdan okunacak 0-1023 aralığını 0-1000 değerine çevirdim ve bunu DUTY değeri olarak kullandım.
Senin programda bu kısımlar hiç belli değil.

İşin PWM kısmında ise senin programda rastgele bir şey yapılmış gibi gözüküyor.
1Khz lik bir PWM frekansının CCP1 pininden çıkartılabilmesi için;
PR2 registerine 249 değerinin verilmesi ve Timer2 bölme oranınında 1/4 yapılması gerekir.
Bu frekansta bir PWM sinyalinin Duty değeri ise maksimum 1000 olabilmektedir. Dolayısıyla bütün hesap ve program bu temeller üzerine oturtuldu.Bu arada senin programın başında yaptığın CCP1 aktivasyonunu ben DUTY_VER etiketi altında;
IF CCP1CON=0 THEN CCP1CON=%00001100  satırı ile yaptım. Sen baştan verebilirsin.

MikroC bilmediğimi söylemiştim. C dilini genel anlamda inceleyebilir biraz anlayabilirim ama kod yazamam.
 

Programın açık halini buraya koyuyorum incelemek isterseniz.

#CONFIG
 __CONFIG _CP_ALL & _WRT_256 & _CPD_ON & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
#ENDCONFIG

DEFINE OSC 4

DEFINE ADC_BITS 10     ' ADCIN resolution  (Bits)
DEFINE ADC_CLOCK 1     ' ADC clock source  (Fosc/8)
DEFINE ADC_SAMPLEUS 20 ' ADC sampling time (uSec)


DEFINE LCD_DREG PORTB 'LCD data port 
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4 
DEFINE LCD_RSREG PORTB 'LCD register select port 
DEFINE LCD_RSBIT 1 'LCD register select bit 
DEFINE LCD_EREG PORTB 'LCD enable port 
DEFINE LCD_EBIT 0 'LCD enable bit 
DEFINE LCD_RWREG PORTB 'LCD read/write port 
DEFINE LCD_RWBIT 2 'LCD read/write bit 
DEFINE LCD_BITS 4 'LCD bus size 4 or 8 
DEFINE LCD_LINES 2 'Number lines on LCD 
'DEFINE LCD_COMMANDUS 2000 'Command delay time in us 
'DEFINE LCD_DATAUS 50 'Data delay time in us  

CMCON=7
ADCON0=%01000000
ADCON1=%10000000
TRISA=%11111111 
TRISB=%00000000
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000

PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

HAM   VAR WORD 56
VOLT  VAR WORD 58
DUTY  VAR WORD 60
X     VAR WORD
ESKI  VAR WORD
YUZDE VAR BYTE

SYMBOL IN1=PORTC.3
SYMBOL IN2=PORTC.4


portb.2=0
lcdout $fe,1
pause 200
lcdout $FE,$80,"LUTFEN  BEKLEYIN"
LCDOUT $FE,$C0,"SISTEM  ACILIYOR" 
PAUSE 500

PR2=249
T2CON=%00000101 'İLK İKİ BİT %00=1/1  %01=1/4   %10=1/16
DUTY=0:GOSUB DUTY_VER
LCDOUT $FE,1
LCDOUT $FE,$C0,"SISTEM ACILDI" 
BASLA:
      
      GOSUB ADC_OKU            
      IN1=1:IN2=0
      IF ESKI=DUTY THEN BASLA
      GOSUB DUTY_VER:ESKI=DUTY
      LCDOUT $FE,$80,"VOLT=",DEC (VOLT/100),",",DEC2 VOLT//100,"  "
      LCDOUT $FE,$C0,"DUTY=",DEC DUTY,"  %=",DEC YUZDE,"  "
      GOTO BASLA



ADC_OKU:
        ADCIN 4,HAM
        DUTY=(HAM*/2503)/10
        VOLT=(HAM*/1252)/10
        YUZDE=DUTY/10
        
        RETURN
        
        
DUTY_VER:
        IF CCP1CON=0 THEN CCP1CON=%00001100
        X=DUTY
        CCP1CON.4=X.0
        CCP1CON.5=X.1
        CCPR1L=(X>>2)
        RETURN   


mehmet

O kodlar sanki CCS C kodları. MikroC değil.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Powered by EzPortal