avatar_elektro77

Bir Cihazda Çocuk Kilidi Uygulaması

Başlatan elektro77, 08 Ekim 2022, 15:04:42

elektro77

Ete Hocam ekteki projemde bir buton ve 3 led var. Simülasyondaki ekran sadece değerleri görme amaçlı.
Aşağıdaki şartların çoğunu sağlıyorum ama çözemediğim birkaç sorunum var.
Yazılımın en alt satırlarında da bulunan Şartlar şunlar:
1-Butona 500mS gibi bir hızla 4 kere basıp bırakınca, "onoff" pini low dan hıgh a geçecek. Cihaz açılmış oldu. Burada sadece 4. basmada  pildeki gerilime göre yanması gereken ledler yanar ve söner
2-Butona yine 4 kere hızlıca basınca  cihaz kapanacak ve onoff  low a düşecek. Burada ilk 3 basmada pildeki gerilime göre yanması gereken ledler yanar ve 4.basmada  hiçbir led yanmaz . Cihaz kapanmış oldu.
Butona yanlış sayıda veya 500mS gibi aralıklarda basılamadığı sürece durum değişmeyecek. (cihaz açık konumda iken her yanlışta, aşağıda belirtilen "out" pininin high olmasında sorun yok. High Olmalı da).
3-Cihaz açık iken butona  basınca "out" pini high olacak, butonu bırakıncaya kadar hıgh ta bekleyecek ve butonu bırakınca low olacak.
4-out pini hıgta olduğu sürece adc bakacak ve pil 4.2V ta iken 3 ledi birden, 4 voltta iken 2 ledi, 3.8V ta iken 1 led yakacak.
Pil gerilimi 3.8 ten küçük ise out pinini high yapmayacak ve tek led blink yapacak.
5-sarj pini bilgisi lojik 1 yapıldığında pildeki gerilime göre sıra ile yanıp sönecek. pilde 3.8 volt varsa tüm ledler sıra ile yanıp sönecek.
pilde 4 volt varsa 1.led yanık kalacak ve diğer 2 led sıra ile yanıp sönecek.
Pilde 4.1 volt var ise 2 led yanık kalacak ve tek led yanıp sönecek-
pilde 4.2 volt varsa tüm ledler yanık bekleyecek.
Şarj pini lojik 0 yapıldığında tüm ledler sönecek. 

sağlayamadığım şartlar ise şunlar:
1- İlk açılışta ki 4 tuş zaman şartını ayarlayamıyorum. Fakat kapatmada sorun yok.
2- Kodlarda bulunan, Tus=0 ise while:wend  döngüsünden gerektiği şekilde çıkamıyorum. Bu nedenle adc okuma sorunu oluyor.
3- Şarj şartlarındaki ledlerin aktif olma sürekliliğini sağlayamıyorum.
Yardımcı olursanız sevinirim.
Projem Ektedir:
"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"

ete

Bütün senaryoyu vermişsin ama zaten karmaşık bir konu bir kaç sefer okuma ile olaya vakıf olmak zor.
Bu nedenle yanlzıca yapamadıklarına odaklanacağım.
"1- İlk açılışta ki 4 tuş zaman şartını ayarlayamıyorum. Fakat kapatmada sorun yok."
zaman aralığı olarak 500ms koymuşsun. Bu süreden daha kısa sürede tuşa basılırsa hiç bir işlem yapılmadan çıkılması gerekecek. Ama 500ms aşılırsa sorun olmamalı aksi halde tam tamına 500ms sonra tuşa basmayı tutturmak deveye hendek atlatmaktan daha zor olacaktır.
Tuş kontrolü bir while wend döngüsü içinde yapılırken aynı zamanda bir sayaç çalışmalıdır.500 ms den kısa sürede tuş basılırsa çıkışa gidilip işlem iptal edilmeli. Ama sayac değeri içinde bir limit koyulup o limite ulaşıldığında while:wend döngüsünden çıkılmalı.
ZAMAN=0
WHILE TUS=1 'henüz tuşa basılmamış ise
ZAMAN=ZAMAN+1
IF ZAMAN=1000 THEN RETURN (Süre doldu ama tuşa basılmadı geriye dönülecek yada tekrar döngüye girilecek sen karar ver ne yapacağına)
PAUSE 1
WEND
Program bu satıra gelirse tuşa kısa sürede basılmış demek olacak ve buraya işlemi iptal edecek kod yazılacak. 

