programım hakkında yardıma ihtiyacım var

Başlatan metonbeyy, 29 Temmuz 2023, 15:13:22

metonbeyy

Merhabalar ben aranıza yeni katıldım. Pic programlamayı en son lisede görmüştüm tekrardan merak sardım fakat takıldığım konular oldu yardımcı olabilirseniz sevinirim. Şöyle özetleyeyim pic ile standart araclarda olan far, sinyal gibi şeyleri yakmak ve hız okuyup ekrana yazmak istiyorum projemin ilk ayağı olan aydınlatma kısmını yaptım fakat sinyal verirken farı yakmak istediğimde pic tepki vermiyor sorunu çözemedim. bu sorundan sonra hızı sensör ile okuyup ekrana yazmak istiyorum yardımcı olabilirseniz sevinirim. Yazdığım kodu bırakıyorum. İyi çalışmalar.

@  __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
    CMCON=%111  '7
  VRCON=0
 
  TRISA=%11111111
  TRISB=%00000000
         
  PORTA=0
  PORTB=0
  K VAR WORD
  SYMBOL FAR =PORTB.0
  SYMBOL UZUNFAR = PORTB.1
  SYMBOL SINYALSAG = PORTB.3
  SYMBOL SINYALSOL = PORTB.2
  SYMBOL BUTON = PORTA.6
  SYMBOL BUTONA = PORTA.7
  SYMBOL SOLBUTON = PORTA.4
  SYMBOL SAGBUTON = PORTA.3
BASLA:
     
  UZUNYAK:
  IF UZUNFAR = 0 AND BUTONA = 0 THEN
  PAUSE 900
  UZUNFAR=1
  ENDIF 
  GOTO UZUNSONDUR
  UZUNSONDUR:
  IF UZUNFAR = 1 AND BUTONA = 0 THEN
  PAUSE 900 
  UZUNFAR = 0
  ENDIF
 
  FARYAK:
  IF FAR = 0 AND BUTON = 0 THEN
  PAUSE 900
  FAR=1
  ENDIF 
  GOTO FARSONDUR
  FARSONDUR:
  IF FAR = 1 AND BUTON = 0 THEN
  PAUSE 900 
  FAR = 0
  UZUNFAR = 0
  ENDIF
 
 
   
  SOLSINYALYAK:
  IF SOLBUTON = 0 AND SINYALSOL= 0 THEN
  FOR K = 1 TO 10
  SINYALSOL=1
  PAUSE 500
  SINYALSOL =0
  PAUSE 500
  IF K = 5 THEN
  SINYALSOL=0
  ENDIF
  NEXT K
  ENDIF
  SAGSINYALYAK:
  IF SAGBUTON= 0 AND SINYALSAG = 0 THEN
  FOR K = 1 TO 10
  SINYALSAG = 1
  PAUSE 500
  SINYALSAG =0
  PAUSE 500
  IF K = 5THEN
  SINYALSAG=0
  ENDIF
  NEXT K
  ENDIF
SELEKTOR:
IF FAR = 0 AND BUTONA= 0 THEN
UZUNFAR= 1
ENDIF
  GOTO BASLA
 

elektro77

#1
Program koşturucu pause komutlarında beklerken başka komutları işlemez. Benim tek ve kısaca söyleyebileceğim pause komularından kurtulman olacaktır. İşin püf noktası bu...
Bunu yapmak için Delay isimli bir alt program kurmalısın. Orada gerekli gecikmeleri yaratıp return ile kaldığın yere dönmelisin. Aşağıya bir örnek bırakıyorum. Biraz daha alıştırma ve örnekler yapmalısın.
Başla:
UZUNYAK: 'bunlara gerek yok kaldır.
   IF UZUNFAR = 0 AND BUTONA = 0 THEN
gosub delay  'pause olan yerlere gosub delay kullanıp delaya gitmelisin
   UZUNFAR=1
   ENDIF
   GOTO UZUNSONDUR 'bunlara gerek yok kaldır.
   UZUNSONDUR: 'bunlara gerek yok kaldır.
   IF UZUNFAR = 1 AND BUTONA = 0 THEN
gosub delay   
   UZUNFAR = 0
   ENDIF
Goto başla
'---------------------------------Alt programlar--------------------------
DELAY:
FOR I=0 TO 500
NEXT
RETURN
ete Hocam daha ayrıntılı şekilde anlatacaktır.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

