Elektronik / Elektronik Kaynakları/

PICBasic Dersleri PIC Basic Pro ile PIC Programlama 12

Sponsorlu Bağlantılar

Bu dersimizde Servo motor kontrolünü inceleyecek ve bazı örnekler vererek konuyu anlamaya çalışacağız. Servo kelimesi daha ziyade pozisyon kontrolünün yapıldığı yada gerekli olduğu yerlerde kullanılan motorlar için motor aksamına ilave edilmiş muhtelif aksamları ifade etmektedir.

Muhtelif aksamlar kapsamına potansiyometre, encoder , switch yada manyetik switch ler gibi pozisyon bulmayı kolaylaştıran malzemeler girmektedir.

Genelde servo motorlar endüstriyel servo motorlar ve oyuncak yada modellerde kullanılan servo motorlar diye ikiye ayrılmaktadır. Öncelikle model uçak ve benzeri aletlerde kullanılan servoları inceleyecek daha sonra da diğer servolara göz atacağız.

Model servoları genelde belirli aralıklar motora yollanan puls lar ile çalışırlar. Pals genişliği motorun alacağı pozisyonu belirler.

Genellikle motora her 20 ms de bir puls gönderilmelidir. Bu , pek çok motor üreticisinin kullandığı puls sıklığı süresidir. Yine üreticiden üreticiye fark eden puls genişliği de motorun alacağı konumu belirler. Bir örnekle açıklamak en doğrusu olacak sanırım.

Elimizde bir servo motor olduğunu düşünün. Normalde motor miline bir disk taktığımızı ve üzerinede bir ok işareti yaptığımızı farz edelim. Okun yönü yatay olarak sağ tarafı gösteriyor olsun.

motor-mil-saga2 Bu şekilde motor mil yönü sağ yatayda.

Şimdi bu motora 1,50 ms süre ile bir HIGH palsi uygulayalım ve her 20 ms de bir bu sinyali tekrarlayalım. Motor hemen hareket alacak ve okun yönü 90 derece dik konuma gelecektir. motor-mil-dik-konum

Sinyalin tekrarlanması motor pozisyonunda bir değişiklik yapmayacaktır. Aynı motora bu seferde 1,25 ms lik bir puls uygular isek bu seferde motor mili -90 derecelik konuma gelecek ve okun yönü sol tarafı gösterecektir. motor-mil-sola

Yine motora bu seferde 1,75 ms lik bir puls uygular isek, Motor yeniden başlangıç konumuna gelecektir. motor-mil-saga2

Görüldüğü üzere verilen palsin süresi motor milinin konumunu değiştirmektedir. Şimdi bu işi Pic kullanarak yapmaya çalışalım.

Pic kullanarak bu işi yapmanın değişik yolları var tabiiki. Öncelikle en kolay olanı tatbik etmeye çalışacağız. Diyelimki 3adet servo motorumuz var ve bunları birer potansiyometre ile kontrol etmek istiyoruz.

Potansiyometrenin konumuna göre motorlarımızda konum değiştirecektir. Pot değeri okunacağı için ADC si olan bir pic kullanacağız. Bu da en popüler olanlardan bir tanesi olan 16F877 olsun. Önce programımızı verelim sonra açıklamasına geçelim

‘****************************************************************
‘*  Name    : SERVO_ORNEK.BAS                                      	*
‘*  Author  : ETE-EROLEC-ERO]                                   	*
‘*  Notice  : Copyright (c) 2007 [E.T.E]                        	*
‘*          : All Rights Reserved                               	*
‘*  Date    : 24.11.2007                                        	*
‘*  Version : 1.0                                               	*
‘*  Notes   :                                                   	*
‘*          :                                                   	*
‘****************************************************************
PORTA=0:TRISA=%00000111
PORTB=0:TRISB=%00000000
PORTC=0:TRISC=%00000000
PORTD=0:TRISD=%00000000
PORTE=0:TRISE=%00000000
ADCON1 = %00000010
‘—————————————————————–
@ DEVICE PIC16F877, WDT_OFF ‘Watch Dog timer kapalı
@ DEVICE PIC16F877, PWRT_ON ‘Power on timer açık
@ DEVICE PIC16F877, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE PIC16F877, BOD_ON
@ DEVICE PIC16F877, XT_OSC
‘—————————————————————–
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 4
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS	50

Define ADC_BITS 8
Define ADC_CLOCK 3
Define ADC_SAMPLEUS 50

HAMA var byte
HAMB VAR BYTE
HAMC VAR BYTE
SUREA VAR BYTE
SUREB VAR BYTE
SUREC VAR BYTE
SURE VAR WORD

pause 250

lcdout $FE,1,” SER1 SER2  SER3″

BASLA:

 lcdout $FE,$C2,dec3  SUREA,”  “,dec3 SUREB,”  “,dec3 SUREC

 PORTC = 0
pulsout PORTC.0,SUREA
pulsout PORTC.1, SUREB
pulsout PORTC.2, SUREC
SURE = (SUREA + SUREB + SUREC)*10
SURE = 12000 – SURE  ‘ASLINDA 20.000 DEN ÇIKARMAK GEREK AMA KOMUT  GECİKMELERİ NEDENİ İLE 12000 alıyoruz.

 pauseus SURE

 Adcin 0, HAMA  :SUREA=(HAMA+1)*/200
Adcin 1, HAMB :SUREB=(HAMB+1)*/200
Adcin 2, HAMC :SUREC=(HAMC+1)*/200
goto BASLA
end

Programın açıklamasına gelince; Öncelikle ADC okuma çözünürlüğünü 8 bit olarak ayarladığımız belirtelim bu şimdilik bizim için yeterli olacak.

Program BASLA satırından hemen sonra mevcut PULS sürelerini ekrana vermektedir. Kullandığımız motorlar, Protesu kütüphanesinde bulunan servo motorlar olup maksimum puls süreleri 2 ms olarak verilmiştir. Dolayısıyla program her 20 ms de bir pot ların pozisyonuna göre 0-2 ms (yada 0-2000us) arası pals verecek şekilde düzenlenmiştir.

