Protokol komutlarına göre led yakıp söndürme

Başlatan blueboard, 11 Şubat 2025, 21:33:43

blueboard

Ete Hocam, iyi akşamlar. Yardımınıza ihtiyacım var. Bir koıntrol devresinde NEC protokolüne benzeyen ama NEC olmayan komutlar gönderiliyor. Bu komutlar infrared led ile değil de normal kablo üzerinden gönderiliyor. Bununla ilgili ekran görüntülerini paintte tek bir foto üzerinde toplayıp ekledim. Bu protokol 16 bitten oluşuyor. İlk 8 bit her 3 komutta da aynı geliyor. Resimden de göreceğiniz üzere başlangıçta sürekli high geliyor. Ardından komut gönderilmeye başlandığında 9 ms low ve 4,5 ms high gelerek header sinyali oluşturuluyor. Bu aşamadan sonra komut 16 bit olarak gönderilşiyor. Lojik Analizör ile ölçümleri transistör kullanmadan yani terslemeden direkt olarak analizöre girdim. Buradaki tespitimde 0 biti 560 ms low+ 560 ms high'tan oluşuyor.      1 biti ise 560ms low+ 1890 ms high'tan oluşuyor( en azından ben o şekilde yorumladım. Siz daha doğrusunu bilirsiniz) . Bu yorumuma göre eklediğim resimdeki 1. komut 1111000100101001    ,   2. komut  1111000110100001 ve 3. komut ise 1111000100010001 olduğunu tespit ettim. Sizin daha önce IR kumanda datalarını almak konusundaki programınız üzerinde elimden geldiği kadar düzenleme yaptım ancak yaptığım değişikliğin n e derece doğru olduğu konusunda fikrim yok. Proteus versiyonu uyumsuzluğu olabilir düşüncesiyle devre şemasının ekran görüntüsünü de ekledim.Size zahmet kontrol eder misiniz.




ete

#1
Tamamen NEC protokol mantığı ile yollanmış bilgiler. Ufak tefek farklılıklar var elbette.
Bu protokolde ilk 8 bit Cihaz kodu dur. Dolayısıyla komutlarda cihaz kodunun aynı tutulması tesadüf olmasa gerek.
Sonraki 8 bit cihaz kodunun tersi(bitlerin ters çevrilmiş hali)  olması gerekirken sende komut bilgisi yollanmış oluyor. Farklılık burada başlıyor.
Normal protokolde 32 bit bilgi yollanır iken sende 16 bit yollanıyor yani terslenmiş bilgiler yollanmıyor. Hepsi bu. Zaten benim kod çözme mantığımda da terlenmişler devre dışı kalıyor idi.
Yapılacak iş şöyle;
Program öncelikle 4,5ms lik HIGH peryodunu yakalamalı ve ardından 16 adet biti süre bazında kayıt etmelidir.
Herbir bilgi biti 2 şer bit ile ifade edildiği için ve bitin ne oldupunu belirleyen ise ikinci bit olduğundan 4,5ms lik HIGH peryodunun ardından ikinci HIGH peryod olan bilginin ikinci parçası alınıp süre bazında kayıt edilmelidir.
16 bitkik kayıt daha sonra çözümlenmeli ve bunun içinde sürenin 70us ki bu aslında 700us ye  tekabül edecektir. Bu süre 70 den büyük ise o bit "1" değil ise "0" olacaktır.
Bu temel mantık üzerinden çalışması gereken program aşağıdadır.
Bu arada tuş kodlarını verdiğin değerlere göre 41 - 161 - 17 olarak tespit edip programa yerleştirdim.