aRci

bendende bir örnek olsun
ilk olarak butonlar için portb yi kullanın pullup dirençlere sahip. buna göre bir örnek yaptım. sizde alt satırlara gitmek için goto komutu kullanmışsınız buna ihtiyaç yok program yukardan aşşağıya doğru akar ve karşısına giden satırları eğer IF benzeri sorgularla bölünmemişse her satırı tek tek işler.

@ __config _BODEN_OFF  & _PWRTE_ON & _WDT_ON & _LVP_OFF & _HS_OSC
    Define OSC 20
    cmcon = 7
    OPTION_REG   = %01000110  'Pull  up dirençleri(7) aktif(0)- Bölme oranı 1/128.
   
    porta       = %00000000
    portb       = %00000000
   
    trisa       = %00000000
    trisb       = %00001111
   
    SYMBOL FAR        = PORTA.0
    SYMBOL UZUNFAR    = PORTA.1
    SYMBOL SINYALSAG  = PORTA.2
    SYMBOL SINYALSOL  = PORTA.3
    SYMBOL BUTON      = PORTB.0
    SYMBOL BUTONA     = PORTB.1
    SYMBOL SOLBUTON   = PORTB.2
    SYMBOL SAGBUTON   = PORTB.3
Basla:
    if ButonA = 0 and Buton != 0 then
         high UZUNFAR
    else
         Low UZUNFAR
    endif
   
    if Buton = 0 and ButonA != 0 then
         high FAR
    else
         Low FAR
    endif
   
    if SAGBUTON = 0 and SolBUTON != 0 then
         toggle  SINYALSAG
    else
         low SINYALSAG
    endif
   
    if SolBUTON = 0 and SAGBUTON != 0then
         toggle  SINYALSol
    else
         low SINYALSol
    endif
 
    pause 500
goto basla

ete

#3
Programda bazı kusur sayılabilecek satırlar veya mantık var. Eksiklerde var.
Sırası ile açıklıyorum.

1. Her programda başlangıç aşamasında register ve değişken tanımlamaları yapıldıktan sonra bunların işlemci içinde ayarlanması için en azından 150-200 ms lik bir gecikme eklemeniz gerekir. Bunu yapmazsanız değişkenleriniz yada registerler rastgele değerler alabilir.
Bu nedenle BASLA etiketinden önce ;
PAUSE 200 eklemeniz gerekir programa.

2. Doğru bir buton kontrolünde butonun basıldığı test edilip gereken yapıldıktan sonra aynı butonun bırakılıp bırakılmadığıda kontrol edilmelidir. Aksi taktirde program çok hızlı çalışacağı için aynı satırlara senbutonu bırakıncaya kadar yüzlerce defa gelir ve yapacağını yapar. Sen bu işi pause ile çözmeye çalışmışsın ki buda programın işleyişini engeller.
Doğru buton kontrolü aşağıdaki gibi olmalı idi.
IF UZUNFAR=0 AND BUTONA=0 THEN  'butona basılmışmı test ediyoruz.  
        UZUNFAR=1                     'basılmış ve UzunFar=1 yaparak farı yakıyoruz.
        while BUTONA=0:WEND           'butonu bırakılıncaya kadar bekliyoruz burada
        PAUSE 100                     'tuş titremesini engellemek için 100ms gecikme ekliyoruz. 
       ENDIF

3. Şayet uzun farın yakılma işlemi bir selektör yapma işi ise tuşu bıraktığın anda farın sönmesi gerekir. Ama anahtardan kontrol edilen bir far yakma ise far yanmaya devam etmeli ve anahtarı tekrar kapatmak gerekir. Şayet selektör yapma gibi bir niyetimiz var ise program kodu şöyle olabilirdi.
IF UZUNFAR=0 AND BUTONA=0 THEN  'butona basılmışmı test ediyoruz.  
        UZUNFAR=1                     'basılmış ve UzunFar=1 yaparak farı yakıyoruz.
        while BUTONA=0:WEND           'butonu bırakılıncaya kadar bekliyoruz burada
        PAUSE 100                     'tuş titremesini engellemek için 100ms gecikme ekliyoruz. 
        UZUNFAR=0           
       ENDIF

