Işık Şiddeti Ölçer.Yardım.

Başlatan ovaliiismail, 12 Mayıs 2017, 01:14:35

ovaliiismail

Arkadaşlar ldr kullanarak ışık şiddeti ölçer yapmaya çalışıyorum.Işık şiddeti 30 LUX iken kalibrasyon yapmadan önce lcd de 151 değerini okudum.30/151=0,199 olduğu için adcdegeri 199 ile çarpıp 1000 e böldüm.Devreyi simüle ettiğimde sadece kalibre ettiğim şiddet olan 30 LUX da dogru değer görüyorum.Diğer değerler saçma.
@ __config _CONFIG1, _INTRC_CLKOUT & _WDT_OFF & _LVP_OFF & _CP_OFF & _MCLR_OFF
CMCON=7 'KARŞILAŞTIRICILARI İPTAL ET.'
DEFINE LCD_RSREG PORTB 'LCD RS PİNİ PORTB.'
DEFINE LCD_RSBIT 0 'LCD RS PİNİ 0.BİT'
DEFINE LCD_RWREG PORTB 'LCD RW PİNİ PORTB.'
DEFINE LCD_RWBIT 1 'LCD RW PİNİ 1.BİT.'
DEFINE LCD_DREG PORTB 'VERİ PİNLERİ PORTB.'
DEFINE LCD_DBIT 4 'LCD VERİ PİNLERİ 4.BİTTEN BAŞLIYOR.'
DEFINE LCD_EREG PORTB 'LCD E PİNİ PORTB.'
DEFINE LCD_EBIT 2 'LCD E PİNİ 2.BİT.'
DEFINE LCD_BITS 4 'LCD VERİSİ 4 BİT.'
DEFINE LCD_LINES 2 'LCD SATIR SAYISI 2.'
DEFINE ADC_BITS 8 'SONUCU 8 BİT OLARAK AL.'
DEFINE ADC_CLOCK 3 'SAAT KAYNAĞI DAHİLİ.'
DEFINE ADC_SAMPLEUS 50 'ÖRNEKLEME ZAMANI 50MİKROSANİYE.'
ADCON1=%00000000 'SONUÇ SOLA YASLI VE 8 BİT.'
ANSEL=%00000010 'A1 ANALOG GİRİŞ.'
TRISA=%00000010 'PORTA.1 GİRİŞ.'
ADCDEGER VAR BYTE 'ADCDEGER DEĞİŞKENİ TANIMLANDI.'
DEGER VAR BYTE'DEGER DEĞİŞKENİ TANIMLANDI.'
PAUSE 300 '300MS BEKLE LCD AÇILMA SÜRESİ.'
PROGRAM: 'PROGRAM BAŞLATILDI.'
    ADCIN 1,ADCDEGER 'DEGERİ OKU ADCDEGER E YAZ.'
    DEGER=(ADCDEGER*199)/1000 'KALİBRASYON.'
    LCDOUT $FE,1 'LCD EKRANI TEMİZLE.'
    LCDOUT "ISIK SIDDETI:" '1.SATIR.'
    LCDOUT $FE,$C0,#deger,"LUX" '2.SATIR.'
    PAUSE 100 '100MS BEKLE.'
GOTO PROGRAM 'PROGRAMA GİT.'
END 'PROGRAM BİTİRİLDİ.'


İşlemci pic16f88.Bu arada bir sorum daha olacak.LCD ile çalıştığımda proteus belli bir süre sonra kapanıyor.Acaba bağlantıları mı yanlış yapıyorum yoksa proteusum da mı sorun var?

ete

LDR ışık karşısında çok lineer hareket etmez ama istemin daha kararlı hale getirilebilir.
Öncelikle min ışık şiddetindeki ADC değerini bulman ve aynı şekilde maksimum ışık şiddetinde max adc değerini bulman gerekiyor. Max değerden min değeri çıkartıp net ADC artışını tespit edip bu değer üzerinden sabit çarpan değerini bulman gerekir.
Ayrıca basicde (ADC x 199)/1000 şeklindeki hesap sonucu gerçeköi değerler vermez . Sebebi basit çarpım sonucu 16bit max değeri olan 65535 değerini aşar. Bunun yerine 32 bit çarpma yapmak daha uygun olur.
İlla bu formülü kullanacak isen ;
0*199 x 256=50,944 çıkar. Bunu 5095 alırsın ve sonucu 100 e bölersin. Böylece formülün ;
DEGER=(ADCDEGER*/5095)/100 şekline dönüşür. Bu formül sana daha doğru değerler verecektir.
Ama dediğim gibi LDR okumada min değeri sıfıra çekemezsin. Bunun için mutlaka onu hata payı olarak okunan değerden düşmen gerekir.
Bu mantığa göre formül hesaplamak için,
diyelimki min değer 20 okudun. Max değer de 700 okudun. Bunun karşılığıda 100 lüx olsun.
700-20=680  ve 100/680=0,147 dir o halde 0,147 x 256= 37,647 dir bunu 3765 alalım.
DEGER=(ADCDEGER*/3765)/100 şeklinde uygulanmalıdır. Bu şekilde hesaplanmış formül sana gerçeğe daha yakın değerler verecektir.