Önemli komutları teker teker inceler isek; pulsout PORTC.0,SUREA komutu SUREA ile belirlenmiş süre kadar PORTC.0 dan puls çıkarır. Burada SUREA değişkeninde tutulan süre , 4 Mhz kristal kullanan devrede 10 us nin katları şeklinde dir. Yani SUREA=20 ise pul süresi 10×20=200 us olacaktır.

Üç çıkış için harcanan komut sürelerini toplayarak SURE isimli değişkende tutacağız. Bu toplanan değerler toplam puls süresinin 10′a bölünmüş hali olduğu için bu süreyi birde 10 ile çarpıyoruz.

Amacımız her 20.000 us de bir istenen pulsları çıkarmak olduğuna göre pulsout komutlarından sonra vermemiz gereken gecikme süresi 20.000-SURE şeklinde hesaplanması gerekir idi.

Ancak kullandığımız diğer komutların (ADC okumaları , Ekran gösterimleri ve pulsout komutlarının kendileri de biraz süre aldıklarından dolayı yaklaşık 8.000 us lik bir süre kaybı olmaktadır. Bu nedenle gerçek bekleme süresini 12.000-SURE eşitliği ile hesaplıyoruz.

Sonuçta PAUSEUS SURE komutu ile iki puls arasındaki gecikmeyi yaratıyor ve sonra ADC okumalarına geçiyoruz.

Sonuçta devreyi simule edersek karşımıza çıkan SKOP ekranında pulslar arasındaki mesafenin 20 ms olduğunu kolaylıkla görmek mümkün olabilmektedir.

ADC den okunan pot değerleri 0-255 arasında olacaktır. Bizim için gerekli olan maksimum puls süresi 2000 us olmasına rağmen Pulsout komutunda bu süreyi 2000/10 =200 olarak kullanmaktayız. Bu nedenle bize lazım olan değeri 200 kabul edeceğiz.

Böylece ADC ham değeri 255 olduğu zaman puls süresi değerimiz 200 , ADC değeri 0 çıktığı zamanda puls süresi değerimiz 0 çıkmalıdır. Bunu hesaplamanın yolu ise 200/256 eşitliğinden geçmektedir. Yani 200 birim için okunan değer (255+1) olacak olup bir birim okumanın karşılığı ise 0,78125 olacaktır. Sonuçta 32 bit çarpma yapacağımız ve sayının 256 ya bölünmüş halini bulacağımız için 0,78125 x 256 = 200 değeri bizim kullanacağımız değer olacaktır.

Böylece okunan ham değere 1 ekleyip bunu 200 ile çarpar ve 256 ya bölersek bize puls süresini verecektir. Bu işi ise */ komutu otomatik olarak yapmaktadır.

Böylece SUREA= (HamA+1)*/200 şeklindeki komut otomatik olarak pulsout komutunda kullanacağımız puls süresini bize verecektir.

lcd-servo-1

İkinci örneğimizi TMR0 kesmesi kullanarak yapacağız. Öncelikle her 20 ms de bir kesme oluşturmamız gerekecek. Bu örneğimizde önce tek servo motor sürmeye çalışacak ikiniciyi sisteme ilave edeceğiz. Böylece birden fazla servonun bu yöntemle nasıl sürüleceğini görmüş olacaksınız.

Önce biraz teorik bilgi. TMR0 kesmesini her 20 ms de bir kesme oluşturacak şekilde kurabilmemiz için gerekli parametreler neler onları bulalım.

4 Mhz lik osilatör frekansında her bir komut çevrimi 1us idi. Bize her 20.000 us de bir kesme lazım olduğuna göre bir kere bölücü kullanmamız gerekecek.

Kesme süremiz 20.000 us bunu 256 ya bölersek . 78 sayısını elde ederiz. Bu sayıcının sayması gereken süre olduğu için TMR0 değeri 256-78=178 olarak bulunur. Bu durumda toplam süre; 78 x 256=19968 + 7us (komut gecikmesi)=19975 olarak bulunur.

Şimdi de bölücü olarak 1/128 kullanacağımızı varsayalım ve hesap yapalım. 20000/128=156 toplam süre, 156 x 128 = 19968 + 7us = 19975 olarak aynı değeri buluruz. O halde TMR0 ‘a vereceğimiz ön değer , 256-156 = 100 olacaktır. Komut gecikmeleri nedeni ile TMR0 değeri 110 olarak alınacaktır.

Şimdi programımıza geçelim.


‘****************************************************************
‘*  Name    : SERVO_2.BAS                                      	*
‘*  Author  : ETE-EROLEC-ERO]                                   	*
‘*  Notice  : Copyright (c) 2007 [E.T.E]                        	*
‘*          : All Rights Reserved                               	*
‘*  Date    : 02.05.2009                                        	*
‘*  Version : 1.0                                               	*
‘*  Notes   :                                                   	*
‘*          :                                                   	*
‘****************************************************************
PORTA=0:portb=0
TRISB=%00000011   ‘PortB tamamı çıkış yapıldı.
TRISA=%00000000 ‘A portu tamamı çıkış yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘işlemci 16F628
@ DEVICE pic16F628, WDT_OFF ‘Watch Dog timer kapalı
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_off               ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT ‘Dahili osilatör kullanılacak
‘—————————————————————–
DEFINE LCD_DREG	PORTB	‘LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT		4	 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT		3 ‘LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	2		‘LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS		4 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2		‘LCD Kaç sıra yazabiliyor
‘————————————————————————-
ON INTERRUPT GoTo KESME ‘kesme  oluşursa KESME adlı etikete git.
OPTION_REG=%00000110  ‘Pull up dirençleri AÇIK- Bölme oranı 1/128.
INTCON=%00100000 ‘Kesmeler aktif ve TMR0 kesmesi aktif
TMR0=110
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giriş çıkış
‘—————————————————————————-
SUREA    VAR  WORD
I        VAR  WORD
SYMBOL ARTIR=PORTB.0
SYMBOL AZALT=PORTB.1
SYMBOL MOTORA=PORTA.0
‘—————————————————————————–
CLEAR ‘tüm değişkenler sıfırlandı
LCDOUT $FE,1
PAUSE 200
lcdout $FE,1,”  SER1        ”
INTCON.7=1
‘—————————————————————————–
BASLA:
lcdout $FE,$C2,dec4 SUREA,”         “