Ete


  
    'PIC 16F1827 İŞLEMCİ
    #CONFIG
      __config _CONFIG1, _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _CPD_ON & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_ALL & _PLLEN_OFF & _STVREN_ON & _LVP_OFF & _BORV_19 & _LVP_OFF 
    #ENDCONFIG
    DEFINE OSC 4
    OSCCON      =%01101000      ' %0xxxx000 ,xxxx=1111 16Mhz, 1110=8Mhz, 1101=4Mhz, 1100=2 Mhz.
    OSCTUNE    =0
    DEFINE PULSIN_MAX 12000 'Maximum counts allowed before pulsin times out
    WPUA      =0              'MCLR için bit5 Pull-up enabled.Eğer MCLR ON yapılmışsa herzaman enabled.
    WPUB      =0
    ADCON0.0  =0              'ADC ölçümleri iptal edildi.
    ANSELA    =0              'PortA nın <4:0> arası analog-dijital olabilen pinlerini dijital yaptık.Pinler Dijital I/0 oldu.
    ANSELB    =0 
    CCP1CON   =0            'Capture/Compare/PWM off
    CCP2CON   =0            'Capture/Compare/PWM off
    CM1CON0.7 =0              'Comparatör disable-kapalı.
    CM2CON0.7 =0
    FVRCON    =0              'Referans sabit voltaj çıkışları (COMPARATOR,DAC ve ADC) kapalı-disable.
    DACCON0.7 =0              'DAC referans voltaj çıkışı kapalı.
    CPSCON0.7 =0              'Capasitive sensing modulu disable yapıldı.
    MDCON.7   =0              'Modülasyon modülü iptal edildi.DSM (Dijital Sinyal Modülü) iptal. Modüleli yani karışık sinyal çıkış kapalı.
    MDSRC.7   =1              'Çevresel sinyallerin sürücü çıkış pinleri iptal.Modüleli sinyal çıkışı pinleri kapalı.
    CLKRCON.7 =0              'Referasn clock modülü kapalı.
     
    PIE1      =0              'TÜM ÇEVRESEL KESMELER KAPALI.
    PIE2      =0              'Tüm Çeveresel Kesmeler Kapalı.
    PIE3      =0
    PIE4      =0              'Tüm çevresel kesmeler kapalı.
    APFCON0=0  'CCP1=B3 de, CCP2=B6 da
    APFCON1=0
     
    LATA=0
    TRISB=%00000001  'PortB.0 giriş diğerleri çıkış yapıldı.
    TRISA=%00000000  'A portu tamamı çıkış yapıldı.
    OPTION_REG.7 = 1    'dahili Pull up dirençleri aktif edildi ayrıca pullup direncine gerek yok.
    OPTION_REG.6 = 0    'düşen kenarda kesme oluşturacak
    '-----------------------------------------------------------------
     
    SYMBOL DATA_GIRIS=PORTB.0
     
    Paket var word 56
    Tus  Var Byte 60
    Cihaz Var Byte 61
    DATA_AL var BYTE(16)62
     
    I    var Byte 100
    Z    var BYTE 101
    TEMP VAR BYTE 102
    SAY  VAR WORD 103
    TAMAM VAR WORD 105
    ARA  VAR BYTE 107
     
    SYMBOL ALDIM=ARA.0
    SYMBOL ILK  =ARA.1
    IOCBN=%00000001 
    INTCON=%10001000  'Kesmeler aktif ve RB0/INT kesmesi aktif
    ON INTERRUPT GoTo KESME  'kesme oluşursa KESME adlı etikete git.
    LATB=0
    PAUSE 200
    '-------------------------------------------------------------------
    BASLA:
          SAY=0
          while ALDIM=0
            SAY=SAY+1
            IF SAY=2700 THEN LATB=0
          WEND
          ALDIM=0
           
          TUS=0
          for I=0 to 7
'            WRITE (0+I),DATA_AL[I]
            IF DATA_AL(8+I)>7 then TUS.0[I]=1 '8 bit den itibaren gelen 8 bit ise komut bitleri oluyor
          next 
'          PAUSE 10                                                    
          IF TUS=41 THEN  '    11110001 00101001    32+8+1=41
            LATB.4=1 
            PAUSE 10
            GOTO BASLA
          endif
          
          if tus=161 THEN  '    11110001 10100001    128+32+1= 161
            LATB.5=1 
            GOTO BASLA
          ENDIF
          
          IF TUS=17 THEN    '    11110001 00010001    1+16=17
            LATB.6=1 
            GOTO BASLA
          ENDIF                          
                  