"2- Kodlarda bulunan, Tus=0 ise while:wend  döngüsünden gerektiği şekilde çıkamıyorum. Bu nedenle adc okuma sorunu oluyor."
Bu sorunun cevabını aslında yukarıdaki döngü içinde verdim. Döngüden çıkmanın yolu belirli bir şarta bağlı olmalı. Ya zaman sayacı değerine ya tuşun değerine yada bir başka sebebe dayandırılabilir.

"3- Şarj şartlarındaki ledlerin aktif olma sürekliliğini sağlayamıyorum."
bu tür sorunlar pause ile halledilemez. Tek bir zaman sayacın olmalı mesela TIMER-1 sayacını 100 veya 200ms ye kuracaksın süre bitiminde kim aktif olacak ise TOGGLE yaparsın. Bu ileri program tekniklerinden birisidir. Bütün programı 100-150 ms lik bir döngü içinde çalıştırırsan döngü sonunda ;
IF HAM<757 then AKTIF.0=1 
IF AKTIF.0=1 THEN TOGGLE LED3
Şeklinde kolaylıkla halledilir.
Programlarınızı süreli döngüler içinde çalıştırmayı her zaman planlayın. Bu sayede hem süreli işleri kolaylıkla halledersiniz hem led flash işlerini halledersiniz.

Umarım anlaşılmıştır açıklamalarım.

Ete

elektro77

#2
Timer1 hariç anladım hocam. Teşekkür ederim.
Aslında birde her tusta 500mS aşılırsa bir şey yapılmaması gerekiyor.
"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"

ete

Bir program düşün. BASLA etiketi ile başlıyor çalışmaya ve bir sürü iş yaptıktan sonra en altta GOTO BASLA etiketini görüp en başa dönüyor ve aynı şeyleri yeniden yapmaya başlıyor. BASLA ile Goto Basla arasına biz bir program döngüsü diyoruz.
Şimdi aynı programı BASLA etiketinden hemen sonra Timer-1 sayacını 100 veya led flash etkisi açısından 150 ms lik bir süre için kurarak çalıştırsak ve 150 ms doluncaya kadar program aynı işleri sanki Basla-GotoBAsla arasında çalışıyorrmuşçasına tekrarlayacaktır.
BASLA:
T1CON=%00110001
BASLA_BIR:
TMR1H=$B6:TMR1L=$C2:PIR1.0=0
WHILE PIR1.0=0
  buraya bütün programı koy yada belirli bir aşamadan sonraki program parçasını koy
WEND
program buraya geldiğinde 150 ms dolmuş olacak.
İşte burada ledleri varsa buzzeri şayet aktif iseler toggle yapacaksın.
GOTO BASLA_BIR
Bütün olay bu işte. Bakledler için ekstra bir zaman gecikmesi kullanmadan hem program çalışıp işini yaptı hemde ledleri flash yaptırmış oldum.

Ete

elektro77

Bütün programlarimizi timer1 gibi süreli döngüler içinde kurmayı onerdiginizi anladım. Peki bu Timerlarin genel kuralları nedir? Nelere dikkat etmeliyiz. Çünkü bir kaç projemi de bu şekilde değiştirmeyi düşünüyorum.
"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"

ete

Adı üzerine Timer yani zamanlayıcı. Dikkat edilecek bir kaç noktası var. Bunlar;
- Programda başka yerde ayrıca aynı timer'ı kullanmamalısın. Yoksa işler karışır.
- Bir ön yükleme değeri vardır. Bu kurmayı düşündüğün zaman dilimine göre değişir.
  Picmulticalc.exe programında ikinci seçenek olan Timer Helper seçeneğinde osc frekansını seçip istediğin zaman dilimini girdiğinde sana aşağıda olası seçenekleri verir. Bu seçenkler bir yandan ön yükleme değerine bağlı iken diğer yandan da bölme oranınada bağlıdır. Ben genelde 1/8 kullanıyorum zaten bu kullanabileceğin maksimum bölme oranıdır. Örneğide bu değer üzerinden verdim.