IF ARTIR=0 THEN
IF SUREA<2000 THEN SUREA=SUREA+10    GOSUB DELAY ENDIF IF AZALT=0  THEN    IF SUREA >10 THEN SUREA=SUREA-10
GOSUB DELAY
ENDIF
GOTO BASLA

DELAY:
FOR I=0 TO 2000
PAUSEUS 5
NEXT
RETURN
DISABLE
KESME: TMR0=110
MOTORA=1
PAUSEUS SUREA
MOTORA=0

 INTCON.2=0        ‘TMR0  Kesme bayrağı sıfırlanıyor
RESUME
ENABLE

END

Programın açıklaması olarak yalnızca Kesme kısmında neler yaptığımızı açıklayacağız. Kesme oluşur oluşmaz TMR0′a ön yükleme değerini veriyoruz o bir taraftan saymaya devam ediyor. Motora high sinyalini veriyoruz ve ayarlanan süre kadar bekleyip sinyali low a çevirip kesmeden çıkıyoruz. Sisteme başka servolar ilave edilebilir.

Kesme oluştuğu zaman bütün servolara High sinyali verilmeli ve süresi en kısa olan dan başlayarak puls süreleri verilmeli ve sonra sırası ile motorların sinyalleri Low a dönüştürülerek kesmeden çıkılmalıdır.

servo-kontrol-proje-2

Biraz da diğer servolara bakmakta yarar var.

ENCODER KONTROLLU SERVO

Endüstriyel servolarda motor miline bağlı encoder yada potansiyometre bulunmaktadır. Encoder li tiplerde referans noktası yada başlangıç noktasında encoder değeri sıfır alınarak sağa dönüş de encoder den gelen palslar sayılarak uygun değerde motorun durdurulması veya dönen motorda uygun pozisyon yakalandıktan sonra motorun durdurulması sağlanabilir. Aynı işlem tabiiki diğer yönde de yapılabilir.

Şimdi bu örneğimize ait programımızı verelim. Programla yapacağımız işlemde sağa dönüş butonuna her basışta motorun 50 puls lık bir dönüş yapıp durması sağlanacaktır. Aynı şekilde sola dönüş butonunada her basışta motorumuz bu sefer ters yöne 50 pulslık bir dönüş yapıp duracaktır.

İşte Programımız ve devre şeması.

‘****************************************************************
‘*  Name    : servo3.BAS                                      	*
‘*  Author  : [Erol Tahir Erdal]                                	*
‘*  Notice  : Copyright (c) 2005 [ETE]                          	*
‘*          : All Rights Reserved                               	*
‘*  Date    : 02.05.2009                                        	*
‘*  Version : 1.0                                               	*
‘*  Notes   :                                                   	*
‘*          :                                                   	*
‘****************************************************************
PORTA=0:portb=0
TRISB=%00000011   ‘PortB tamamı çıkış yapıldı.
TRISA=%00000011  ‘A portu tamamı çıkış yapıldı.
‘—————————————————————–
@ DEVICE pic16F628 ‘işlemci 16F628
@ DEVICE pic16F628, WDT_OFF ‘Watch Dog timer kapalı
@ DEVICE pic16F628, PWRT_ON             ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF  ‘Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_off               ‘MCLR pini kullanılıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT  ‘Dahili osilatör kullanılacak
‘—————————————————————–
DEFINE LCD_DREG	PORTB	‘LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT		4	 ‘LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	‘LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT		3 ‘LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	‘LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	2		‘LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS		4	 ‘LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2	 ‘LCD Kaç sıra yazabiliyor
‘————————————————————————-

OPTION_REG=%00000000 ‘Pull up dirençleri AÇIK-
CMCON=7 ‘16F628 de komparatör pinleri iptal hepsi giriş çıkış
‘—————————————————————————-
SAYI  VAR  WORD
NEW   var byte
OLD   VAR BYTE
YON   var  bit
SYMBOL ARTIR=PORTB.0
SYMBOL AZALT=PORTB.1

‘—————————————————————————–
CLEAR  ‘tüm değişkenler sıfırlandı
LCDOUT $FE,1
PAUSE 200

‘—————————————————————————–
BASLA:
gosub ekran
IF ARTIR=0 THEN SAG
IF AZALT=0 THEN SOL
GOTO BASLA

SAG:
SAYI=0:YON=1  ‘encoder bilgisi sıfırlandı
porta.2=1 ‘motor sağ a dönecek şekilde harekete geçti
GOSUB ENC
GOTO BASLA

SOL:
SAYI=0:YON=0
PORTA.3=1 ‘motor sola dönecek şekilde çalışmaya başladı
GOSUB ENC
GOTO BASLA

EKRAN:
IF YON=1 then
LCDOUT $fE,$02,”MOTOR YONU : SAG”
ELSE
LCDOUT $fE,$02,”MOTOR YONU : SOL”
endif
lcdout $FE,$C0,”PULS SAYISI:”,dec3 SAYI,” ”
return

ENC:
NEW=PORTA & %00000011 ‘ilk encoder bilgisini al
IF NEW=OLD THEN ENC ‘bir önceki ile kaşılaştır aynı ise yeniden al
GOSUB EKRAN  ‘aynı değil demekki encoder dönmüş
OLD=NEW                        ’son okunanı eskiye eşitle
SAYI=SAYI+1  ’sayı değerini bir artır.
IF SAYI=50 THEN  ‘50 değerini bulmuş ise
PORTA.2=0                    ‘hem sağ motoru hemde
PORTA.3=0 ’sol motoru durdur.
RETURN
endif
GOTO ENC
END