'          LATB=0
          
          GOTO BASLA          
      
    DISABLE    
    KESME:  
            PULSIN DATA_GIRIS,1,TAMAM:TEMP=NCD(TAMAM) 
            IF TEMP=9 THEN    ' BU PROTOKELDE lojik 0 560 low 560 high VE    
            for I=0 to 15                    'lojik 1 560 low 1890 high OLDUĞUNDAN HIGH BİTLERİNİ ALMAK DOĞRU OLACAKTIR DİYE DÜŞÜNÜYORUM.
              PULSIN DATA_GIRIS,1,TEMP:DATA_AL(I)=NCD(TEMP) 'YALNZCA HIGH BİTLERİNİ ALIP SÜRESİNİ KAYIT EDİYORUZ
            next 
            ALDIM=1:ILK=1:LATA.0=1 
            ENDIF 
            
    GECGIT: SAY=0     
            INTCON.0=0:IOCBF=0  
            Resume      
    Enable      
    End

17-02-2025 de İKİNCİ DEFA düzenlendi (Ete)

blueboard

Ete Hocam, hızlı cevabınız için sonsuz teşekkür ederim. İlk fırsatta gerçek devreyi kurarak deneyeceğim. İyi ki varsınız. Siz olmasanız benim gibi acemilere kim yol gösterecekti. Sağlığınıza duacıyım.

blueboard

Ete Hocam,iyi akşamlar. Maalesef ne yaptımsa devreyi bir türlü çalıştıramadım. Mutlaka bir şeyi atlıyorum ama hatamın nerede olduğunu bilemiyorum. Kullandığınız Proteus'un versiyonu nedir? Sizinle aynı versiyonda hem verici hem de alıcı devreyi çizeyim. Verici devrenin kodlarını yazarım. Tüm kodlar ile birlikte buraya yükleyeyim. Zamanınız olduğunda kontrol etmenizi rica edeceğim.

ete

Hemen telaş etme. Bir sebep yakalamaya çalışalım önce bütün. Eminim mantıklı bir sebebi vardır çalışmamasının. Programa bakınca sigorta ayarlarında ;
_FOSC_XT  grüyorum. Bu devrede kristal kullanılmasını gerektiren bir komut. Ancak alt kısma bakınca da her şeyin dahili OSC ye göre yazıldığını anlıyorum. Şimdi soruyorum devrende kristal kullandınmı?
Aslında birebir bir devre şeması buraya kaysan daha iyi olabilir.
Diğer taraftan bu gibi durumlarda şüphe duyacağımız bir kaç nokta olacak. Bunların başında programın 4500us lik HIGH pulsini yakalayıp yakalamadığını bir şekilde anlamak.
İkincisi puls sürelerinin hangi değerlerle okunup kayda alındığının bilinmesi ki bunuda okumadan sonra kod ayıklamadan önce okunan süreleri eproma yazdırıp sonra bu süreleri incelemek.

Bana kalırsa sorun bu anlattıklarımdan birisi kesinlikle.
4500us lik süre için , kesme içindeki aşağıdaki satırın devamına işlemcinin boş bir pinini HIGH yaptırarak anlayabilirsin.;
ALDIM=1:ILK=1:LATA.x=1 şeklinde.

Sürelerin durumunu gözlemlemek için ise;
IF TUS=41 THEN  satırından önce;
For I=0 to 31 
WRITE (0+I),DATA_AL(I)
NEXT
PAUSE 10
şeklinde kod eklemesi yapıp programı çalıştırıp bir tuş kaydı alman.
Ardından başka bir şey yapmadan devreyi durdurup işlemciyi programlayıcıya takıp 0-31 arası adres değerlerini bir yere yazman ve mümkünse buraya o değerleri koyman yeterli olacaktır.