Arci nin metodunda ise anahtar kapalı ise far yanar açık ise söner mantığı uygulanmış.Ama o da şöyle olmalıydı
IF UZUNFAR=0 AND BUTONA=0 THEN  'butona basılmışmı test ediyoruz.  
        UZUNFAR=1                     'basılmış ve UzunFar=1 yaparak farı yakıyoruz.
        while BUTONA=0:WEND           'butonu bırakılıncaya kadar bekliyoruz burada
        PAUSE 100                     'tuş titremesini engellemek için 100ms gecikme ekliyoruz.
        ELSE
        UZUNFAR=0                     'BUTONA basılı değil ise UZUNFAR sönecek.          
       ENDIF

4. Basic programları satır takip eder.
  GOTO UZUNSONDUR
  UZUNSONDUR:
şeklinde yazılmış bir satır hata vermez ama lüzumsuz ifadeler içeriyor. Oraya GOTO UZUNSONDUR yazmasan program zaten satır takıp ettiği için UZUNSONDUR etiketine gelecektir. Dolayısıyla GOTO... satırı lüzumsuzdur silinmesi daha doğru olur.

5. Tuş kontrolleri içerisinde PAUSE 900 gibi çok uzun (işlemci açısından çok uzun) gecikmeler yer alıyor. Program işlerken bu gecikmeler bitmeden bir sonraki komuta yada satıra geçmeyecektir. Bu nedenle daha akıllı algoritmalar düşünmek gerekir.
Örneğin. Sinyal verdirme meselesinde tek bir sinyal verdirme işlemi 10 sn sürmektedir. Bu işlem bitmeden sen başka bir emir versen bile program onu görmeyecektir.
Bu programı şöyle yazarsak hiç bir şey gecikmeden etkilenmezdi.
- 500 ms lik TMR1 sayacı kur. Sayac sıfırdan başlayıp 500ms doluncaya kadar olan döngü içinde bütün butonları kontrol edersek ve 500ms sonunda şayet bir sinyal aktif edilmiş ise o sinyale TOGGLE işlemi uygularsak sinyal her 500ms de bir yanıp söner. Aynı anda 4 lü sinyalleri bile çalıştırabilirsin. Hemde o 500 ms lik süre içinde bütün butonları da kontrol etmiş olursun.
İyi program bu şekilde olur. Hiç bir gecikme diğer basılan tuşu algılamamı engellememelidir.
Bu konu üzerinde biraz daha derin çalışabiliriz.

Madem bu işte yenisin adım adım ilerleyerek işi öğrenebilirsin. Program bir hayal ürünüdür. Sistemin nasıl çalışacağını önce hayal etmen gerekirse kağıda program adımlarını yazman gerekir. Buna program senaryosu diyoruz. Senaryonun her şeyi tam kontrol ettiğinden emin oluncaya kadar programı yazmaya başlama ve kafanda her şey netleştikten sonra yazmaya başla.

Şimdi bu açıklamalarıma uygun kodlarını yeniden düzenle bakalım bir sonuç alacakmısın. Sorun devam ediyor ise yeniden yazdıklarını buraya koy tekrar üzerinde tartışalım.

Ete

ete

Yapmak istediklerini yapacağını düşündüğüm aşağıdaki programı önce biraz incele sonrada hazır devren var ise denemeye çalış bakalım.
İstediklerinden yalnızca SELECTOR kısmı bu kod içinde eksik. Selektör işi ayrı bir butonla yapılmalıdır. Araçlarda da böyledir.
Verdiğim örnek aşağı yukarı yukarıda açıkladıklarımla eşleşmektedir. Bazı farklılıklar var. Mesela tuşun bırakıldığını anlamak için while-wend döngüsü sonrasına pause 100 eklemedim. Çünki kodun kendisi zaten bir zaman döngüsü içinde çalışıyor.

Ete

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [ETE]                                             *
'*  Notice  : Copyright (c) 2023 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 30.07.2023                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
  CMCON=7
  VRCON=0
 
  TRISA=%11111111
  TRISB=%00000000
         
  PORTA=0
  PORTB=0
  K VAR WORD
  SINYAL_LEFT VAR BIT
  SINYAL_RIGHT VAR BIT
 
  SYMBOL FAR =PORTB.0
  SYMBOL UZUNFAR = PORTB.1
  SYMBOL SINYALSAG = PORTB.3
  SYMBOL SINYALSOL = PORTB.2
  SYMBOL BUTON = PORTA.6
  SYMBOL BUTONA = PORTA.7
  SYMBOL SOLBUTON = PORTA.4
  SYMBOL SAGBUTON = PORTA.3