ENCODER-KONTROLLU-SERVO

Bu programda motorun dönüş yönü butonlar ile sağlandığı için encoder ile bir yön tayini yapılmamıştır. Gerekirse encoder ile de yön tayini kolaylıkla yapılabilir. Şema dan da görüleceği gibi encoder den gelen A ve B girişlerini kullandık. Bu iki giriş bir birinden yarım faz farkı olan iki sinyal üretirler.

encoder-servo-dalga

Yukarıdan aşağı doğru çizdiğimiz kesikli çizgiler encoderin okuma noktalarını gösteriyor. Bu noktalarda soldan sağa doğru gidişte (diyelimki motor sağ a dönüyor olsun) okunacak bilgi çiftleri şöyle olacaktır; 00 10 11 01 00

Bu seferde motor sağdan sola yani sola dönerken aynı bilgilere bir göz atalım. 00 01 11 10 00 şeklinde olacaklardır.

Yön tayini ilk okumanın (OLD) A. biti ile son okumanın (NEW) B biti nin XOR yapılması ile bulunur. Önce motor sağa dönerken duruma bakalım.

Old=00 ve NEW= 10 olacaktır. (Old.0) XOR (NEW.1)= bize 0 XOR 1 şeklinde bir eşitlik verecek ve sonucu 0 olacaktır.

Şimdi de motor sola dönerken olan duruma bakalım. OLD=00 , NEW=01 Old.0 XOR New.1=0 XOR 0 şeklinde bir eşitlik verecek ve sonucu 1 olacaktır. (0 XOR 0)=1 , (1 XOR 1)=1 (1 XOR 0)=0 (0 XOR 1)=0 dır.

Gördüğünüz gibi bir yönde dönüşlerde ilgili bitler XOR yapılırsa yön biti daima aynı değeri alıyor. Sola dönüşte 0 , sağa dönüşte ise 1 olmaktadır. Tabiiki dönüş yönüne göre bitleri biz tayin ettik bu geröekte terside olabilir. Yani sola dönüşte yön biti 0 sağa dönüşte yön biti ise 1 olabilir.

Bu programda ve verdiğimiz kısa bilgide bir encoder okuma konusundaki bilgiyide vermiş olduk. Bir şey daha ekleyebiliriz. Yön bilgisine bağlı olarak saydırma sisteminde;

Yon=0 ise SAYI=SAYI+1
Yon=1 ise SAYI=SAYI-1

eşitlikleri kullanılabileceği gibi yönün şekline göre terside kullanılabilir. Yani 0 iken eksiltir 1 iken artırablirsinizde. Tabiiki limitleri daima kontrol etmelisiniz. Word cinsinden tayin edilmiş bir SAYI değişkeni 65535 den sonra otomatik olarak sıfır değerini alacaktır. Sizinde bu değerden önce limitleriniz olmalı ve sayma esnasında bu limitlere bakmalısınız.

POT KONTROLLU SERVO:

Piyasada bulunabilecek bir başka Servo modeli de DC yada AC motor miline akuple edilmiş bir Potansiyometresi bulunan motorlardır. Genellikle Damper kontrolünde kullanılan bu tip motorlarda pozisyon genelde 90 deredir. Ancak 180 derecede olabilir. İşin temelinde o derece konumunda potansiyometrenin de sıfır konumunda bulunması ve motor döndükçe motor mili ile birlikte potansiyometreninde dönerek belli değerlere ulaşması sağlanmaktadır.

Kontrol mekanizmasında potansiyometre orta ucu bir ADC çeviriciye girilerek pot değeri digitize edilir ve istenen değerle karşılaştırılarak motorun akımı kesilir. Böylece motor istenen pozisyonlarda durdurulmuş olur.

Bu konuda da bir örnek yapacağız. Ancak bu tip motoru direk simule edemeyeceğimiz için sistemde pot ve motor ayrı ayrı gözükecektir. Aslında pot ve motor mili birlikte hareket ediyor olacaklardır.

İşin prensibini biraz daha açıklamakta yarar var. 0 derece konumunda motor sıfır derece de, pot verisi ise sıfır olacaktır. Bu durumda motoru 90 derecelik bir konuma getirdiğimizde POT da orta konuma gelecek ve veri değeri 512 olacaktır (10 bitlik ADC) . Burada bazı motorlarda potansiyometrenin bir dişli düzeneği ile döndürüldüğünü hatırlatmak isterim.

Motor mili 180 derece dönünce pot 270 derece dönerek son noktasına gelmektedir. Bu durumda elinizdeki motora göre hareket etmenizi önermekten başka söyleyecek bir şeyim olamaz. Biz motor mili ile pot’un birlikte hareket ettiklerini varsayacağız. Motor milini 512 pot verisi konumunda bıraktığımızı ve sistemi kapatıp yeniden açtığımızı farz edelim. Bu durumda hemen pot okunacak ve motorun konumu hakkında hemen bilgi alınacaktır. Bu durumda motora sıfır konumuna git şeklinde bir emir verirsek neler olacak ona bir bakalım.

0 konumu 512 konumundan küçük olduğu için motor ters tarafa dönmelidir. O halde motora geri dön emri verilecek ve pot değerinin sıfır değerine ulaştığı nokta gözlenerek motor durdurulacaktır.

Aynı şekilde 512 konumunda bekleyen motora 1023 konumuna (maksimum pozisyonu) git emri verilirse ne olur onada bir bakalım;

1024 konumu motorun bulunduğu 512 konumundan daha büyük olduğu için motor ileri dönecektir.

Motora ileri dön komutu verilecek ve 1024 pozisyonuna gelip gelmediği gözlenerek motor durdurulacaktır.

Yukarıda bahsini ettiğimiz sistemi simulasyonda 2 adet pot ile çalıştıracağız. Birinci pot Konumlandırma Pot’u olarak çalışacak ve motorun pozisyonu bu pot ile ayarlanacaktır.

