USB'den gelen DATA'yi hangi kesme ile algilayabilirim?

Başlatan Digimensch, 10 Ocak 2011, 20:03:36

Digimensch

Arkadaslar USB _HID üzeri bir cihazla calisiyorum.
Baglanti veri alip verme konularinda sorunm yok onlari hallediyorum.
Bir konuda takildim.
Ben Programimda USB den veri geldiginde kesme devreye sokarak islemler yapmak istiyorum.Bilindigi gibi USB destekli PIC18F4550 picinin
RC4 / D+  ve RC5 / D-  pinleri ile USB baglantisi kuruluyor.
Ben bu uclardan gelen Datayi algilayan bir kesme yapam istiyorum hangi kesmeyi uygulamam mantikli olur?
Örnegin Serial Portan gelen veriyi algiliyan #int_rda  kesmesi var ama USB icin böyle birsey yok.
Bana USB 'den gelen DATA 'yi algilayacak  Kesme konuusunda ne öneririsiniz?

t2

18 F serisinde

Galiba böyle bir kesme yok. Müsait zaman data gelmiş mi diye bakıyorsun gelmişse okuyorsun gelmediyse boş bir dizi oluyor. Okuma periyodu her interval için 1 defa olması yeterli. daha fazla okusan da anlamı olmaz. ama 2 kere okusak daha iyi olur gibi. interval 2ms ise  1msaralıklar ile bakmamız iyi olur. 


Alıntı yapılan: protonNotes for 18F devices
The method used for USB on the 18F devices is a polled method, meaning that no interrupt is
working in the background. However, this does mean that either a USBpoll, USBin, or USBout
command needs to be executed approximately every ...ms or the USB interface connection will
be lost.

Digimensch

Aslinda While();
döngüsüyle devamli kontrol edebilirim ama , while döngüsünü o anda bsaka bir islemde kullanacagim icin , bir kesme islemi uygulayamazmiyim?

t2

USB ile alakalı bazı kesmeler var fakat veri geldiğini anlamak için bir kesme olduğunu bilmiyorum duymadım (belki vardır)

Digimensch

#4
Iste sorun orda USB ile ilgili kesme yok.
CCS de 14 kesme varmis.
1-RB0 harici kesme
2-RB2-RB7 pinlerindeki degisiklik kesmesi
3-Timer0
4-Timer1
5-Timer2
6-A/D
7-CCP1 Modülü kesmesi
8-CCP2 Modülü kesmesi
9-Parelel Porttan veri Gelme kesmesi
10-Seri Porttan veri geldiginde olusan kesme
11-SPI veya I2C iletisimi sirasinda veri gelme kesmesi
12-EEPROM veri yazma islemi sonlandiginda olusan kesme
13-RS232 seri iletisimde gönderillecek veri tamponu bos oldugunda meydana gelen kesme
14-Bus Collision kesmesi
Benim isime yarayan yok , acaba nasil bir yöntem ile USB den veri geldiginde bu veriye göre islemler yaptirabilirim.
While() döngüsü olmadan ... Cünkü baska islemler icin main funksiyonunda kullaniyorum...

Digimensch

#5
Arkadaslar hic yoktan bana bir Servoyu nasil adim adim 0°-180° arasi döndürebilirim bunu yazin.
Su kodlarla bir servoyu saga - sola - ortaya ceviriyorum.
void sagadon()
{
      for(x=0;x<25;x++)
      {
      high;
      delay_us(500);       // servoya 0,5 ms'lik sinyal gönderiliyor
      low;
      delay_us(20000-500);
      }
}
void ortayagel()
{
      for(y=0;y<25;y++)
      {
      high;
      delay_us(1500);    // servoya 1,5ms'lik sinyal gönderiliyor
      low;
      delay_us(20000-1500);
      }
}

void soladon()
{
      for(z=0;z<25;z++)
      {
      high;
      delay_us(2500);      // servoya 2,5 ms'lik sinyal gönderiliyor
      low;
      delay_us(20000-2500);
      }
}

Ama ben birden saga - sola ve ortaya değilde ,servoyu derece derece nasil 0°- 180°   ve tekrar 180°- 0° arasi cevirebilirim.Servoya Komutlar USB den gelecek.
USB'den nasil veri göndermeliyim?
Servo nasil adim adim yukarda bahsettigim sekilde dönsün?
Hic yoktan bu kounda yardimci olun !!!
Simdiden tesekkürler

ErsinErce


Digimensch

Dostum sağolda ben kesme kullanmaktan vaz gectim...
Yukardaki sorumu  yeniliyorum.
Servoyu adim adim nasil döndürebilirim? (0°-180°) arasi ??
Su kodu yaptigimda 45 derce birden dönüyor
for(int x=0;x<25;x++)
{
output_high(PIN_A0);
delay_us(500);
output_low(PIN_A0);
delay_us(20000-500);
}