pause 500
    T1CON=%00110001
BASLA:
     
      TMR1H=$0B:TMR1L=$DC:PIR1.0=0 'HER KESME 500ms
      WHILE PIR1.0=0
        IF BUTONA = 0 THEN
           TOGGLE UZUNFAR
           WHILE BUTONA=0:WEND           
        ENDIF
 
        IF BUTON = 0 THEN
           TOGGLE FAR
           WHILE BUTON=0:WEND
        ENDIF
       
        IF SOLBUTON = 0  THEN   
            TOGGLE SINYAL_LEFT
            WHILE SOLBUTON=0:WEND
        ENDIF     
                 
        IF SAGBUTON = 0 THEN   
            TOGGLE SINYAL_RIGHT
            WHILE SAGBUTON=0:WEND
        ENDIF 
      WEND
      IF SINYAL_LEFT=1 THEN
        TOGGLE SINYALSOL               
      ELSE
        SINYALSOL=0
      ENDIF
       
      IF SINYAL_RIGHT=1 THEN
         TOGGLE SINYALSAG
      ELSE
         SINYALSAG=0
      ENDIF
      GOTO BASLA       
     

ete

#5
Selektör işleminde farklı bir mantık yürütür isek;
ButonA ya bastığımızda FAR yanıyor ise uzunları yakacağız demektir. O halde uzunları yakalım.
Tekrar bastığımızda ise yine far yanıyor ise ve uzunlar yanıyor ise uzunlar sönecek demektir.
Far yanmıyor ise uzun far selektör yapacağız demektir ve buton basılı olduğu sürece uzun far yanacak ama butonu bırakınca uzun far sönecektir.

Bu mantığı sadece BUTONA kontrolüne uygulayacağız. Uygulanmış hali aşağıdadır.

Ete

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF         
    
  CMCON=7 '7
  VRCON=0
 
  TRISA=%11111111
  TRISB=%00000000
         
  PORTA=0
  PORTB=0
  K VAR WORD
  SINYAL_LEFT VAR BIT
  SINYAL_RIGHT VAR BIT
 
  SYMBOL FAR =PORTB.0
  SYMBOL UZUNFAR = PORTB.1
  SYMBOL SINYALSAG = PORTB.3
  SYMBOL SINYALSOL = PORTB.2
  SYMBOL BUTON = PORTA.6
  SYMBOL BUTONA = PORTA.7
  SYMBOL SOLBUTON = PORTA.4
  SYMBOL SAGBUTON = PORTA.3
pause 500
    T1CON=%00110001
BASLA:
     
      TMR1H=$0B:TMR1L=$DC:PIR1.0=0 'HER KESME 500ms
      WHILE PIR1.0=0
        IF BUTONA = 0 THEN
           IF FAR=1 THEN
             TOGGLE UZUNFAR
             WHILE BUTONA=0:WEND          
           ELSE
             UZUNFAR=1
             WHILE BUTONA=0:WEND
             UZUNFAR=0
           ENDIF
        ENDIF
 
        IF BUTON = 0 THEN
           TOGGLE FAR
           WHILE BUTON=0:WEND
        ENDIF
       
        IF SOLBUTON = 0  THEN  
            TOGGLE SINYAL_LEFT
            WHILE SOLBUTON=0:WEND
        ENDIF    
                
        IF SAGBUTON = 0 THEN  
            TOGGLE SINYAL_RIGHT
            WHILE SAGBUTON=0:WEND
        ENDIF 
      WEND
      IF SINYAL_LEFT=1 THEN
        TOGGLE SINYALSOL               
      ELSE
        SINYALSOL=0
      ENDIF
       
      IF SINYAL_RIGHT=1 THEN
         TOGGLE SINYALSAG
      ELSE
         SINYALSAG=0
      ENDIF
      GOTO BASLA   

metonbeyy

Ete hocam yazılarınızı okudum fakat şehirler arası yolculuktaydım en kısa sürede dediklerinizi deneyeceğim dediğim gibi daha işin çok başındayım sizlerin yaptığı projeleri inceledikçe bende de bir şeyler yapma isteği doğuyor yardımlarınız için çok teşekkür ederim yaşadığım sıkıntıları sizlerle paylaşmak bile beni sevindiriyor teşekkür ederim iyilikler dilerim

Powered by EzPortal