Diğer pot ise Motor miline bağlı olan konum potu olacak ve motor mili ile birlikte dönecek olan pot dur. Simulsayonda bu potun motor mili ile birlikte döndüğü kabul edilecek ve manuel olarak ayarlanarak diğer pot ile aynı konuma getirildiğinde motorun durduğu gözlemlenecektir.

Esas olan iki potun da aynı konuma gelmiş olmalarıdır. Bu nedenle önce konumlandırma potu bir yere ayarlanmalı motor çalışmaya başladıktan sonra yavaş yavaş motor mili potu aynı yere getirilmelidir. Bu aşamda motorun durduğu gözlemlenmelidir.

Şimdi bahsini ettiğimiz sisteme ait örnek programımızı ve devre şemasını verelim.

‘****************************************************************
‘*  Name    : Servo_Pot.BAS                                      	*
‘*  Author  : [                   E.T.E.                      ] 	*
‘*  Notice  : Copyright (c) 2008  İzinsiz kullanılamaz )        	*
‘*          : All Rights Reserved                               	*
‘*  Date    : 02.05.2009                                        	*
‘*  Version : 1.0                                               	*
‘*  Notes   :                                                   	*
‘*          :                                                   	*
‘****************************************************************

@ DEVICE pic12F675 ‘işlemci 12F675
@ DEVICE pic12F675, WDT_ON              ‘Watch Dog timer açık
@ DEVICE pic12F675, PWRT_ON  ‘Power on timer açık
@ DEVICE pic12F675, PROTECT_OFF  ‘Kod Koruma kapalı
@ DEVICE pic12F675, MCLR_off            ‘MCLR pini kullanılMIYOR.
@ DEVICE pic12F675, INTRC_OSC_NOCLKOUT  ‘Dahili osilatör kullanılacak 

DEFINE OSCCAL_1K 1  ‘bu  komut mutlaka olacak OSCCAL değerini yeniden pice yazdırıyor

DEFINE OSC 4

DEFINE ADC_BITS 10 ‘  ADCIN resolution  (Bits)
DEFINE ADC_SAMPLEUS 10 ‘ ADC sampling time (uSec)

CMCON = 7
ANSEL = %00010011
ADCON0=%10000000
GPIO=0
TRISIO=%00000011
WPU=0

‘———————-değişkenler——————————-

HAMK    var word 60
HAMM    VAR WORD 62

SYMBOL MOTORSAG=GPIO.4
SYMBOL MOTORSOL=GPIO.5

GOSUB ADCAL
PAUSE 200

BASLA:

 gosub adcal
WHILE HAMK>HAMM
MOTORSAG=1
GOSUB ADCAL

 WEND

 WHILE HAMK
MOTORSOL=1
GOSUB ADCAL
WEND 

 IF HAMK=HAMM THEN gosub  fren

 GOTO BASLA

FREN:
motorsag=1
motorsol=1
PAUSE 500
MOTORSOL=0
MOTORSAG=0
RETURN 

ADCAL:
ADCIN 0,HAMM
ADCIN 1,HAMK
RETURN

POT-KONTROLLU-SERVO

Servo kontrol Sistemlerine Çizgi takibi yapan robot sistemlerini de dahil edeceğiz. Onlarda bir nevi servo kontrol yapmaktadırlar. Amaçları önceden çizilmiş olan bir çizgiyi takip etmektir. Sonuçta pozisyon emri çizgi tarafından veriliyor ve sistemde bu emri yerine getirmeye çalışmaktadır.

Çizgi kontrolüne geçmeden kullanılan elemanlar hakkında biraz bilgi vermek gerekiyor.

Bu sistemlerde genelde cisimden yansılmalı fotosel gurubu kullanılmaktadır. Bir Infrared verici ledi sinyal yayınlar, verilen bu sinyal karşıda bulunan herhangi bir cisimden yansır ve geri döner. Yansıyan bu sinyaller ise bir foto transistör yada diyot tarafından alınarak yorum yapılır.

Genelde CNY70 gibi hazır sensörler kullanıldığı gibi sensör gurubunu kendinizde oluşturabilirsiniz. Bu şekide daha hassas sensörler yapmak mümkün olabilir.

Aşağıda kendinizin oluşturabileceği bir sensör gurubu şeması verilmektedir. Bu devrede çizgi ile sensörler arasındaki mesafe 15 mm kadar çıkartılabilir.

sensor-devresi

Siyah çizgi ışığı absorbe eder ve yansıtmaz. Bu nedenle sensör siyah çizgiyi görünce LM358 (yada LM741LM324 de olabilir) sensör çıkışı LOW, Beyaz çizgiyi görünce HIGH olacaktır.

Siyah çizgide yeşil led yanacaktır. Bu sensörden en azından 3 adet yapılacak ve araçta , sağ ve sol’a birer tane yerleştirilecek ortada ise sürekli siyah çizgiyi takip eden bir üçüncü sensör daha bulunacaktır.

Şimdi 3 lü sisteme göre olası alternatifleri inceleyelim.

-Siyah Çizgi orta sensör tarafından görülmekte dıştaki iki sensör ise beyaz alanı görmektedirler. (Çıkışlar 1 0 1) Bu durumda aracın ileri düz gitmesi beklenir. Her iki motor da açık olmalı.

– Araç hafifçe sağa döndü sol sensör siyah çizgiyi görecek, sağ ve orta sensör beyazda kalacaktır. Çıkışlar (0 1 1) Aracın hemen sola dönüp sol sensörün siyah çizgiden kurtulup orta sensörün siyah çizgiyi bulması gerekir. O halde sol motor kapalı sağ motor açık olacaktır.

– Araç hafifçe sola döndü sağ sensör siyah çizgiyi görecek sol ve orta sensör sensör beyazda kalacaktır. Çıkışlar (1 1 0), Aracın hemen sağa dönüp sağ sensörün siyah çizgiden kurtulması ve orta sensörün yeniden siyah çizgiyi görmesi gerekir. O halde sağ motor kapalı, sol motor açık olacaktır.

