avatar_elektro77

PCA9685 Kullanımı

Başlatan elektro77, 05 Eylül 2022, 17:13:12

Dtmf

İyi günler arkadaşlar pca9685 mod1 ayarlaması yaparken mod2 olarak gönderdim birdahada çalışmadı bu konuda yardımcı olabilecek varmı

ete

Bildiğim ve kullandığım bir entegre değil bu. Bu nedenle Data Sheet'ine baktım.
Gözüme ilk çarpan şey "Software Reset" oldu.

"PCA9685 LED All Call address (1110 000) and Software Reset (0000 0110) which are
active on start-up"

Software Reset nasıloluyor diye br bakayım dedim. Data Sheet "7.6 Software reset" açıklmasını yorumlamaya çalıştım ama pek anladığımı söyleyemiyeceğim. Orada cihaz adresini 0000 000+0 olarak verileceği belirtilmiş. Karmaşık bir iş. Sen de araştır bakalım. Belki bir şeyler bulursun. Bu reset ile entegrenin açılış (powerup) konumuna getirildiği ve bus 'ında herhangi bir cihazın asılı bırakılmadığı belirtilmiş.

Ete



Dtmf

Ete hocam ıkı gündür datashet türkce cevirdim araştırıyorum söyle bir tuhaf durum var bu modul 1dk 28 sn sonra aktif olup servo komutunu 10sn ligine icra edip, tekrar pasif hale geciyorsonra 2.56 dk sonra tekrar ediyor yani her 1dk.28 sn de bir 10sn ligine aktif oluyor. Sanırım mod2 de ayarları bozdum

ete

Ne yazıkki yardımcı olamayacağım. Hiç bilmediğim bir entegre. Hadi inceleyeyim dedim ama öyle bir çırpıda anlaşılacak kadar bast bir data sheet'i yok maalesef. Bu NXF nin data sheetlerini hiç sevmem. Her şeyi çok ağır bir dille anlatır.

Ete,

Dtmf

Gerçekten karışık bi datasheti var hocam cihazı uyku modundan çıkaramadım bir türlü. Mod1 okuduğum zaman binary olarak uyku modunda ve osc kapalı gözüküyor

ete

Hiç bir rakamsal bilgi vermeden bu entegrenin uyku modunda olduğunu ve bu moddan çıkartamadığını söylediğine göre olaya yeterince hakimsin diye düşünüyorum.
Ama diğer taraftan da merak etmekten kendimi alamıyorum. Biraz daha data sheet inceleyince bu işin Mode1 registerinde bittiğini anlayabiliyorum.
Bit bazında bu registeri nceleyecek olursak;
Bit-7 bu RESTART , açıklamada şöyle söylüyor. Kullanıcı çalışan bir PCA9685 de kanalları durdurmadan entegreyi Uyku moduna (MODE-1) sokmak isterse bu biti set etmelidir. Tersine entegre uyku modunda ise ve sen bunları eski haline çevirmek istiyorsan bu biti sıfırlaman gerektiğide aynı yerde yazıyor. Bu işlem için;

1. MODE1 kaydını okuyun.
2. Bit 7'nin (RESTART) mantıksal 1 olup olmadığını kontrol edin. Eğer öyleyse, bit 4'ü (SLEEP) temizleyin. osilatörünün stabilize olması için zaman tanıyın (500 �s).
3. MODE1 kaydının 7. bitine lojik 1 yazın. Tüm PWM kanalları yeniden başlatılır ve
RESTART biti temizlenir.
Bu durumda senin öncelike bu işlemi yapman gerekiyor. Hangi programlama dilini kullandığınıda yazmayınca insan nasıl fikir vereceğinide bilemiyor. Bu nedenle sen şimdilik bu açıklamaya uygun gelen işleri yap ve sonunda ne sonuç aldığını burada kullandığın kodları da ekleyerek belirt istersen ona göre gerekirse yeniden düşünelim.
Burada kritik bir bilgi var. SLEEP bitinin değiştirilmesi için 500us lik bir sürenin mutlaka verilmesi gerektiği bir çok yerde belrtiliyor data sheet de.

Ete

mehmet

Bu entegrede kalıcı hafıza yok ki. POR sonrası registerler üzerinde katalogdaki yıldız işaretli değerler ile açılıyor.
Özellikle OE pinini kontrol edin.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

