RGB dimmer Hk

Başlatan yolcu27, 09 Temmuz 2016, 11:06:34

yolcu27

Arkadaşlar pic basic dilinde RGB led sürmek istiyorum. bunu 3 ana 3 ara renkten ziyade istediğim renk tonunu ayarlamak istiyorum .

bir BYTE değişkeni ile portları dimlemek istiyorum 0-255 arasındaki değerlere göre.

örnek bir kod parçacığı varmı acaba hiç dimmer yapmadım da yabancıyım.


şöyle bir kod yazdım ama portlar sırası ile pwm şeklinde yanıyor sönük olarak ama aynı anda yanmıyorlar.

test amaclı yazdıgım kodlar. ben bunu bluetooth ile kontrol etmeyi planlıyorum




@ DEVICE pic16F628A
@ DEVICE pic16F628A, WDT_OFF
@ DEVICE pic16F628A, PWRT_ON
@ DEVICE Pic16F628A, BOD_OFF
@ DEVICE Pic16F628A, LVP_OFF
@ DEVICE pic16F628A, PROTECT_off
@ DEVICE pic16F628A, MCLR_OFF
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT
CMCON=7
DEFINE OSC 4

trisa=%00000000
trisb=%11100000

porta=0
portb=0

pause 50

basla:

pwm portb.7,30,100
pause 1000
pwm portb.6,30,100
pause 1000
pwm portb.5,30,100
pause 2000


pwm portb.7,255,100

pwm portb.6,255,100

pwm portb.5,255,100

pause 5000

goto basla

end





karacan451

Senin kullanacağın işlemci 3 adet harici pwn özelliği olması gerekiyor.

ete

RGB dimmer yapmanın en iyi yolu 3 adet HPWM çıkışı olan bir pic (16F777) kullanmaktır. Böylece ana programdan bağımsız arka planda çalışan verdiğin duty değerlerine uyan 3 ayrı, ama aynı frekansta çalışan bir dimmerin olabilir.
Elimdeki picleri değerlendireyim diyor isen elbette kesme kullanarak da benzer bir çalışma yapabilirsin. Her ne kadar diğeri gibi güzel çalışmasada işini görür sanırım.
Temel fikir ,her 1-2 ms de bir TMR0 kesmesi yaratmak. Kesme alt programında ise 0-255 arasında bir döngü kurup,
Duty_R değeri döngü değerinden küçük ise RED=1 yapmak. Değil ise RED=0 yapmak.
Duty_G değeri döngü değerinden Küçük ise GREEN=1 yapmak, değil ise GREEN=0 yapmak.
Duty_B değeri döngü değerinden küçük ise BLUE=1 yapmak değil ise BLUE=0 yapmak.
Sonra TMR0 ön yükleme değerini verip Kesme bayrağını sıfırlayarak kesmeden çıkmak şeklinde açıklanabilir.
Tabiiki ana program kısmında ledlerin Duty değerlerini bir şekilde ayarlayacaksın. Duty değerleri 1-250 arasında olursa sorunsuz sistem çalışır.

Başka metodlarda var tabiiki ama en iyilerinden birisi yukarıda açıkladığımdır.
İllaki nedir diye sorarsan 0-255 arasını diyelimki 200us lik dilimlere bölersin ve her 200 us de bir kesme oluşturursun.
Ana program bölümünde Duty değerlerini ayarlarsın. Ledlerin yanması gerekenleri yakarsın.
Kesme oluştuğu anda Red=1 ise Duty_R değerinden bir eksiltirsin. Red=0 ise bu sefer 255-R_Duty değerinden bir eksiltirsin.
Kısaca led yanıyor ise Duty değerinden led sönük ise 255-Duty değerinden bir eksilterek  ledlerin duty değerleri kadar yanık kalmasını sağlarsın. Eksiltmeler esnasında değer sıfırlanır ise Led konum değiştirmesi gerekir.

Ete


yolcu27

hocam  dediğiniz gibi TMR0=131 ile 4 ms lik bir kesme oluşturdum

kesme içerisinde kullandığım kodlar şunlar.


ben burada telefondan 3 tane 0-255 arası byte verisi yollayacağım ama bunu  """" HSerIn [BILGI]  """" bu satırda nasıl alabilirm orada takılı kaldım. buradan alıp basla adlı etikette bu değerleri dutyR dutyG dutyB  değişkenlerine yükleyeceğim  burada takılı kaldım. app inventor ile yazıyorum liste şeklide 3 değer birden yollayabilirim. 3 adet 0-255 arası değer şeklinde. burada ama nasıl bir sıra ile alacak orasını kestiremedim. şöyle olabilir mi acaba '  HSerIn [BILGIRED,BILGIGREEN,BILGIBLUE]  ŞEKLİNDE GELEN 3 adet değeri  bunlara sırası ile mi yükler nasıl olur?

 Disable