Olası alternatifler bunlar olup aşağıdaki program içinde bu alternatifler değerlendirilerek sistem çalıştırılacaktır.

Normal olarak bu gibi sistemlerde motor hareketleri çift yönlü olmalıdır. Bu nedenle her bir motor bir H-Köprü devresi ile sürülmelidir. Araca daha fazla manevra kabiliyeti verebilmek için gerekirse sağ ve sol motorlar birlikte hareket ettirilmelidir.

Yeri gelmiş iken H köprü devreleri konusunuda biraz açıklayalım. Genelde bir motorun 4 transistörle sürülmesi ve motorun mekanik kontak kullanılmadan ileri geri fren ve devir kontrolü yapılarak hareket ettirilmesini sağlayan bir sistemdir.

Sabit devir kontrollü sistemlerde iki tane lojik sürme girişi bulunmaktadır. Bunalrdan birisi High yapıldığı zaman motor bir yöne (diğeri Low da olmalı) tersi yapıldığı zamanda motor diğer yöne dönmektedir. Devir kontrolü gerekir ise lojik high yapılan tarafa PWM sinyali uygulanmalıdır.

Bu işler için hazır entegreler de bulunmaktadır. Bunlara örnek vermek gerekir ise L293 ve L298 piyasada bolca bulunabilen ve üzerinde 2 ayrı motor için köprü devresi bulunan entegrelerdir. Devremizde L293 kullanacağız.

‘****************************************************************
‘*  Name    : ROBO01.BAS                                        *
‘*  Author  : [select VIEW...EDITOR OPTIONS]                    *
‘*  Notice  : Copyright (c) 2008 [select VIEW...EDITOR OPTIONS] *
‘*          : All Rights Reserved                               *
‘*  Date    : 02.05.2009                                        *
‘*  Version : 1.0                                               *
‘*  Notes   : Çizgi izleyen Robot Araba                         *
‘*          :                                                   *
‘****************************************************************
PORTA=0:TRISA=0
PORTB=0:TRISB=%00001111
CMCON=7
OPTION_REG.7=0  ‘PULLUP LARI BU KOMUT AÇIYOR GEREKİRSE SİLİP  KAPATABİLİRSİN. SENSÖRLER İÇİNDİR.
‘—————————————————————–
@ DEVICE pic16F628                      ‘işlemci 16F628
@ DEVICE pic16F628, WDT_ON ‘Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON ‘Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF ‘Kod Protek kapalı
@ DEVICE pic16F628, MCLR_off ‘MCLR pini kullanılMIYOR.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT  ‘Dahili osilatör kullanılacak
‘—————————————————————–
DEFINE OSC 4
‘————————————————————————-
GERI  VAR BIT

SYMBOL SOLSEN=PORTB.0       ‘SOL SENSOR
SYMBOL ORTSEN=PORTB.1  ‘ORTA SENSOR
SYMBOL SAGSEN=PORTB.2 ‘SAG SENSOR

SYMBOL SAI =PORTB.5 ‘SAĞ İleri
SYMBOL SAG =PORTB.4      ‘SAĞ Geri
SYMBOL SAE=PORTA.0 ‘SAĞ Enable
SYMBOL SOI=PORTB.6 ‘SOL İLERİ
SYMBOL SOG=PORTB.7      ‘SOL GERİ
SYMBOL SOE=PORTA.1 ‘SOL Enable

;***ILK  HAREKET********************************************************
DUZGIT:
WHILE ORTSEN=0            ‘orta sensör siyah çizgiyi görüyor ise
SAI=1:SAG=0:SAE=1      ‘Sağ motoru ileri çalıştır
SOI=1:SOG=0:SOE=1 ‘ Sol motoru ileri çalıştır
Wend ‘yani araç düz gitsin.

 WHILE SOLSEN=0  ‘Araç hafif sağa doğru dönmüş ise sol sensör siyah çizgiyi görür
SAI=0:SAG=1:SAE=1      ‘ bu durumda sağ motor geri dönecek
SOI=1:SOG=0:SOE=1  ‘ sol motor ileri dönecek böylece
WEND                                 ’siyah çizgiye doğru dönüş  hızlanacak

 WHILE SAGSEN=0            ‘Araç hafif sola doğru dönmüş ise sağ sensör siyah çzigiyi görür
SOI=0:SOG=1:SOE=1    ‘ Sol motor geri doğru dönecek
SAI=1:SAG=0:SAE=1    ‘ sağ motor ileri doğru dönecek, böylece
wend ‘ siyah çizgiye doğru dönüş  hızlanacak 

 IF SAGSEN=1 and  SOLSEN=1 and ORTSEN=1 THEN  ’sensörlerin tamamı siyah çizgiyi
SAI=0:SAG=0:SOI=0:SOG=0:SAE=0:SOE=0 ‘görmüyor ise tüm  motorları durdur
pause 1000 ‘ 1 sn bekle
WHILE SAGSEN=1 AND SOLSEN=1 and ORTSEN=1
SAI=0:SAG=1:SAE=1 ‘  Sağ motor geriye dönsün
SOI=0:SOG=1:SOE=1 ‘  Sol motor geriye dönsün
WEND  ‘araç geriye doğru  gidip siyah çizgiyi bulsun.
ENDIF 

 GOTO DUZGIT

cizgi-robotu

Hazırlayan: Erol Tahir Erdal (ETE) PICBasic Dersleri PIC Basic Pro ile PIC Programlama 12 Kod ve isis simülasyon dosyaları: PICBasic Dersleri PIC Basic Pro ile PIC Programlama 12

Dosya indirme LINK listesi (TXT formatında) link-10198.zip şifre-pass: 320volt.com