mehmet

#52
Maalesef BASIC ile yardım edemiyorum. Ama yol gösterebilirim.

Alttaki kodlar ile çalışıyor:
Hazırlık:
I2C_Basla();
I2C_Yaz(I2C_ADDR);
I2C_Yaz(0xFE);              //Çıkış frekansı belirleme
I2C_Yaz(11);                //11-> ~500Hz

I2C_Tekrar_Basla();
I2C_Yaz(I2C_ADDR);
I2C_Yaz(0x00);              // Mode1 seç
I2C_Yaz(0b10100001);        // Mode1: Restart açık(7), dahili osilator(6), otomatik artırma açık(5)
//I2C_Yaz(0b10100001);      // Mode1: Restart açık(7), dahili osilator(6), otomatik artırma kapalı(5)
I2C_Tekrar_Basla();
I2C_Yaz(I2C_ADDR);
I2C_Yaz(0x01);              // Mode2 seç
I2C_Yaz(0b00000100);        // Mode2: ön tanımlı(kullanılmayabilir)
I2C_Dur();
mb_delay(1000);

Bir kanala değer verme:
(Mode1 de otomatik artırma iptal edilir ve tek lede değer verilir.)
I2C_Basla();
I2C_Yaz(I2C_ADDR);
I2C_Yaz(0xFA);                 // Tüm ledler veya 6H'den başlayan ilk led
I2C_Yaz(0x00);                 // Ledin yanması için bekleme süresi. (Burada hemen açılıyor)
I2C_Yaz(0x00);                 //
I2C_Yaz((uint8_t) i);          // Ledin sönme süresi
I2C_Yaz((uint8_t) (i >> 8));   //
I2C_Dur();

Mcu programlanırken bazen huysuzluk yapıyor. Modülün besleme ucunu çıkarıp mcuyu öyle programladım.
PIC16F887 ile denemeler yaptım.
Yukarıdaki ayarlar için Vcc den besleme vermelisiniz. Led çıkışlarını OD olarak sürecekseniz veya servo çalıştıracaksanız; V+ pininden de gerilim vermeniz gerekecek.
Yine yukarıdaki ayarlar ile OE pinine dokunmanıza gerek yok.
Modül üzerinde led çıkışlarına seri 220R direnç bağlanmış, sadece led bağlamanız yeterli.

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Dtmf

#53
Hocam çok teşekkür ederim ilgilendiniz çalıştı sonunda.iyi bayramlar diliyorum
Bir kaç sorum olacak hocam
1-ön ayarları yapabilmek için 0x00 adresine 7.bit 1 ve 4.bit 1 verilerek uyku moduna sokup işlem yapılıp sonra 4.bit 0 verilerek uyku modundan çıkarmadan bahsetmiş
2-otomatik artırım doğrumu anlamışım 1.kanaldan başlayıp 16.kanala kadar tarayarak her kanal için ayrı ayrı veriler yüklüyor yoksa örneğin 1.kanal için verdiğimiz değeri servo motor için konuşursak 16 kanala birdenmi dağıtıyor

Dtmf

Hocam frekans olayı prescale degeri 500hz için $0C  çıkıyor. Sizin örnek programda prescale degeri $03 max frekans olan 1526hz olarak verilmis
https://hizliresim.com/jvw0ben

mehmet

#55
İyi bayramlar.

Şu an cevaba ikinci sorudan başlamak istiyorum.  😁
Otomatik artırma verdiğimizde;
I²C start
I²C yaz(ı²c adresi)
I²C yaz(ilk led/servo adresi«06 ilk»)
I²C yaz(0)
I²C yaz(0)// hemen yanacak
I²C yaz(pwm1 değerinin alt 8-biti)
I²C yaz(pwm1 değerinin üst 8-biti) //dur komutu vermeden tüm 16 kanal için sadece pwm değerlerini gireceğiz. 
I²C yaz(0)
I²C yaz(0)// hemen yanacak
I²C yaz(pwm2 değerinin alt 8-biti)
I²C yaz(pwm2 değerinin üst 8-biti)
...
...
I²C yaz(0)
I²C yaz(0)// hemen yanacak
I²C yaz(pwm15 değerinin alt 8-biti)
I²C yaz(pwm15 değerinin üst 8-biti)
I²C dur
16 kanala değer vermiş olacağız.