Oradaki önyükleme değerini HEX e çevirip (hesap makinesi ile) soldaki iki bit TMR1H ve sağdaki iki bit de TMR1L değerin olacaktır. Bunları ver yazmaçlarına.
- Kontrol mekanizması Timer-1 in 65535 değerini aşıp kesme oluşturmasına dayanıyor. Kesme oluştuğu anda PIR1.0 biti HIGH oluyor. Böylece seçilen zamanın dolduğunu bu bitden anlıyorsun.
While PIR1.0=0 döngüsünü kurduktan sonra bu bit 1 oluncaya kadar WEND komutuna kadar olanlar sürekli tekrarlanıyor. Bir nevi BASLA-GOTO BASLA aralığını çalıştırmak gibi.
Hepsi bu kadar
Ete

elektro77

Hocam ilk enerjilendirme işini az çok becerdim ama tam değil.
İkincisi ise timer 1 döngüsünden sonrasını hala beceremedim. Vaktiniz varsa bakabilir misiniz lütfen?
Son kodlar aşağıdadır:
#config
 __Config _HS_OSC  &  _WDT_OFF &_PWRTE_OFF &_BODEN_OFF &_CP_ON &_CPD_OFF &_LVP_OFF 
#ENDCONFIG
'------------------
define OSC 8
'ADCON1=7              'ADC KANALLARI DİJİTAL YAPILDI - ADC İPTAL
ADCON1=%10000010      '1 KANAL ADC AKTİF EDİLDİ.
CMCON=7               'komparatör pinleri iptal hepsi giriş çıkış yapıldı.
OPTION_REG.7=1        'portB deki dahili PULL-UP lar AKTİF edildi. OPTION_REG.7=1 İSE PULLUPLAR PASİF
'------------------
 TRISA=%00000001      'ADC OKUNACAK PİNLER GİRİŞ YAPILDI
 TRISB=%10000001      
 TRISC=%00000000      
 PORTA=%00000000
 PORTB=%00000000
 PORTC=%00000000
'-------------------------
'-------------------
DEFINE LCD_DREG		PORTC	
DEFINE LCD_DBIT		0		
DEFINE LCD_RSREG	PORTC	
DEFINE LCD_RSBIT	5	
DEFINE LCD_EREG		PORTC	
DEFINE LCD_EBIT		4		
DEFINE LCD_BITS		4	
DEFINE LCD_LINES	4
DEFINE LCD_COMMANDUS   2000     
DEFINE LCD_DATAUS      50       
'-------------------------------------------------------------------------------
DEFINE ADC_BITS        10       'A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK       5        'Clock kaynağı (5=FOSC/16)
DEFINE ADC_SAMPLEUS    20       'Örnekleme zamanı mikro saniye cinsinden.
'DEFINE ADC_BITS 10     ' ADCIN resolution  (Bits)
'DEFINE ADC_CLOCK 5     ' ADC clock source  (Fosc/16)
'DEFINE ADC_SAMPLEUS 11 ' ADC sampling time (uSec)
'------------------------------------------------------------------------------
I VAR BYTE
SAYAC VAR byte
SURE  VAR WORD
X     VAR BIT :x=0
DEGER VAR WORD   'İZİN VERİLEN TUSA BASMAMA SÜRESİ
HAM   VAR WORD
P     VAR WORD

SYMBOL tus  =portB.0
SYMBOL LED1 =portB.1    
SYMBOL LED2 =portB.2   
SYMBOL LED3 =portB.3   
SYMBOL ONOFF=portB.4
SYMBOL OUT  =portB.5 'PWM ÇIKIŞI OLACAK
SYMBOL SARJ =portB.7

CLEAR
lcdout $FE,1  
PAUSE 200
'******************************************************************************* 
'IF HAM<757 then AKTIF.0=1 
'IF AKTIF.0=1 THEN TOGGLE LED3

BASLA:

DEGER=1000    'İZİN VERİLEN TUSA BASMAMA SÜRESİ AYARI (YAKLAŞIK 500mS)
ADCIN 0,HAM
GOSUB EKRAN