PICBasic Dersleri PIC Basic Pro ile PIC Programlama-13 Ders-13 Devam

  • Seyit Baba

    Abicim neden yorum yapılmamış anlayamadım. Süper anlatılmış. Tebrik ederim çok başarılı bir çalışma olmuş.

  • @Seyit Baba yorum sistemi bu sayfalara yeni eklendi yoksa ben dahil bir çok kişi ETE hocamıza duacı, minnetar sağolsun PIC programlama picbasic konusunda Türkiyede çok büyük katkıları var

  • emre kula

    Arkadaşlar güzel olanı örnek almak meziyettir. Ete hocama gönülden teşekkür ediyorum ve sitedeki tüm kardeşlerimi pic hakkında öğrendiklerimizi paylaşmaya tartışmaya davet ediyorum

  • feridun

    ETE hocamız sayesinde pic programlamayı öğrendim. Hiç bir şey bilmezken şmdi profesyonel devreler üzerinde çalışıyorum. Kendisinden ALLAH razı olsun.

  • mustafa

    Hocam eline sağlık çok eğitici oldu teşekkürler.

  • hasan yılmaz

    konuyu bilmesemde kafamda ufak ufak ışıklar çaktı teşekkür ederim..

  • Kemal Berki

    Hocam MErhabalar ,

    Öncelikler elinize, emeğinize sağlık, sayenizde gerçekten çok güzel bir kaynak olmuş burası.çok teşekkür ederiz.

    Benim bir sorum olacak.

    Potansiyometre ile ADC’den pozisyon bilgisini alırken gelen değerler sürekli -6,+6 gibi bir aralıkta değişiyor ve bu değişimden dolayı gelen bilgi bana tam poziyon bilgisini vermiyor.Yakın veriyor.Yukarıda sizde ADC nin veriminin çok iyi olmayacağından bahsetmişsiniz.

    Ancak şöylede bir gerçek var. Proteus similasyonunda program sıfır hata ile çalışıyor. Fiziki olarak devre üzerinde ise değerler saçmalıyor. Bu normalmidir. Yoksa devre üzerinde bir gürültü sinyalimi aramak lazım.
    teşekkürler…

    Kemal B.

  • ete

    Kemal,

    Analog bir bilginin digital bilgiye çevrilmesi işi sonuçta bir kondansatörün şarj edilip zaman tutulması ve boşaldığı anda zaman değerinin digital bilgi olarak verilmesi esasına dayanır. Ne kadar hassas zamanlama yapsanızda şaşmalar elbette oluyor maalesef.

    Genelde ölçüm zamanının uzun tutulması lçüm sonuçlarının doğruluğunu artırıyor. Ancak buda zaman zaman yetmiyor. Genelde iki ölçüm arasında arada birde olsa farklılıklar olabiliyor. Hele giriş değeri sürekli oynayanbilgilerde farklarda artabiliyor.

    Bu işin çözümü ortalama almaktan geçiyor. Benim sıklıkla uyguladığım çözüm ADC okumasını üst üste mümkünse 50 defa yapıp bütün okumaları toplamak ve sonuçta toplam değeri 50 ye bölerek ortalama bir değer bulmak şeklindedir. Bu yöntem epeyce stabilite sağlamaktadır.

    Ete
    http://etepic.com

  • veysel

    hocam 3potla 3 servo motoru kontrol ettiğiniz devreyi rf ile uzaktan kontrol etmeye çalışıyorum yanlız 20 mili saniyelik gecikmeyi ayarlıyamıyorum alıcı verici arasındaki uzaklık değiştikçe bekleme süresininde değişmesi gerekiyor çünkü haberleşme hızı değişiyor nasıl bir mantık izlemem gerekli? teşekkürler

  • ete

    Veren devre yalnızca hangi motorun ne kadarlık pals alacağının bilgisini yollar ise alıcı devrede bunu uygulayabilir. Dolayısıyla bir sorun olmaz diye düşünüyorum.
    Bilginin yollanma hızı veya iki ünite arasındaki mesafe burada etki bir rol oynamaz diye düşünüyorum. Kesin oynamaz. AKıllıca bir mantık kurmanız gerek.
    3 adet motor var ise 3 ayrı bilgi yollamanız yeterli.
    Ancak unutmayın verilen puls lar us cinsinden olmalıdır. Yoksa süreyi 1,5ms nasıl vereceksiniz?. AMa bunu 1500us şeklinde vermeniz gayet kolay bence. Bu nedenle 6 adet bilgi yollamanız gerekecek. Sırası ile,
    Birinci motor puls süresi (word cinsinen bir değişken ile önce Lowbyte sonra High byte verilmeli Mesela SureA.Byte0, SureA.Byte1 şeklinde) Daha sonra ikinci motor puls süresi ve son olarak da üçüncü motor puls süresini 6 adet byte şeklinde yollarsanız motorda bunu uygular ve sorun çıkmaz. Yeni bilgi gelinceye kadar eskisini uygular.

    Ete

  • veysel

    Hocam bende sizin programlardan yola çıkarak söylediğinize benzer bir program yazdım üç puls süresini farklı ön kontrol bitiyle gönderip alıcıda farklı kaydedicilerde yerleştrip tek bir wordde toplayıp işleme devam ettim verici programın ana kısmı şu
    basla:
    GOSUB GONDER
    Adcin 0, HAMA :SUREA=(HAMA+1)*/200
    Adcin 1, HAMB :SUREB=(HAMB+1)*/200
    Adcin 2, HAMC :SUREC=(HAMC+1)*/200
    goto BASLA
    GONDER:
    SEROUT2 CIKIS,396,[“E”,”T”,”E”,”A”,SUREA]
    SEROUT2 CIKIS,396,[“E”,”T”,”E”,”B”,SUREB]
    SEROUT2 CIKIS,396,[“E”,”T”,”E”,”C”,SUREC]
    return
    alıcıda bu
    BASLA:
    SerIn2 GIRIS,396,[WAIT (“ETEA”),surea]
    SerIn2 GIRIS,396,[WAIT (“ETEB”),SUREB]
    SerIn2 GIRIS,396,[WAIT (“ETEC”),SUREC]
    pulsout KAMERA, SUREA
    PULSOUT ELYON, SUREB
    PULSOUT ELKAPA, SUREC
    SURE = (SUREA + SUREB + SUREC)*10
    SURE = 12000 – SURE

    pauseus SURE
    GOTO BASLA
    END
    uygulamada verici alıcıya yakınken çelışmıyor uzakken potun ilk ve son hareketini bi anda yapıyor ara değerler yok gibi bazende iki servo tek potla hareket ediyor..

  • ete

    Gönder kısmını şöyle yap;
    GONDER:
    SEROUT2 CIKIS,396,[“E”,”T”,”E”,SUREA,SUREB,SUREC]
    RETURN

    Tabiiki alacak olan da bu formata uygun şekilde alması gerekir.
    Dolayısıyla Alıcı daki ALma kısmıda aşağıdaki şekilde olmalı.
    SERIN2 GIRIS,396,[WAIT (“ETE”),SUREA,SUREB,SUREC]

    Ancak bir konuya dikkatini çekmek isterim. Seri haberleşmede yollanan bilgi 8 bitlik olmak zorundadır. Şayet SUREA gibi bir değişken WORD tipinde ise ve taşıdığı değer 255 den büyük ise onu gönderme ve alma komutunda 16 bitlik kullanmazsın. SURE değişkenleri Word tipinden ise alma ve verme komutları şöyle olmalı;
    SEROUT2 CIKIS,396,[“E”,”T”,”E”,SUREA.Byte0,SUREA.Byte1,SUREB.Byte0,SUREB.Byte1,SUREC.Byte0,SUREC.Byte1]

    Alma komutuda benzer şekilde her bir değişkenin low byte’ıile high byteları ayrı ayrı yazılarak yollanmalı ve aynı sıra ile alınmalıdır.
    Senin sorunun muhtemelen yolladığın bilginin yalnızca low byte larının yollanmasından kaynaklanıyordur.

    Ete

  • veysel

    Hocam çok teşekkür ederim dediğiniz gibi yaptım sorun çözüldü 8 bitlik adc olduğundan byte cinsinden değişkenlerdi yanlız şimdi tuhaf bir sorun var bu yazılımsal değil sanırım donanımda ben alıcı kısımda 3 servo haric iki tanede şu basit çin motoru denilen sarı motorlardan sürüyorum L293d ile 16f877nin b portuna bağlı tek tek lojik 1 verip kontrol ettim sorunsuz çalışıyor

    sizin bilgiden yola çıkarak şöyle bir değişiklik yaptım SERIN2 GIRIS,396,[WAIT(“ETE”),SUREA,SUREB,SUREC,PORTB]tabi verici kısımda aynı şekilde ve sonra volt metreylealıcının portlarını kontrol ettim tam vericide tuşa basılıp brakıldığı anda alıcıda gerekli sinyal l293dye gönderiliyor sıkıntı şu sistem boştayken düzgün çalışıyor motoru bağlayınca tusu braksanda lojik seviye yaklaşık 5 ile 10 saniye arasında 1 olarak kalıyor yani tusu braksamda bir müddet motor çalışıyor neden acaba sistem boşta düzgün çalışıyor motor çalışırken beslemeyi ölçtüm 5vden 4.9 a düşüyor bariz bir değişiklik yok zıt emk danmı acaba yoksa fazla akım çekiyorda frekans hızımı düşüyorda pic yavaş işlem yapıyor o sürede motor çalışmaya devam ediyor valla çok soru sordum ama basit görünüp uğraştıran sorunlar.

  • ete

    Veysel,
    Bahsini ettiğin sorunu anlayamadım. Boşta çalışan şey doluda da çalışması gerekir. Şema ve programın o kısmını görmeden bir şey söylemem mümkün değil maalesef.

    Ete

  • Kemal

    Veysel Selamlar ,
    Benzer bir problemi ben de yaşamıştım , DC motoru çalıştırdığım zaman devre doğru çalışmıyordu , Motorları beslediğim güç kaynağını, devreyi beselyen güç kaynağından ayırınca problem çözülmüştü. Yani ayrı birgüç kaynağı denemen belki problemi çözebilir.

  • Fatih

    Hocam öncelikle verdiğiniz dersler için teşekkürler, ben devre tasarımı ile yeni ilgilenmeye başladım; bunun sebebi de Parallax firmasının Kinect sensörünü kullanarak yaptığı bir mobil robot platform olan Eddie. Kendim evde bunun bir benzerini yapmaya çalışıyorum ama elektronik devreler hakkında çok bilgim yok. 2 tane servo motor kontrolü sağlayan ve kinectle birlikte toplam 6 sensörü kontrol eden bir elektronik devrenin yaklaşık olarak maliyeti ne kadar olur? Eğer maliyet çok olucaksa firmadan kontrol kartını satın almak zorunda kalacağım için projemi gerçekleştiremeyeceğim. Bana bu konuda bilgi verebilir misiniz?

  • et

    Bu sorunun cevabını sağlıklı bir şekilde veremem. Sebepleri şunlar;
    – Kinect sensörü nedir bilmiyorum hiç duymadım. Bildiğim bir sensördür ama ticari adı ile söylemişsin ne olduğunu bilemiyorum. Bilmediğim bir şeyin kontrolünü sağlayacak devreyide bilemem doğal olarak.

    -O kadar fazla servo motor varki piyasada güçlerine göre sürme şekilleri veya çalışma şekillerine göre sürülme şekilleri değişir. Bu nedenle motor cinsi belli olmadığı için onu sürecek devre içinde bir şey söyleyemem.

    – Toplam 6 sensör biri kinect olduğuna göre geri kalan 5 sensör nedir. ? Onlarda belli değil.
    Analayacağın çok bilinmeyenli denklem gibi bir soru. BU nedenle cevabı vermem çok zor. Kendin bulmaya çalış cevabını.

    Ete

  • MUHAMMET

    iyi çalışmalar bu xor komutu ile enkoder palslerini düzenlemenizde bir hata olmalı çünkü enkoder palslerini direk bir xor entegresine verdiğimde çıkış hep aynı oluyor. açıklamalarınızda eksik birşey olmalı teşekkürler