Ete

ovaliiismail

Hocam dediklerinizi dikkate aldım ve DIV32 yi kullanarak 32 bitlik bölme yaptım.Ayrıca 0.1LUXta 2 50.1LUXta 177 değerini okudum.177-2=175 yaptım. 50/175=0,2875 buldum.Gecici bir değişken oluşturup onu adcdeger*2875 e eşitledim.Ardından deger=DIV32 10000 yaparak degeri elde ettim.Ama 50LUX ve yakınlarında doğru değer gösterirken mesela 2LUXta 12 LUX gösteriyor.Bu acaba ldr nin karakteristiği yüzünden mi?
@ __config _CONFIG1, _INTRC_CLKOUT & _WDT_OFF & _LVP_OFF & _CP_OFF & _MCLR_OFF
CMCON=7 'KARŞILAŞTIRICILARI İPTAL ET.'
DEFINE LCD_RSREG PORTB 'LCD RS PİNİ PORTB.'
DEFINE LCD_RSBIT 0 'LCD RS PİNİ 0.BİT'
DEFINE LCD_RWREG PORTB 'LCD RW PİNİ PORTB.'
DEFINE LCD_RWBIT 1 'LCD RW PİNİ 1.BİT.'
DEFINE LCD_DREG PORTB 'VERİ PİNLERİ PORTB.'
DEFINE LCD_DBIT 4 'LCD VERİ PİNLERİ 4.BİTTEN BAŞLIYOR.'
DEFINE LCD_EREG PORTB 'LCD E PİNİ PORTB.'
DEFINE LCD_EBIT 2 'LCD E PİNİ 2.BİT.'
DEFINE LCD_BITS 4 'LCD VERİSİ 4 BİT.'
DEFINE LCD_LINES 2 'LCD SATIR SAYISI 2.'
DEFINE ADC_BITS 8 'SONUCU 8 BİT OLARAK AL.'
DEFINE ADC_CLOCK 3 'SAAT KAYNAĞI DAHİLİ.'
DEFINE ADC_SAMPLEUS 50 'ÖRNEKLEME ZAMANI 50MİKROSANİYE.'
ADCON1=%00000000 'SONUÇ SOLA YASLI VE 8 BİT.'
ANSEL=%00000010 'A1 ANALOG GİRİŞ.'
TRISA=%00000010 'PORTA.1 GİRİŞ.'
ADCDEGER VAR BYTE 'ADCDEGER DEĞİŞKENİ TANIMLANDI.'
DEGER VAR BYTE'DEGER DEĞİŞKENİ TANIMLANDI.'
GECICI VAR WORD 'GECICI DEĞİŞKENİ TANIMLANDI.'
PAUSE 300 '300MS BEKLE LCD AÇILMA SÜRESİ.'
PROGRAM: 'PROGRAM BAŞLATILDI.'
    ADCIN 1,ADCDEGER 'DEGERİ OKU ADCDEGER E YAZ.'
    GECICI=ADCDEGER*2857 'KALİBRASYON.'
    DEGER=DIV32 10000 'KALİBRASYON.'
    LCDOUT $FE,1 'LCD EKRANI TEMİZLE.'
    LCDOUT "ISIK SIDDETI:" '1.SATIR.'
    LCDOUT $FE,$C0,#DEGER,"LUX" '2.SATIR.'
    PAUSE 100 '100MS BEKLE.'
GOTO PROGRAM 'PROGRAMA GİT.'
END 'PROGRAM BİTİRİLDİ.'

ete

#3
Baştan söyledim LDR ışık karşısında lineer değişim göstermez.
Belirli aralıklarda ölçüm yapıp onu grafiğe çevirsen bir doğru değil eğri görürsün. Doğru olsa lineer olurdu.
İşin doğrusunu yapmak istersen formül olarak bir eğri denklemi çıkartıp onu kullanman gerekir. Excel de bu özllik var. Grafik datalarını verdiğin zaman sana hem grafiğini çizer hemde denklemi verir.
Ama işi basitçe aralarda düzeltmeler yaparak da çözebilirsin.

GECICI=ADCDEGER*2857 'KALİBRASYON.'
    DEGER=DIV32 10000 'KALİBRASYON.'
satırları yerine,
DEGER=(ADCDEGER*/7315)/100 formülünüde kullansan olur.

7315 şöyle buldum. 50/175=0,2857142857142857   bunu 256 ile çarparsak  73,14285714285714 değerini bulurum. Bu sayıyı 7315 olarak kullanır ve sonucu 100 e bölersem doğru sonuç elde ederim. Zira */ işlemi sayıyı yanındaki parametre ile çarpar ve bize 256 ya bölünmüş halini verir. Bu nedenle önden 256 ile çarpıyoruz. Değeri değişmemiş oluyor.

Ete

ovaliiismail

Anladım hocam çok teşekkür ederim.Allah sizden razı olsun.

Powered by EzPortal