KESME:
  for i=1 to 255       
    INTCON.7=0    ' kesmeyi kapat
      HSerIn [BILGI]
     isaret=1
     if dutyR<i then
      portb.7=1
     else
      portb.7=0
      endif
      if dutyG<i then
      portb.6=1
      else
      portb.6=0
      endif
      if dutyB<i then
      portb.5=1
      else
      portb.5=0
      endif
     
   
       next
       TMR0=131
    TEMP=RCREG   ' kesme bayrağı sıfırlar
   INTCON.7=1           ' kesmeleri aç
      Resume
      Enable
     
      End

yolcu27

sorunu hallettim bu kodların for next kısmını ana donguye taşıdım. bir kaç değişiklik yaptım bluetoothtan yolladıgım 1-250 arası 3 ayrı değere göre ledlerimi dimliyorum. fakat kısık yanarken titreşim çok fazla geldi bana 4 ms lik bir kesme oluşturdum bunu daha düşürmek için nasıl hesap yapılır bilmiyorum açıkcası .

ete

Gönderilen bilgi adedi kadar değişken kullanılarak gelen bilgilerin tamamı bir anda alınabilir.
Bilgi1,bilgi2,bilgi3 şeklinde. Bunu döngü ile de almak mümkün ama bence az da olsa zaman kaybı yaşanabilir.

Timer hesabı çok kolay bunu efalarca açıkladım. Ama hesapla uraşmayayım diyorsan Picmulticalc.exe isimli çok kısa programı kullanmanı öneririm. Her ne kadar hesabı bilsemde bende işimi bu programla hallediyorum. Başka işlerede yaradığı için program gerçekten çok yararlıdır.
Sitede yükleme adresi olması gerekir. Ara bulursun yada netten bullabilirsin.
Hesaba gelince. Sana diyelimki 2 ms lik bir kesme süresi lazım. Bu 2000us eder. Hesap daima us cinsinden yapılmalıdır.
TMR0 yalnızca 0-255 arasında sayabildiği için bölücüleri devreye sokmak gerekir. Bölücü genellikle Option_Reg registerinin ilk 3 biti ile ayarlanır. 1/2 - 1/4 - 1/8 - 1/16 - 1/32 - 1/64 - 1/128 - 1/256 şeklinde değerler alır. Bölücü ne demektir onuda açıklayayım. Kaç adet işlemci kristalinden gelen CLK palsi ile bir TMR0 değeri artırılacak onu belirler. 1/2 bölme oranı alınmış ise 2CLK palsi TMR0 değerini bir artırır. 1/128 alınırsa 128 clk palsi ile Tmr0 değeri bir artar. Bu sayede daha uzun süreli kesme süreleri elde edilmiş olur. Tekrar hesap kısmına dönelim. 2000us değerini kaça bölerimki bana 255 veya daha küçük bir değer versin. 2000/8 =250 gibi bir değer veriyor ki bu bizim için uygun bir değer oluyor.
O halde bölme oranımızı 1/8 alacağız. Böylece her 250 clk palsinde TMR0 1 sayar ise 250*8=2000 değerine ulaşmış olacağız demektir bu. Toplamda timer0 da 250 sayacağı için, Timer0'a ( 256-250=)6 ön yükleme değeri verdirmemiz gerekecektir. Kısaca TMR0 6 dan başlayıp 255 den 256 'ya geldiği an ki bu aslında TMR0 ın yeniden sıfıra döndüğü an demektir geçen süre 256*8=2000 us olacaktır. Neden 256 dan çıkarma yapıyoruz diye sorabilirsin. Kesme sayacın 255 den 256 ya geçip 256 olmayıp yeniden sıfır olduğu anda oluşur. Bu nedenle 2000 us sonra kesme oluşabilmesi için sayacımızı 0 yerine 6 dan başlatmak zorundayız. 0 dan 250 ye kadar sayılan sayı ile 6 dan 256 ya kadar sayılan sayı aynıdır ve aynı sayıda clk palsi gerektirir. Ama birinde kesme oluştuğu için 6 dan başlatıyoruz.
Aynı işi 2000/16=125 ile de yapabilirdik. Bölme oranımız 1/16 olur ve TMR0'a 256-125=131 değerini vererek yine 125*16=2000 us lik gecikme elde edebilirdik.

Ete




yolcu27

Hocam çok teşekkürler bu yazınızı çok okudum hesaplama hakkında . Dediginiz programı indireyim kalsın masaüstünde.

Kendi programında bölme oranını 1/16 yapayım ozaman Option_Reg registeri ile  ozaman bu göz kırpmalar azalır sanırım.

yolcu27

#7
for next döngüsünü daha kısa tutasrak daha iyi sonuca vardım titreme çok azaldı

Powered by EzPortal