herkese iyi çalışmalar;
pic16f877A ile bir servo motor sürme devresi kurdum. devrenin çalışması şu şekilde;
potansiyometre ile analog giriş alıyorum bu girişin değişimine göre servo motorun konumu değişiyor. 0V da -90 derecede 5V da +90 derecede duruyor.
proteusta devreyi oluşturdum CCS C de de kodları yazdım gayet istediğim gibi çalışıyor, fakat gerçekte kurdum aynı kodları yükledim istediğim gibi çalışmadı, tek bir pulse değeri görünüyor potansiyometrenin değişimine cevap vermiyor. sorun ne olabilir kodlarda yada donanımda eksik olan ne olabilir. devre ve kodlar aşağıda bulunmaktadır. yardımcı olabilicek arkadaşlara şimdiden teşekkür ederim ...
devre;
[IMG]http://i1012.hizliresim.com/2010/12/15/3365.jpg[/img]
kodlar;
#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#use fast_io(a)
#use fast_io(c)
#define use_portb_lcd TRUE
#include <lcd.c>
#byte ADRESH = 0x1E
#byte ADRESL = 0x9E
#byte ADCON0 = 0x1F
#byte ADCON1 = 0x9F
unsigned long int digdata;
int pwm=0;
int duty=0;
#int_timer0
void kesme()
{
set_timer0(227);
if (pwm==0) output_high(pin_c3);
if (pwm>=duty) output_low(pin_c3);
pwm++;
output_high(pin_c2);
if (pwm>=140) pwm=0;
}
#int_AD
void ADC_kesme()
{
output_high(pin_c1);
}
//****MAIN PROGRAM******
void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
set_tris_a(0b11111111);
set_tris_c(0b00000000);
ADCON0=0b00001101;
ADCON1=0b00000000;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(ALL_ANALOG);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4);
set_timer0(227);
enable_interrupts(int_timer0);
enable_interrupts(int_AD);
enable_interrupts(global);
output_c(0b00000000);
lcd_init();
while(1)
{
set_adc_channel(1);
delay_us(20);
digdata=read_adc();
if ((digdata>=0) && (digdata<=93)) duty=5;
if ((digdata>=94) && (digdata<=187)) duty=6;
if ((digdata>=188) && (digdata<=281)) duty=7;
if ((digdata>=282) && (digdata<=375)) duty=8;
if ((digdata>=376) && (digdata<=469)) duty=9;
if ((digdata>=470) && (digdata<=563)) duty=10;
if ((digdata>=564) && (digdata<=657)) duty=11;
if ((digdata>=658) && (digdata<=752)) duty=12;
if ((digdata>=753) && (digdata<=846)) duty=13;
if ((digdata>=847) && (digdata<=940)) duty=14;
if ((digdata>=941) && (digdata<=1023)) duty=15;
printf(lcd_putc,"\fDigData=%lu",digdata);
delay_ms(50);
}
}
Tam inceleyemedim ama gözüme çarpan:
setup_adc(ADC_CLOCK_INTERNAL); yerine
setup_adc(ADC_CLOCK_DIV_8); // Bu 16F877'e göre, 16F877A'nın kataloğunu indirmedim "Selecting the A/D Conversion Clock" bölümünü kontrol edersiniz.
Bir de ya doğrudan ADCONX kullanın ya da setup_adc_.... fonksiyonlarını.
setup_adc(ADC_CLOCK_INTERNAL);
JKramer, merak ettim, bu satırın nasıl bir sakıncası var ki? Belki dönüşüm işleminin mümkün olandan biraz daha yavaş yapılmasına sebep olabilir ama başka bir etkisi olmaz diye düşünüyorum.
Simulasyon çalıştığına göre sorunu donanımda aramak lazım. Fiziksel olarak kurduğun devrenin şemasını, fotoğrafını falan eklersen yorum yapılabilir belki.
devru budur;
devredeki ledlerden sağdaki timer kesmesi gerçekleştiğinde soldakide adc çevirimi yapıldığında yanıyor. yani kesme ve adc çevirim oluşuyor fakat direnci değiştirdiğimde üretilen pwm de bi değişme olmuyor ...
(http://i1012.hizliresim.com/2010/12/16/538.jpg)
877A olarak belirtmişsin simulasyonda 877 gözüküyor analog ve komparator olarak bu iki entegre
arasında minik farklar var bu yüzden olabilir.....nasıl derledinse öyle olsun
birde isiste hata mesajı alıyormusun yani renk yeşilmi yoksa sarımı burada komparator uyarısı alıyormusun.????
Timer kesmen kaç ms lik?
lcd de yazdırdıgın değerler pot la oynayınca güncelleniyor mu?
bu sorulara cevap verebilirsen daha rahat yardımcı olabiliriz...
RC servolar için frekansın 50Hz peryod 20ms olamalı.(proteus gözardı ediyor) -90 için 0,5ms duty,+90 için 2,5ms duty gerekli. merkez için 1,5ms.
(http://www.uerkal.com/Posts/Res/p30PWM.jpg)
Alıntı yapılan: ipek - 16 Aralık 2010, 04:13:57
877A olarak belirtmişsin simulasyonda 877 gözüküyor analog ve komparator olarak bu iki entegre
arasında minik farklar var bu yüzden olabilir.....nasıl derledinse öyle olsun
birde isiste hata mesajı alıyormusun yani renk yeşilmi yoksa sarımı burada komparator uyarısı alıyormusun.????
evet isisdeki 877 ama derlerken 877A ya göre derliyorum simulasyonu çalıştırdığımda hta mesajı almıyorum bütün mesajlar yeşil
Alıntı yapılan: Everlast - 16 Aralık 2010, 08:59:51
Timer kesmen kaç ms lik?
lcd de yazdırdıgın değerler pot la oynayınca güncelleniyor mu?
bu sorulara cevap verebilirsen daha rahat yardımcı olabiliriz...
evet analog girişlerin dijital değerlerine göre (0 ile 1023 değerleri arasında) 11 tane duty değeri tanımladım yani motoru potu değiştirerek 11 farklı açıya getirebiliyorum simulasyonda bunu net bir şekilde yapıyorum
Alıntı yapılan: muhittin_kaplan - 16 Aralık 2010, 09:26:41
RC servolar için frekansın 50Hz peryod 20ms olamalı.(proteus gözardı ediyor) -90 için 0,5ms duty,+90 için 2,5ms duty gerekli. merkez için 1,5ms.
(http://www.uerkal.com/Posts/Res/p30PWM.jpg)
evet ürttiğim pwm değerleri bu şelikde isis da bunlar net bi şekilde görülüyor fakat gerçek devrede gördüğüm tek bir pwm değeri var o da şu ;
(http://i1012.hizliresim.com/2010/12/16/2281.jpg)
logic 1 seviyesini pot u değiştirerek değiştirmek istiyorum fakat değişmiyor.
PIC16 serisi mcu ları bilmem ama gördüğüm kadarı ile ;
kristal vs. hız gibi değerlere göre doğru yazıldı ise main deki sonsuz döngüde ki delay_ms(50); den dolayı max 20Hz liK bir PWM frekansı üretiliyor. Servonun doğru çalışması için en az 50Hz gerekir.
delay_ms(50); satırı delay_ms(20); olmalı.
PWM duty si %4-5 ile %10-12 civarında olmalı. Duty değişkenine atanan 5 ile 15 arasındaki değerler değişkenin kesme içerisindeki kullanım şekline göre yüzde olarak duty ifade ediyor. Bu durumda set_timer0(227); satırının dutynin max değeri de gözönüne alınınca 143 us ye karşılık geldiğinden emin olunmalı.
Diğer yol da bu kadar uğraşmayıp CCP modülünü kullanmak. Timerı 20ms ye ayarlayıp, timer değeri = 20 ms hesabından ADC max değerini 2 ms olacak şekilde bir çarpan/bölen hesaplayıp ADC den okunan değerleri bu değer ile çarpıp/bölüp CCP modülünde kullanmak yeterli.
Edit
logic 1 seviyesi değişmeyecek, logic 1 'in genişliği-süresi değişecek. İki logic bir'in yükselen kenarları arasında 20ms olacak, darbe genişlikleri 1-2 ms olacak.
Alıntı yapılan: puremonday - 16 Aralık 2010, 14:10:27
Alıntı yapılan: Everlast - 16 Aralık 2010, 08:59:51
Timer kesmen kaç ms lik?
lcd de yazdırdıgın değerler pot la oynayınca güncelleniyor mu?
bu sorulara cevap verebilirsen daha rahat yardımcı olabiliriz...
evet analog girişlerin dijital değerlerine göre (0 ile 1023 değerleri arasında) 11 tane duty değeri tanımladım yani motoru potu değiştirerek 11 farklı açıya getirebiliyorum simulasyonda bunu net bir şekilde yapıyorum
ISIS seni yanıltır neden ISI i baz alıyorsun demek istediğim pratik devrende pot değişince lcd ye değer yazdırıyorsun pot değeri değişin ce LCD de neler görüyorsun?
ADC den okudugun değeri art arda 10 kere okuyup bu 10 değerin ortalamasını alırsan daha kesin bir değer görebilirsin potu çevirirken oluşabilcek gerilim dalgalanmalarına karşı daha düzgün sonuç alırsın.
Skoptaki görüntüden 20 ms lik peryot tutuyor gibi.
delay_ms(50); yerine for( i = 0; i < 10000; i++){ for( j = 0; j < 10000; j++) } gibi bir döngü koyar mısın CCS delay fonksiyonlarında diğer interruptları görmüyor. bunları dikkate alıp denemisin?
arkdaslar merhaba ben servo motoru inverter olmadan 1'er derecelik açılarla nasıl çevirebilirim bilenimiz varsa lütfen yardımcı olsun.
teşekkürler:)
Merhaba
acaba servo motorlar şu şekilde mi çalışıyor
servoya mesela 40 derecelik açı için 1ms lik bi değer gönderdik 40 dereceye geldi ee sonra bu sinyali tekrar tekrar göndermemiz gerekiyor mu yoksa açıyı değiştirmek istediğimzde mi tekrar sinyal göndermemiz gerekiyor
arkadaşlar devre şemeasını göremiyorum yardımcı olabilmek isterim ama göremşyorum pic devresini
Arkadaşlar birşey sormak istiyorum. Pic ile servo sürüyorum gayet güzel fakat bir müddet sonra pic entegre aşırı ısınıyor neden kaynaklanıyor acaba bir fikri olan varmı
Pic ile servo sürerken yanlış yapmışsınız. Bu yüzden ısınıyor.
Bir yalnışlık var evet bende onu çözmeye çalışıyorum. Bir müddet normal çalışıyor ama sonrasında pic ısınıyor ve çalışmayı kesiyor
Peki biz bu yaptığınız yanlışlığı nasıl anlayacağız da size bildireceğiz?
Biraz ipucu verseniz?