''------------------------CİHAZI İLK AÇMA BÖLÜMÜ---------------------------------
  IF TUS=1 THEN
     
   WHILE TUS=1:WEND
      SAYAC=SAYAC+1
          
      IF SAYAC=4 THEN
              ADCIN 0,HAM
                         IF HAM>820 THEN  'ADC 4.0V tan büyükse 3 ledi birden yakar
                            LED1=1:LED2=1:LED3=1
                         ENDIF
                         IF HAM<820 AND HAM>778 THEN  'ADC 4.0V ve 3.8V arasında ise 2 ledi yakar
                            LED2=1:LED3=1
                         ENDIF
                         IF HAM<778 THEN    'ADC 3.8V tan küçükse 1 ledi yakar
                            LED3=1
                         ENDIF
                         IF HAM<778 and ham>757 THEN    'ADC 3.8V ve 3.7V arasında ise 1 ledi yakar
                            LED3=1
                         ENDIF
                         IF HAM<757 THEN    'ADC 3.7V tan küçükse 1 ledi blink yapar ve out vermez
                            LED3=1:pause 100:led3=0:pause 100
                            LED3=1:pause 100:led3=0:pause 100
                            LED3=1:pause 100:led3=0:pause 100
                            LED3=1:pause 100:led3=0:pause 100
                         ENDIF
     
       
      ONOFF=1
      PAUSE 200:LED1=0:LED2=0:LED3=0
      GOTO BASLA1
      ENDIF
         
  ENDIF

'-------------İLK AÇILIŞ BUTON ZAMANLAMA DOĞRULAMASI----------------------------
    IF TUS=0 THEN  'henüz tuşa basılmamış ise
    WHILE TUS=0
       SURE=SURE+1:PAUSE 1
         IF SURE>DEGER THEN  '(Süre doldu ama tuşa basılmadı geriye dönülecek yada tekrar döngüye girilecek sen karar ver ne yapacağına)
            
            lcdout $FE,$C0,"SURE  :",#SURE  ,"   "
            SAYAC=0
            GOSUB DURUM0
             'GOTO BASLA
         ENDIF
    WEND
'Program bu satıra gelirse tuşa kısa sürede basılmış demek olacak ve buraya işlemi iptal edecek kod yazılacak.
IF TUS=0 THEN SURE=0:SAYAC=0:GOSUB EKRAN':GOSUB DURUM0
    ENDIF


GOTO BASLA

DURUM0:
SAYAC=0
SURE=0
lcdout $FE,$C0,"SURE  :",#SURE  ,"   "
LCDOUT $FE,$90,"SAYAC :",#sayac,"    "
RETURN

'----------------OUT VERMEK VEYA CİHAZI KAPATMAK BÖLÜMÜ-------------------------

T1CON=%00110001 '/////////////////////////////////////////////////////////////////////////////////////// T1CON=%00110001

BASLA1:

TMR1H=$B6:TMR1L=$C2:PIR1.0=0'////////////////////////////////////////////////////////////////////////////TMR1H=$B6:TMR1L=$C2:PIR1.0=0
WHILE PIR1.0=0  '////////////////////////////////////////////////////////////////////////////////////////WHILE PIR1.0=0

DEGER=500'İZİN VERİLEN TUSA BASMAMA SÜRESİ AYARI (YAKLAŞIK 500mS)
ADCIN 0,HAM
GOSUB EKRAN
'IF X=1 THEN  'X BİTİ 1 İSE CİHAZ AÇIKTIR VE YAPMASI GEREKENLERİ YAPAR
  IF TUS=1 THEN
     IF HAM>820 THEN  'ADC 4.0V tan büyükse 3 ledi birden yakar
        LED1=1:LED2=1:LED3=1:OUT=1
     ENDIF
     IF HAM<820 AND HAM>778 THEN  'ADC 4.0V ve 3.8V arasında ise 2 ledi yakar
        LED2=1:LED3=1:OUT=1
     ENDIF
     IF HAM<778 THEN    'ADC 3.8V tan küçükse 1 ledi yakar
        LED3=1:OUT=1
     ENDIF
     IF HAM<778 and ham>757 THEN    'ADC 3.8V ve 3.7V arasında ise 1 ledi yakar
        LED3=1:OUT=1
     ENDIF
     IF HAM<757 THEN    'ADC 3.7V tan küçükse 1 ledi blink yapar ve out vermez
     OUT=0
        LED3=1:pause 100:led3=0:pause 100
        LED3=1:pause 100:led3=0:pause 100
        LED3=1:pause 100:led3=0:pause 100
        LED3=1:pause 100:led3=0:pause 100
     ENDIF
   WHILE TUS=1:WEND
      SAYAC=SAYAC+1
          LED1=0:LED2=0:LED3=0:OUT=0:SURE=0
      IF SAYAC=4 THEN
      X=0 
      GOSUB DURUM
      ENDIF 
  ENDIF
