Merhaba arkadaşlar,
Neopixel yani adreslenebilir ledler üzerinde bir projem var. Bu konuda nasıl bir yol izleyebilirim.
Datasheet okudum.
Her renk 8-bir olarak kontrol ediliyor. Dolayısıyla bir ledin kontrolü için 24-bit gönderilir.
Protokol kısmına kısmen hakimim. Anlamadığım nokta şu hangi seri haberleşme yöntemi ile yapmalıyım.
İyi çalışmalar.
Datasheet te ayrıntısı war zaten. Tek kablo üzerinden uygulanan FIFO yapısıyla seri bilgi aktarımı..
Önce uzak led bilgisini çıkarsınız en sona en yakın led bilgisini.
Her çıkış bir önceki çıkışı b adım öteye öteler.
Sayfa 3, 4 ve 5 bu bilgileri zaten içeriyor.
https://cdn-shop.adafruit.com/datasheets/WS2812.pdf (https://cdn-shop.adafruit.com/datasheets/WS2812.pdf)
Yanıtınız için teşekkür ederim.
Dediğinizi biliyorum. Detaylıca inceledim. Bilmiyorum belki de takıldığım nokta çok basit olabilir. Fakat anlamadığım ben 0xA9C bu 24-bitlik veriyi ledlere göndermek istesem nasıl yaparım?
int32 data = 0xA9C;
spi_write(data); //spi
fprintf(UART, data); //rs-232
Bunları kullanmak doğru olur mu?
Bir diğer nokta bu ledlere gönderilen verinin hızı max. 800kHz olmalı diye datasheetten okumuştum.
Bunu nasıl sağlayabilirim.
İyi çalışmalar.
Arduino kodlarını inceleyiniz. Daha
hızlı yol alırsınız.
Merhaba. Ws2812de kendisi infaruj ledlerin sürülmesine benzeyen bir protokol oluşturmuş. Diyelim ki 1 bit 3mikrosaniyede gönderiliyor. Bu 3 usaniyenin 1mikrosaniyesi lojik 1, 2 mikrosaniyesi lojik 0 okursa durumu 0 kabul ediyor. 2mikrosaniyesi lojik1, 1 mikrosaniye 0 olursa 1 kabul ediyor. Buna göre önce 8biti kodlayacak kütüphaneyi yaz yada arduinodan çevir. Sonra her led için rgb olmak üzere 3byte göndereceksin. Kaç tane rgb ledin varsa o kadar sayıda veri göndreceksin. Veriler arasında belirli milisaniye beklemek ledlerin resetlenip ilk ledin veri almasını sağlıyor. Sanırım takıldığın nokta burası.
Yanıtlarınız için teşekkür ederim.
Ben veriyi hangi haberleşme(spi, uart, i2c, wire, vs.) üzerinden göndereceğimi bilemedim.
Datashette veri işlemi hızı 800kHz yani 1.25us(1/800kHz = 1.25us) değerini aşmamalıdır ifadesi yer alıyor.
Bunun için baud rate değerine dikkat etmem gerekecek. Biliyorum.
Benim takıldığım nokta burası. Hangi haberleşme?
iyi çalışmalar.
Ben kendi görüşümü söylersem "hiçbirisi".
Kendi protokolünü oluştur. Tek kanaldan çıktı oluştur.
SPI UART I²C veya diğerleri çift yönlü protokollerdir.
Sana "
saldım çayıra mevlam kayıra" protokolü lazım. :D
Boud Rate timing olayına dikkat etmen gerek sadece.
Akıllı Ledlerle ilgilenmedim hiç.
Ama
Sinclair-Spectrum parmaklamışlığımız war.
Kaset çalar üğzerinden gelen sesleri data olarak okuyordu.
Sonuçta tek canlı tel üzerinden data okuma.
Yanıtın için teşekkür ederim.
Benimde aklıma ondan başka bir yol gelmiyor. Kendi protokolümü oluşturacağım.
Bu baud-rate için bir önerin var mı?
İlgili Dataları-Frame'i bitlerine ayırıp 1 için belli genişlikte, 0 için belli genişlikte
bir Porttan seri olarak gönderin.
Şeması,tek yollu haberleşme donanımı olduğunu gösteriyor.
Tek yollu haberleşme Protokollerinde Clock olmaması sizi aldatmasın.
Pixel Led içindeki işlemci-Receiver sizin gönderdiğiniz Bitler'in genişliğinden
gelen datanın ne olduğunu anlayabilir.
Tıpkı IR, RF Protokollerindeki gibi.
Alıntı yapılan: JOKERAS - 10 Nisan 2018, 11:40:21İlgili Dataları-Frame'i bitlerine ayırıp 1 için belli genişlikte, 0 için belli genişlikte
bir Porttan seri olarak gönderin.
Şeması,tek yollu haberleşme donanımı olduğunu gösteriyor.
Tek yollu haberleşme Protokollerinde Clock olmaması sizi aldatmasın.
Pixel Led içindeki işlemci-Receiver sizin gönderdiğiniz Bitler'in genişliğinden
gelen datanın ne olduğunu anlayabilir.
Tıpkı IR, RF Protokollerindeki gibi.
Evet öyle oluyor. Benim anlamadığım 24-bit göndereceğim ya. Bu 24-bir nasıl bir frame olacak?
Teşekkürler.
O sizin keyfinize kalmış bir şey.
Ne göndereceğinizi siz belirleyeceksiniz.
Mesela Gök Kuşağı göndermek için olan Frame'i ya hazır kütüpanesini bulacak,yada kendiniz oluşturacaksınız.
Ne bileyim.
Alıntı yapılan: makine_terbiyecisi - 10 Nisan 2018, 11:36:44Yanıtın için teşekkür ederim.
Benimde aklıma ondan başka bir yol gelmiyor. Kendi protokolümü oluşturacağım.
Bu baud-rate için bir önerin var mı?
Checksum kullanman gerekmeyecek sanırım.
o yüzden datasheet limitlerine uygun frekans üzerinden yola çıkarak baudrate hesabı yapabilirsin.
zaten sıfırlar ve birler birbirinden farklı uzunlukta oldukları için ortalama eşitmiktarda 1 ve 0 olarak düşünerek yapmaya çalış.
Alıntı yapılan: makine_terbiyecisi - 10 Nisan 2018, 11:44:28Evet öyle oluyor. Benim anlamadığım 24-bit göndereceğim ya. Bu 24-bir nasıl bir frame olacak?
Teşekkürler.
Mantık yürüterek renk standartlarında RGB sıralamasıyla 8+8+8=24 bit olacak şekilde datalarını gönderirsen ardışık kaç led için gönderim yapacaksan en sondaki ledi en önce ye sıralayarak dataları gönderirsen problem olmayacaktır sanırım.
birkaç denemeden sonra zaten olaya vakıf olacaksın.
Sonrasında biz senden öğreneceğiz. ;D
çıkış sırası şöyle 4 led olduğunu varsayarsak...
Bağlantı tarafı -> led1 + led2 + led3 + led4
gönderilecek bilgi ise
öncelik sırası led4(RGB) +led3(RGB) + led2(RGB) + led1(RGB)
bir ledi açarsak önce R sonra G sonra B gönderilecek.
Led4{R(b=11111110) + G(b=00000001) + B(b=00011110)} olsun
gönderime sıralayacak olursak
led4 R için önce 0 sonra sırasıyla 1111111, toplamda 8 bit
led4 G için önce 1 sonra sırasıyla 0000000, toplamda 8 bit
led4 B için önce 0 sonra sırasıyla 1111000, toplamda 8 bit
toplam 24 bit
yani önce kırmızı küçük değerli bitleri göndereceksin.
Alıntı yapılan: Mehmet Salim GÜLLÜCE - 10 Nisan 2018, 12:01:13Mantık yürüterek renk standartlarında RGB sıralamasıyla 8+8+8=24 bit olacak şekilde datalarını gönderirsen ardışık kaç led için gönderim yapacaksan en sondaki ledi en önce ye sıralayarak dataları gönderirsen problem olmayacaktır sanırım.
birkaç denemeden sonra zaten olaya vakıf olacaksın.
Sonrasında biz senden öğreneceğiz. ;D
Elbette burdaki amacımız o zaten. :D
Yanıtlarınız için teşekkür ederim.
Şöyle yapsam:
Örneğin
x = 128; //0b10000000 --> Red
y = 128; //0b10000000 --> Green
z = 128; //0b10000000 --> Blue
Bunu bir pin üzerinden göndersem hangi komutu kullanacağım?
Alıntı yapılan: makine_terbiyecisi - 10 Nisan 2018, 12:31:15Yanıtlarınız için teşekkür ederim.
Şöyle yapsam:
Örneğin
x = 128; //0b10000000 --> Red
y = 128; //0b10000000 --> Green
z = 128; //0b10000000 --> Blue
Bunu bir pin üzerinden göndersem hangi komutu kullanacağım?
Komut kullanmak çok doğru bir soru değil.
bir pini çıkış portu olarak tanımlayıp bir bekleme aralığı için zaman döngüsünü kullanacaksın.
sağdaki bitlerden başlayarak önce R sonra G sonra B renklerini 0 1 2 3 4 5 6 7 inci bitleri göndereceksin.
göndermeyi şöyle yapacaksın.
-bekleme zaman döngüsü en kısa pals için gereken süre kadar dönecek.
-1 için haberleşme portunu HI yapıp bekleme portunu 2 defa üstüste çağıracaksın. geri dönüşünde portu LOW Yapacaksın. yeniden çağıracaksın. HI ve LOW süreleri 2xHI + 1xLOW olmuş olacak.
-0 için ise tersini yapacağız 1xHI + 2xLOW sürelerinde olacaklar.
gödereceğin bitlerin ne olduğunu bilmen gerekecek yani.
bunuda 8 bit için yaptığında bayt yada renk-Data gönderme rutini haline getirirsen...
RGB için 3lüğ denetim yaparsan...
renkleri yazıp subrutini çağırmak kalır geriye
çıkacak dalga şekli datasheet 4. sayfadaki gibi..
(https://s9.postimg.cc/fxpcusza7/Serial_Send.png)
Teşekkürler.
Biraz uğraşayım bakalım.
hangi işlemciyi kullanıyorsunuz.
@omereliusuk PIC18F4431 kullanacağım.
en az 64mhz lazım. pwm yoluyla kullanacaksınız. geçmiş zaman 18f46k22 (64mhz/4=16mhz)veya daha yüksek bir işlemci ile pwm kanalıyla sürmüştüm. başlangıçta çok yormuştu. sonra güzel oldu.
Led sayısı fazla olamayacağı için sorun teşkil edeceğini düşünmüyorum. Yoksa yanılıyor muyum.
Bildiğim kadarıyla ki siz projeyi gerçekleştirmişsin eminim benden daha deneyimlisiniz fakat led sayısı az olursa bence pic o kadar hıza gerek duymaz.
Siz ne düşünüyorsunuz?
Çalışmanızı biraz daha detaylandırır mısınız?
hocama bir tane bile led yakamadım. sonra anladım ki önemli olan ne kadar uzun olduğu değil ne kadar işlevsel olduğu :). hızınız müsaitse isterseniz milyon tane yakın sorun yok. hızınız müsait değilse 1 tane bile led yakamazsınız.
:D
Hangi protokol üzerinden denediniz mi? WS2812 mi yoksa eski protokol mü?
https://www.aliexpress.com/item/WS2812B-4pins-5050-SMD-W-WS2811-Individually-Addressable-Digital-RGB-LED-Chip-5V/1639139960.html?spm=a2g0s.9042311.0.0.tWPWKa
Buradan zaman hesabı yapabilirsiniz.
merhaba belki işinizi görebilir
#include <18F4550.h>
#device ADC = 16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=48000000,crystal=20000000)
#define NeoPin PIN_E0
#define NeoNum 60
#define RAND_MAX 64
#define ALL_OUT 0x00
#define ALL_IN 0xFF
#byte PORTA = 0xF80
#include <stdlib.h>
unsigned int8 NeoGreen [NeoNum];
unsigned int8 NeoBlue [NeoNum];
unsigned int8 NeoRed [NeoNum];
void NeoBit (int1 Bit)
{
if (Bit == 1)
{ output_high (NeoPin); delay_cycles (6); output_low (NeoPin); } // delay_cycles (3); // Bit '1'
else
{ output_high (NeoPin); delay_cycles (3); output_low (NeoPin); } // delay_cycles (6); // Bit '0'
}
void NeoInit (void)
{
unsigned int8 NeoPixel;
for (NeoPixel = 0; NeoPixel < NeoNum; NeoPixel++)
{
if (NeoPixel < 10)
{ NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 64; }
else if ((NeoPixel >= 10) & (NeoPixel < 20))
{ NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 0; }
else if ((NeoPixel >= 20) & (NeoPixel < 30))
{ NeoGreen[NeoPixel] = 0; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 64; }
else if ((NeoPixel >= 30) & (NeoPixel < 40))
{ NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 0; }
else if ((NeoPixel >= 40) & (NeoPixel < 50))
{ NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 0; NeoRed[NeoPixel] = 64; }
else if ((NeoPixel >= 50) & (NeoPixel < NeoNum))
{ NeoGreen[NeoPixel] = 64; NeoBlue[NeoPixel] = 64; NeoRed[NeoPixel] = 0; }
}
}
void NeoDraw (void)
{
unsigned int8 NeoPixel;
signed int8 BitCount;
for (NeoPixel = 0; NeoPixel < NeoNum; NeoPixel++)
{
for (BitCount = 7; BitCount >= 0; BitCount--)
NeoBit(bit_test(NeoGreen[NeoPixel], BitCount));
for (BitCount = 7; BitCount >= 0; BitCount--)
NeoBit(bit_test(NeoRed[NeoPixel], BitCount));
for (BitCount = 7; BitCount >= 0; BitCount--)
NeoBit(bit_test(NeoBlue[NeoPixel], BitCount));
}
output_low (NeoPin);
}
void NeoRotate (void)
{
unsigned int8 NeoPixel;
for (NeoPixel = 0; NeoPixel < NeoNum - 1; NeoPixel++)
{
NeoGreen[NeoPixel] = NeoGreen[NeoPixel + 1];
NeoBlue[NeoPixel] = NeoBlue[NeoPixel + 1];
NeoRed[NeoPixel] = NeoRed[NeoPixel + 1];
}
NeoGreen[NeoNum - 1] = NeoGreen[0];
NeoBlue[NeoNum - 1] = NeoBlue[0];
NeoRed[NeoNum - 1] = NeoRed[0];
}
void main()
{
NeoInit ();
while(true)
{
NeoDraw ();
NeoRotate ();
delay_ms (25);
}
}
Onu bende gördüm fakat değişme olmuyor. Benim kullandığım ledler eski tip galiba. Çünkü ledler 3'lü gruplar halindeler. Ondan kaynaklanıyor olabilir.
WS2811 mi?
Sanırsam öyle. Ama üstünde entegre yok. İlk baştaki entegre 4 bacaklı ve üstünde entegre var.
Sonraki iki tane led ise 3 bacaklı.
resim paylaşırmısın yardımcı olmaya çalışırım
Elimdeki ledler ws2811 miş.
Bunları 20MHz kristal kullanan pic ile yapamaz mıyım?
16f1826 ile yapabilirsin az sayıda piksel ledin varsa
Alıntı yapılan: ertuğrul54 - 11 Nisan 2018, 21:37:4416f1826 ile yapabilirsin az sayıda piksel ledin varsa
Led sayısından bağımsız olsa gerek.
Zira seri transfer yapıyor Kıyma makinası gibi.
Makinanın ağzından çıkınca bir sonraki kıyma çıkar.önceki çıkanlar makinayı ilgilendirmez. çıkan çıkmıştır.
Bununda süresi önemli.
unsigned char dr[nDots]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char dg[nDots]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char db[nDots]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#define ws2811_zero 0b10000000
#define ws2811_one 0b11110000
void WS2811send(){
unsigned int j;
unsigned int Mask;
long ii;
for(ii=0;ii<nDots;ii++){
Mask=0x80;
for (j=0;j<8;j++){
if(Mask & db[ii]) spi_write(ws2811_one);
else spi_write(ws2811_zero);
Mask>>=1;
}
Mask=0x80;
for (j=0;j<8;j++){
if(Mask & dr[ii]) spi_write(ws2811_one);
else spi_write(ws2811_zero);
Mask>>=1;
}
Mask=0x80;
for (j=0;j<8;j++){
if (Mask & dg[ii]) spi_write(ws2811_one);
else spi_write(ws2811_zero);
Mask>>=1;
}
}
delay_us(50);
}
ws2811 veya 2812 çalıştırabilirsiniz büyük ihtimal 2813 de çalıştıracaktır
pic16f1827 ile 30 adet led çalıştırmıştım