Bu kodda  20 ms 'lik süreyi düsürsem olurmu? su sekilde
for(int x=0;x<25;x++)
{
output_high(PIN_A0);
delay_us(500);
output_low(PIN_A0);
delay_us(1000-500);
}


ErsinErce

for(int x=0;x<25;x++)
{
output_high(PIN_A0);
delay_us(750);
output_low(PIN_A0);
delay_us(20000-750);
}


basit bir doğru orantı hesabı yapalım bakalım uyacak mı;
0.5 ms sinyal verince solda
1.5 ms sinyal verince ortada
2.5 ms sinyal verince sağda
konum alan devreye 0.75ms sinyal verirsek hangi konumu alır?
yukarıdaki kodu deneyip görelim ;)

Digimensch

#9
500 degerini 750 cikartmakla pek fark eden birsey olmadi.
O degeri 1500 yaptim dönüs acisi daraldi ama servonun dönüs siddetinde degisme oluyor.
yani sanki zorlaniyormus gibi...

Oysa ben nette high süresini arttirmak değilde,  20 ms'lik low süresinin kisaltilmasinin dönüs acisini kisaltacagini buldum.
yani söyle
for(int x=0;x<25;x++)
{output_high(PIN_A0);
delay_us(500);
output_low(PIN_A0);
delay_us(20000-500); ---> Bu satirdaki 20000 , örnegin 10000 yapildiginda
}


iyildirim

#10
Servo dan servoya biraz farklılıklar olsa da standart servo sinyali 50Hz ve darbe süreleri min 1ms, max 2 ms dir. 1ms'den  kısa veya 2ms'den uzun darbe sürelerinde ki davranış yine 1 ms veya 2ms deki davranışına eşit olacaktır. Limit dışındaki darbe sürelerinde servo zorlanabilir, fazla akım çekebilir, zarar görebilir.



Kodunu şu şekilde değiştirip deneyebilirsin.
for(int uSec=1000;uSec<2000;uSec++)
{output_high(PIN_A0);
delay_us(uSec);
output_low(PIN_A0);
delay_us(20000-uSec); ---> Toplam  süreden HIGH süresini çıkarıp LOW süresinin buluyoruz. Toplam süre yani döngünün tamamı 20000 mikrosaniye olmalı. 
}

Digimensch

Yani senin bu verdigin koda göre
for(int  uSec=1000;uSec<2000;uSec++)
{
output_high(PIN_A0);
delay_us(uSec);
output_low(PIN_A0);
delay_us(20000-uSec); ---> Toplam  süreden HIGH süresini çıkarıp LOW süresinin buluyoruz. Toplam süre yani döngünün tamamı 20000 mikrosaniye olmalı. }


uSec ilk etapda 1000 demissin ve 2000'e kadar döngü calisacak yani 1000 defa bu cok uzun degilmi??

iyildirim

Kod servoyu yavaşça çevirmen için örnek.
Kodun amacı, servonun hangi aralıkta çalışacağını görmek için. Burada asıl anlaşılması gereken servo sinyalinin nasıl olması gerektiği. Örnek kodun amacı da, bir önceki mesajında duty değil toplam döngü süresi ile oynamak anlamındaki yazıdan dolayı.
Alıntı yapılan: Digimensch - 11 Ocak 2011, 04:36:14
500 degerini 750 cikartmakla pek fark eden birsey olmadi.
O degeri 1500 yaptim dönüs acisi daraldi ama servonun dönüs siddetinde degisme oluyor.
yani sanki zorlaniyormus gibi...

Oysa ben nette high süresini arttirmak değilde,  20 ms'lik low süresinin kisaltilmasinin dönüs acisini kisaltacagini buldum.
yani söyle
for(int x=0;x<25;x++)
{output_high(PIN_A0);
delay_us(500);
output_low(PIN_A0);
delay_us(20000-500); ---> Bu satirdaki 20000 , örnegin 10000 yapildiginda
}


Gerçi tamamen analog çalışan bir servo da duty yerine frekans'ı arttırmak ( sabit ON süreli bir PWM sinyalinde frekansı arttırmak) ortalama voltajı arttıracaktır. Ancak 50hz'lik bir servoyu 50hz lik bir sinyal ile sürmek daha doğru olur.

Deneme yaparken servonun bir bir uctan bir uca 20 saniye de gitmesi sorun olur diyorsan
for(int  uSec=1000;uSec<2000;uSec+=20)  gibi de kullanabilirsin.  Bu durumda servo 1 saniyede min. açıdan  max açıya gelmeli.
Eğer bu şekilde, bu kod ile  servoyu elinle çevirip getirdiğin maksimum noktaya getiremezsen 1000'i azalt ve 2000'i büyüt. Yada servo limitlerde zorlanıp fazla akım çekerse  tersini yaparsın.

Digimensch

Tamam dostum bu kismi anladim.
deneme yapip bakayim, deneme yanilma usuluü...
takildigim yer olursa bilgine bas vururum.
tesekkürler