'ENDIF


'-----CİHAZI AÇIP KAPATMAK İÇİN TUS GEREKLİ SÜRE KADAR BASILMAMIŞSA BÖLÜMÜ------ 
'if X=1 then
    IF TUS=0 THEN 'henüz tuşa basılmamış ise
    WHILE TUS=0
       SURE=SURE+1:PAUSE 1
         IF SURE>DEGER THEN  '(Süre doldu ama tuşa basılmadı geriye dönülecek yada tekrar döngüye girilecek sen karar ver ne yapacağına)
            SAYAC=0
            lcdout $FE,$C0,"SURE  :",#SURE  ,"   "
            goto BASLA1
         ENDIF
    WEND
'Program bu satıra gelirse tuşa kısa sürede basılmış demek olacak ve buraya işlemi iptal edecek kod yazılacak.
IF TUS=0 THEN SURE=0:SAYAC=0:GOSUB EKRAN
    ENDIF
'endIf

WEND'/////////////////////////////////////////////////////////////////////////////////////////////////////////////////WEND


'--------------------CİHAZ SARJA BAĞLANMIŞSA BÖLÜMÜ-----------------------------
IF SARJ=1 AND  HAM>850              THEN GOSUB LEDYAK1 '4.2V TAM ŞARJDA İSE
IF SARJ=1 AND (HAM>820 AND HAM<850) THEN GOSUB LEDYAK2 '4V İLE 4.2V ARASINDA İSE
IF SARJ=1 AND (HAM>778 AND HAM>820) THEN GOSUB LEDYAK3 '3.8V İLE 4V ARASINDA İSE
IF SARJ=1 AND  HAM<778              THEN GOSUB LEDYAK4 '3.8V DEN KÜÇÜKSE






GOTO BASLA1
'******************************************************************************
DURUM:
        SAYAC=0
        ONOFF=0
        IF ONOFF=0 THEN GOTO BASLA
RETURN
'---------------------ŞARJ bildirim ledleri BÖLÜMÜ-------------------------------------
'4.2V TA ADC=860    '4.0V TA ADC=820   '3.8V TA ADC=778
LEDYAK1:
        LED1=1:LED1=0:LED3=1
        GOSUB DELAY
        LED1=0:LED2=0:LED3=0
RETURN
LEDYAK2:
        ADCIN 0,HAM
        LED3=1  
        LED2=1
        LED1=1
        GOSUB DELAY
        LED1=0
RETURN

LEDYAK3:
        ADCIN 0,HAM
        LED3=1 
        LED2=1
        GOSUB DELAY
        LED1=1
        GOSUB DELAY
        LED2=0:LED3=0
RETURN

LEDYAK4:
        ADCIN 0,HAM
        LED3=1  
        GOSUB DELAY
        LED2=1
        GOSUB DELAY
        LED1=1
        GOSUB DELAY
        LED1=0:LED2=0:LED3=0
RETURN
'-------------------------------------------------------------------------------
DELAY:
     FOR P=0 TO 400
     PAUSE 1
     NEXT
RETURN
'-------------------------------------------------------------------------------
  EKRAN:
        ADCIN 0,HAM
	    lcdout $FE,$80,"ADC   :",#HAM  ,"    "        'okunan o,pot değerini ekrana yazdırmak
	    lcdout $FE,$C0,"SURE  :",#SURE ,"    "
	    LCDOUT $FE,$90,"SAYAC :",#sayac,"    "    
        LCDOUT $FE,$D0,"ON/OFF:",#ONOFF,"    "        
  RETURN

 END
"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"

Powered by EzPortal