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