Programın bu hali ile çalışması gerekir. Çalışmaz ve süre kayıtları çok fazla değişiklik arzederse o zaman o sürelerin küsüratlarını atmamızı sağlayan şu komutu kullanmamızı önereceğim.
PULSIN DATA_GIRIS,1,TAMAM:TEMP=NCD(TAMAM)
NCD komutu o sayının en yüksek değerlikli bitini bulur ve TEMP değişkenine (Byte cinsinden) eşitler. Örnek vermek gerekirse diyelimki PULSIN 4500us lik süreyi okudu ve TAMAM=450 buldu. TEMP=NCD(450)=9 olacaktır.
Süre değerlerinde ise Uzun Süre değerimiz 189 olacak ve bunun NCD karşılığı ise 8 olacaktır.
Bu yazdıklarımı bir düşün ve yağpmaya çalış yapamadığını tekrar sor açıklayayım.

Ete

Programı çalışır hale getirdikten sonra başka alternatifler deneyeceğiz. Bu hali ile puls süreleri

blueboard

Ete hocam, günaydın. Gerçek devrede harici kristal kullanmış idim. Kullandığınız Proteus'un versiyonunu yazarsanız şemamı da sizin proteus'a uygun olarak çizerek ekleyeceğim.

ete

#6
Yukarıda verdiğin  programı yeniden düzenledim.
Bir kere daha denermisin lütfen.
Buda olmuyor ise okunan bilgileri kayıt ettirip ne kayıt ediliyor bakmak gerekir.

Ete

Edit: Yukardaki programı yeniden düzenledim. Ufak bir hata varmış.
Devreyi simule ettim ben uğraşmana gerek yok. Çalışıyor.
Son haline şimdi yeniden bak lütfen.

blueboard

Ete Hocam , iyi akşamlar. Son yazılımınızı yükledim.Ancak hem gerçek devrede hem de isis'te  yine çalışmadı. Simule ettiğiniz isis dosyalarını gönderebilir misiniz. Ben de benim bilgisayarımda simule edeyim. Veya benim bilgisayarımda Proteus'un 8.5 versiyonu ile çizmiş olduğum alıcı ve verici isis devresini göndereyim.( Verici devresinin hem isis çizimini , hem de kontrol datalarını gönderen pbp dosyasını gönderebilirim. Vericinin de gerçek devresini yaptım. Verici dataları doğru çıkıyor.)  Siz kontrol edin.
Eğer Proteus versiyonunun benim 8.5'ten üst versiyon ise sorun olmaz. Bilgisayarıma sizin versiyonu da yükleyebilirim. Versiyonu bildirmeniz yeterli olacaktır.

ete

Simulede 8.17 kullanıyorum.
Daha önceden nec protokolünü denediğim bir şemayı senin sistemine adapte ederek kullandım.
Dosyalar ilişiktedir.

Ete

blueboard

#9
Ete hocam,sanırım sorunun kaynağını buldum. Sizin simulasyonunuzda verici devreden hiç bir butona basmıyorken sürekli low çıkıyor. Butona basılınca 9 ms high ve ardından 4,5 ms low ve komut bitleri geliyor. Komut bitleri sonlanınca çıkış yine sürekli low'da kalıyor. Oysa benim verici devrede durum bunun tam tersi.Benim  devreden hiç bir butona basmıyorken sürekli high çıkıyor. Butona basılınca 9 ms low ve ardından 4,5 ms high ve komut bitleri geliyor. Komut bitleri sonlanınca çıkış yine sürekli high'ta kalıyor.
Sizin gönderdiğiniz verici simulasyon devresini kendi yazdığım verici kodları uyarladım. Farkı gösteren sizin verici devresi ile benim verici devresinin çıkışlarındaki farkın daha net görülebilmesi için ikisini ekteki resimde birleştirdim. Benim verici devresinin çıkışına transistör ile tersleme yapılmamıştır. Devreden çıktığı gibidir.Uygun bir zamanda kontrol edebilir misiniz.


ete