Bir nokta daha var. Özellikle otomatik artırma da iken, ya her ACK sonrası çıkışa değer verilebiliyor ya da Stop komutundan sonra. Ben stop gelene kadar çıkış verilmemesi taraftarıyım. Yani tüm değerler tampona yazılır, stop komutu gelince hepsi aynı anda çıkışa verilir. 
Tabii ki projeye göre bu değişiklik gösterecektir.

Birinci soru için daha ayrıntılı haftaya cevap verebilirim. Ancak, işlem yapıldıktan sonra uyutmak daha uygun olacaktır.

Frekans hesabı çok karışık değil. Sadece -1 olayını unutmamak lazım.  8)

Kolaylıklar...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Dtmf

#56
Ben verileri bu şekilde gönderiyorum.sanırım yaptıgım otomatik adres artırımını iptal etme tek tek adresleri yazıp gönderme işine giriyor
PCA9685:
I2COut RXX1,TXX1,ADRESS,$06,[0] 
I2COut RXX1,TXX1,ADRESS,$07,[0] 
I2COut RXX1,TXX1,ADRESS,$08,[MOTOR1.LowByte]   ; 1. MOTOR
I2COut RXX1,TXX1,ADRESS,$09,[MOTOR1.HighByte] 

I2COut RXX1,TXX1,ADRESS,$0A,[0] 
I2COut RXX1,TXX1,ADRESS,$0B,[0] 
I2COut RXX1,TXX1,ADRESS,$0C,[MOTOR2.LowByte]    ;2. MOTOR
I2COut RXX1,TXX1,ADRESS,$0D,[MOTOR2.HighByte] 


I2COut RXX1,TXX1,ADRESS,$0E,[0]                 ; SERVO 1  SAG SOL YÖN 
I2COut RXX1,TXX1,ADRESS,$0F,[0] 
I2COut RXX1,TXX1,ADRESS,$10,[VERI1.LowByte] 
I2COut RXX1,TXX1,ADRESS,$11,[VERI1.HighByte] 


I2COut RXX1,TXX1,ADRESS,$12,[0]                   ;SERVO 2  ;ASAGI YUKARI YÖN 
I2COut RXX1,TXX1,ADRESS,$13,[0] 
I2COut RXX1,TXX1,ADRESS,$14,[VERI2.LowByte] 
I2COut RXX1,TXX1,ADRESS,$15,[VERI2.HighByte]

I2COut RXX1,TXX1,ADRESS,$16,[0]                    ;SERVO 3 SAG KANAT 
I2COut RXX1,TXX1,ADRESS,$17,[0] 
I2COut RXX1,TXX1,ADRESS,$18,[SAGKANAT.LowByte] 
I2COut RXX1,TXX1,ADRESS,$19,[SAGKANAT.HighByte] 

I2COut RXX1,TXX1,ADRESS,$1A,[0]                   ;SERVO 4 SOL KANAT
I2COut RXX1,TXX1,ADRESS,$1B,[0] 
I2COut RXX1,TXX1,ADRESS,$1C,[SOLKANAT.LowByte] 
I2COut RXX1,TXX1,ADRESS,$1D,[SOLKANAT.HighByte]  

I2COut RXX1,TXX1,ADRESS,$1E,[0]                   ;harici servo çıkışı
I2COut RXX1,TXX1,ADRESS,$1F,[0]                     
I2COut RXX1,TXX1,ADRESS,$20,[VERI3.LowByte] 
I2COut RXX1,TXX1,ADRESS,$21,[VERI3.HighByte]
Return

sizin kullandığınız programlama dilinde stop biti ı2c ile tüm veriler pca9685 iletildikten sonra stop biti ile çıkışlara aktarılıyor.Benim yazdığım programdan her veride stop biti gönderiyor sanırım

ete

#57
Bir sitede bulduğum ve 8 kanal ayarlı pwm sinyali oluşturan buton kontrollü ve frekans ayarlı programı Basic'e çevrip ilişikte veriyorum. Belki birilerinin işine yarayabilir.

Ete

parametre

#58
Tesekkurler


Edit: yüklendi. (Ete)

mehmet

@Dtmf, halâ sıkıntılar var mı, yoksa işlem tamam mı?  8)
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Powered by EzPortal
▲