#10
Bu tespitin bir sorun değil aslında. Program sürekli olarak düşen kenar kesmesi bekliyor.
Düşen kenarda kesmeye girip orada HIGH bitinin süresini ölçmek için bekliyor. Dikkat edersen her düşen kenar bir LOW sinyale tekabül eder. Ama bu LOW un ardından bir HIGH sinyali gelir ve bizde bu sinyali önce buluyor sonra süresini ölçüyoruz. Bana göre devrenin sinyalsiz hali sürekli LOW yada HIGH olması bir şeyi değiştirmez. Ancak yinede senin sinyal şekline uygun hale getirip o şekilde denemekte yarar görüyorum. Bakacağım.
Şunuda belirteyim hemen, benim devrede IR göz bulunuyor ve sinyal sanki IR sinyali imiş gibi yollanıyor. IR_Göz aldığı sinyali ters çeviriyor ve sinyal şeklini senin sinyal şekli ile aynı hale getiriyor. sonuçta sinyalin şekli önemli burada nerden nasıl geldiği önemli değil. Anlayacağın tamamen senin sinyal ile aynı olan bir sinyali çözdürüyorum ben.


Ete

ete

#11
Asıl sorunu ben anladım galiba. Senin sistemin önce cihaz bilgisini veriyor ardından tus bilgisi dediğimiz asıl bilgiyi veriyor ama o bilginin son biti gerektiği gibi sonlandırılmıyor.
Bu son verdiğin resime bakarsan senin bilginde en son bit bir HIGH biti kod değeri 1 ise orada 1860us lik bir HIGH olması gerekiyor kod değeri "0" ise orada 560us lik bir HIGH palsi olması gerekiyor. Ama sinyaline bakarsan orada sürekli devam eden bir HIGH görüyorsun. Kısaca son bitin HIGH kısmı sinyalin boşta verilen HIGH ile birleşerek o bitin çözülmesi imkansız hale geliyor.
Çünki PULSIN komutu çok uzun gelen HIGH bitini süre olarak ölçemiyor.

Bu durumu değiştirmek yada bir şekilde düzeltmek mümkün değil ise yapılacak tek şey 8 bitlik bilginin 7 bitini kullanmak olur. Yada en güzel orada yalnızca 7 bitlik bilgi almak en doğrusu olacaktır.
Örnek vermek gerekir ise , gelen bilgi 41 olduğunu varsayalım (%0010 1001) bunun %x0101001 kısmını kullanacağız. Böylece 41 geldiğinde yine 41 almış olacağız (41 AND 127 işlemi), 161 geldiğinde ise 33 almış olacağız. (161 AND 127 işlemi) 17 geldiğinde yine 17 almış olacağız.
Programı bu mantığa göre yeniden düzenledim. Sistemi hızlandırmak açısından işlemciyi 16Mhz de çalıştırdım. Şimdi kod çözme daha hızlı çalışıyor.

Ete

Edit: Bu sistemde bir sorun olsa gerek. Hiç bir haberleşme sisteminde son bit HIGH ile bitiyor ise sistemin boşta bekleme şekli HIGH olmamalı. Olursa da son bitin HIGH palsi bir şekilde LOW sinyali anlık da olsa (1us-2us gibi) verilerek bit sonlandırılmalı sonrasında sistemin boşta bekleme lojik seviyesine geçilmelidir. Aksi halde bu gibi sorunların olması kaçınılmaz olur.
Son bitin bitiriliş şekline bakmak benim bile aklıma gelmemiş idi. Ancak sistemi senin istediğin şekle yada senin sisteminin çalışma şekline sokunca 2. tuş olan 161 yollanınca alınan bilginin sürekli olarak 33 olması beni detaylı araştırmaya sevk etti. 33 ün 2li sistem değerine bakınca 161 in 7ci bitin 1 olduğunu 33 de ise 7 ci bitin0 olduğunu görünce uyandım. Demekki sistem son biti doğru şekilde alamıyor dedim ve o bite bakınca boşta bekleme sinyali ile birleştiğini görerek durumu anlamış oldum.

Powered by EzPortal