MLX90614 Temassız Sıcaklık Sensörü Kullanımı Hakkında

Başlatan Elektronikprojem, 18 Ağustos 2021, 00:05:40

Elektronikprojem

Merhaba.
MLX90614 sensörü ile uğraşıyorum. Ne yaptıysam registerdeki verileri okuyamadım. Yardımcı olur musunuz? Bu arada 18F25K22 Kullanıyorum.

ASM
    __CONFIG _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_ON_1H & _FCMEN_OFF_1H & _IESO_OFF_1H        
    __CONFIG _CONFIG2L, _PWRTEN_ON_2L & _BOREN_OFF_2L & _BORV_285_2L 
    __CONFIG _CONFIG2H, _WDTEN_OFF_2H & _WDTPS_32_2H                                                                                     
    __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _HFOFST_OFF_3H & _T3CMX_PORTB5_3H & _P2BMX_PORTC0_3H & _MCLRE_INTMCLR_3H
    __CONFIG _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
    __CONFIG _CONFIG5L, _CP0_ON_5L & _CP1_ON_5L    
    __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H  
    __CONFIG _CONFIG6L, _WRT0_ON_6L & _WRT1_ON_6L 
    __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    __CONFIG _CONFIG7L, _EBTR0_ON_7L & _EBTR1_ON_7L
    __CONFIG _CONFIG7H, _EBTRB_ON_7H 
endasm
DEFINE OSC 64
;-------------------------------------------------------------------------------
TRISA=0     :PORTA=0
TRISB=%11111111      :PORTB=0
TRISC=%10000000      :PORTC=0  
TRISE.3=1 
;-------------------------------------------------------------------------------
OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000 ; 64Mhz
CCP1CON=0:CCP2CON=0:CCP3CON=0 
INTCON=%00000000
INTCON2.7=0 
WPUB=255
CM1CON=0 :CM2CON=0 
;-------------------------------------------------------------------------------
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 160 ' 38400 Baud @ 64MHz, -0,08%
SPBRGH = 1
BAUDCON.3 = 1         ' Enable 16 bit baudrate generator

SYMBOL GIE =INTCON.7 'genel interruptları açıyor
SYMBOL PEIE =INTCON.6 'peripheralinterruptları açıyor
SYMBOL RCIE =PIE1.5 'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5 'USART Receive interrupt flag bit
RCIE=1
tempx var BYTe
'ON INTERRUPT GOTO INT
;-------------------------------------------------------------------------------
ADCON2.7=1
ANSELA=0
ANSELB=0 
ANSELC=0
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 100
;-------------------------------------------------------------------------------
'DEFINE LCD_RSREG PORTC
'DEFINE LCD_RSBIT 5
'DEFINE LCD_EREG PORTC
'DEFINE LCD_EBIT 4
'DEFINE LCD_DREG PORTC
'DEFINE LCD_DBIT 0
'DEFINE LCD_BITS 4
'DEFINE LCD_LINES 2
;-----------------------------------------------------------------------------
SYMBOL  SDA=PORTB.7
SYMBOL  SCL=PORTB.6
;-------------------------------------------------------------------------------
DEGER VAR WORD[5]

BASLA:
PAUSE 1000
I2CRead SDA, SCL, $5A, $04, [DEGER[0]]
PAUSE 100
I2CRead SDA, SCL, $5A, $05, [DEGER[1]]
PAUSE 100
I2CRead SDA, SCL, $5A, $06, [DEGER[2]]
PAUSE 100
I2CRead SDA, SCL, $5A, $07, [DEGER[3]]
PAUSE 100
I2CRead SDA, SCL, $5A, $08, [DEGER[4]]
HSEROUT["$04:",DEC DEGER[0],"-$05:",DEC DEGER[1],"-$06:",DEC DEGER[2],"-$07:",DEC DEGER[3],"-$08:",DEC DEGER[4],13,10]
GOTO BASLA

END

alisumer

18F25K22 serisini bilmiyorum ama sorunlarından birincisi okumaya çalıştığın sensör analog veri göndermiyor neden adc açıyorsun
2- I2C tanımlamalarını yapmamışsın
3- sensörün 15 bitlik config ayar kayıtçısı var içeriğine bakmadım ama ayarlamam gereken değerler vardır elbet lap diye verileri sana vereceğini sanmıyorum bunun için I2Cwrite komutunu da kullanman gerekecek görebildiğim kadarıyla yok
4-gene işlemciyi bilmiyorum ama config ayarları 16fxxxx serilerinde config1-config2 diye gidiyor cCONFIGL ve H hiçgörmedim emin ol sigorta ayarlarının öyle yapıldığına
5-sensör verileri ile ekrana grafik çizmeyeceksen ki uğraşsan onlarlada olur 18 e ne gerek var 16 daha az reg daha kolay program yazma daha az ayar daha az maliyet vb
Hep meraktan

Elektronikprojem

Sayın @alisumer

1.Adc ler açık değil. Dikkat ederseniz ansel registerinden kapalı.

2. I2c tanimlamalarindan kastınız nedir bilmiyorum örnek verirseniz daha iyi anlayacağım.

3. Ne kadar Araştırma yaptıysam gördüğüm kadarıyla hepsinde direk okuma yapıyorlar okuma sonrası bir hesaplama ile sicaklik değeri elde ediyorlar.

4. Bu işlemci ile uzun zamandır çalışmaktayım. Config kayıtlarından eminim.

5. Teşekkür ediyorum işlemci için öneride bulunmussunuz fakat tercihim bu işlemci yönünde. Tek yapacagim iş i2c olmayacak çünkü.

alisumer

Hep meraktan

alisumer

Adcon 7 sadece ADC yi açmaya yarasa haklısınız da reg ler flipflop mantığı ile çalıştığından ADC yi açarken aynı zamanda diğer operasyonlari kapatma ihtimali olmasa sen bilirsin açık kalsın ben olsam kullanmayacağım şeyi kapatırım
Hep meraktan

ete

Programda grdüğüm kusurları açıklamaya çalışayım.
Öncelikle işlemcinin 64Mhz ile çalışıp çalışmadığına bakmak lazım. Data sheet bu konuda şöyle söylüyor. 64Mhz PLL aktif frekans isteniyor ise dahaili osc 16Mhz de çalışması gerek. Bu ise HFINTOSC seçilerek mümkün olabiliyor. Şidi neler yapılmalı onlara bakalım.
_FOSC_INTIO67_1H  seçeneği, _FOSC_HSHP_1H  ile değiştirilmeli. Yüksek frekansta çalışacaksınız.
OSCTUNE=%11000000
OSCCON=%01110010
OSCCON2=%11001100
Bu register ayarları ile dahili osilatör 16Mhz hızında seçilmiş olacak ve PLL de enable edilerek sistem frekansı 64 Mhz olarak ayarlanmış olacaktır.

Sistem frekansı 8Mhz ve üzeri olunca I2C hızınıda buna uygun olarak düzenlemek gerekiyor. Bu amaçla,
DEFINE I2C_SLOW 1 'Use for >8MHz OSC with standard speed devices
komut satırını programa eklemekte yarar var.
Programda analog pin kullanmayacaksanız ADC için belirlenen Define komutlarınıda kaldırmanız gerekir. Yoksa derleyici onlar için ayarlama yapacaktır.

Gelelim MLX ile haberleşme meselesine. Biliyorsunuz her I2C aletin bir donanım adresi bulunmaktadır. MLX için bu adres $5A olarak verilmiş. Ancak bu adresin sondaki 7 bitini kapsamaktadır. İlk bit ise okuma yapıldığında "1" olmakta , yazma yapıldığında ise "0" olmaktadır.
Bu durumda Cihaz (donanım) adresi Okumada =%$10110101 yani Hex olarak $B5, yazmada ise %10110100 yani Hex olarak $B4 adres değerini almalıdır. Sizin en büyük yanlışınız burada direk $5A olarak kullanmışsınız. Siz genelde okuma yapacağınıza göre cihaz adresinş $B4 olarak kullanmanız doğru olacaktır. Şunuda unutmayın. Basic derleyicisi cihaz adresinin son 7 bitini alıp okuma ve yazma durumuna görre ilk biti 1 veya sıfır kendisi otomatik yapmaktadır. Bu nedenle siz cihaz adresini ilk biti sıfır olacak şekilde ($B4) vermeniz yeterlidir. Gerisini basic derleyicisi halledecektir.
Unutmayın, 7 bit olarak verilen cihaz adreslerinde kullanmanız gereken adres değerini bulmak için (7Bit_Değeri)*2+0 formülünü kullanınız. Bu örnekte ($5A*2)+0 bize direk $B4 değerini verecektir.

BU açıklamalara göre yeniden deneyin bakalım ne sonuç alacaksınız.

Ete

Elektronikprojem

Alıntı yapılan: ete - 18 Ağustos 2021, 11:10:04Programda grdüğüm kusurları açıklamaya çalışayım.
Öncelikle işlemcinin 64Mhz ile çalışıp çalışmadığına bakmak lazım. Data sheet bu konuda şöyle söylüyor. 64Mhz PLL aktif frekans isteniyor ise dahaili osc 16Mhz de çalışması gerek. Bu ise HFINTOSC seçilerek mümkün olabiliyor. Şidi neler yapılmalı onlara bakalım.
_FOSC_INTIO67_1H  seçeneği, _FOSC_HSHP_1H  ile değiştirilmeli. Yüksek frekansta çalışacaksınız.
OSCTUNE=%11000000
OSCCON=%01110010
OSCCON2=%11001100
Bu register ayarları ile dahili osilatör 16Mhz hızında seçilmiş olacak ve PLL de enable edilerek sistem frekansı 64 Mhz olarak ayarlanmış olacaktır.

Sistem frekansı 8Mhz ve üzeri olunca I2C hızınıda buna uygun olarak düzenlemek gerekiyor. Bu amaçla,
DEFINE I2C_SLOW 1 'Use for >8MHz OSC with standard speed devices
komut satırını programa eklemekte yarar var.
Programda analog pin kullanmayacaksanız ADC için belirlenen Define komutlarınıda kaldırmanız gerekir. Yoksa derleyici onlar için ayarlama yapacaktır.

Gelelim MLX ile haberleşme meselesine. Biliyorsunuz her I2C aletin bir donanım adresi bulunmaktadır. MLX için bu adres $5A olarak verilmiş. Ancak bu adresin sondaki 7 bitini kapsamaktadır. İlk bit ise okuma yapıldığında "1" olmakta , yazma yapıldığında ise "0" olmaktadır.
Bu durumda Cihaz (donanım) adresi Okumada =%$10110101 yani Hex olarak $B5, yazmada ise %10110100 yani Hex olarak $B4 adres değerini almalıdır. Sizin en büyük yanlışınız burada direk $5A olarak kullanmışsınız. Siz genelde okuma yapacağınıza göre cihaz adresinş $B4 olarak kullanmanız doğru olacaktır. Şunuda unutmayın. Basic derleyicisi cihaz adresinin son 7 bitini alıp okuma ve yazma durumuna görre ilk biti 1 veya sıfır kendisi otomatik yapmaktadır. Bu nedenle siz cihaz adresini ilk biti sıfır olacak şekilde ($B4) vermeniz yeterlidir. Gerisini basic derleyicisi halledecektir.
Unutmayın, 7 bit olarak verilen cihaz adreslerinde kullanmanız gereken adres değerini bulmak için (7Bit_Değeri)*2+0 formülünü kullanınız. Bu örnekte ($5A*2)+0 bize direk $B4 değerini verecektir.

BU açıklamalara göre yeniden deneyin bakalım ne sonuç alacaksınız.

Ete

Hocam başta verdiğiniz sigorta ayarları ile işlemcinin zaman ayarları ve seri haberleşme ayarları malesef uyuşmadı. Tekrar inceleyeceğim.
Okuma ve yazma durum bitini göz ardı ettim haklısınız şimdi verileri alabiiliyorum bundan sonrası hesaplamaya kaldı.

oguztkn

Merhaba,

Aynı sensörü 16F726 ile kullanmaya çalışıyorum. Buradaki kod bloğu gibi okuma adresini $B4  yaparak değer aldım. Fakat hesaplama konusunda anlayamadım. Adafruit 'in MLX kütüphanesini inceledim ama işin içinden çıkamadım. Hesaplama konusunda yol gösterebilirmisiniz ?


// RAM
#define MLX90614_RAWIR1 0x04
#define MLX90614_RAWIR2 0x05
#define MLX90614_TA 0x06
#define MLX90614_TOBJ1 0x07
#define MLX90614_TOBJ2 0x08


double Adafruit_MLX90614::readObjectTempF(void) {
  return (readTemp(MLX90614_TOBJ1) * 9 / 5) + 32;
}
/**
 * @brief Get the current ambient temperature in degrees Farenheit
 *
 * @return double The temperature in degrees Farenheit or NAN if reading failed
 */
double Adafruit_MLX90614::readAmbientTempF(void) {
  return (readTemp(MLX90614_TA) * 9 / 5) + 32;
}

/**
 * @brief Get the current temperature of an object in degrees Celcius
 *
 * @return double The temperature in degrees Celcius or NAN if reading failed



ete

Data sheet sıcaklık hesaplamalarını şöyle yapmış. Temeli önce Kelvin cinsinden hesaplamaya sonrada onu Santigrat derece çevirmeye dayanıyor.
T(obje)=Okunan Ham sıcaklık /50= Sıcaklık(Kelvin cinsinden)
T (derece)=T(kelvin)-273,15

Örnek verelim.
Okunan değer =15095
Hesaplanan Sıcaklık = (15095 /50)=301,9 Kelvin cinsinden
T(derece)=301,9-273,15=28,75 derece

Aynı hesap T(Ortam) sıcaklığı içinde yapılacaktır.
Şayet derleyici ondalıklı hesap yapabiliyor ise 1/50=0,02 olduğundan ham sıcaklığın direk 0,02 ile çarpılması ilede sonuca ulaşılabilir.


Ete

oguztkn

Alıntı yapılan: ete - 21 Eylül 2021, 09:06:04Data sheet sıcaklık hesaplamalarını şöyle yapmış. Temeli önce Kelvin cinsinden hesaplamaya sonrada onu Santigrat derece çevirmeye dayanıyor.
T(obje)=Okunan Ham sıcaklık /50= Sıcaklık(Kelvin cinsinden)
T (derece)=T(kelvin)-273,15

Örnek verelim.
Okunan değer =15095
Hesaplanan Sıcaklık = (15095 /50)=301,9 Kelvin cinsinden
T(derece)=301,9-273,15=28,75 derece

Aynı hesap T(Ortam) sıcaklığı içinde yapılacaktır.
Şayet derleyici ondalıklı hesap yapabiliyor ise 1/50=0,02 olduğundan ham sıcaklığın direk 0,02 ile çarpılması ilede sonuca ulaşılabilir.


Ete


tempk var word
Sicaklik var word

SYMBOL  SDA=PORTB.4   ; OPTION_REG.7=0 PULL UP'LAR AKTİF
SYMBOL  SCL=PORTB.5

I2CREAD sda,scl,$B4,$07,[Sicaklik.lowByte,Sicaklik.HighByte]

tempk =((sicaklik/50)*100)-27315

 SEROUT2 PORTB.1,84,[dec4 tempk,13,10]

Bu blok ile okuyorum ama değerler rastgele gibi. 11,99,31290,24512,18931 şeklinde. Çok stabil olmasını beklemiyorum ama bu kadar düzensiz olması farklı geldi bana.


ete

Data ve CLK hattında pullup dirençleri olması gerek olduğundan emin ol.
Yanlızca Dahili Pullup ları aktive etmen yeterli değil. Dahili pulluplar pin giriş olarak ayarlanırsa aktif olurlar. Halbuki sende CLK giriş değil çıkış olacak.
Bu nedenle son dahili pullupları bırak oralara 10K direnç bağla.

Data Sheet'e bakılırsa önce hangi adresten okuma yapacağını sensöre söylemen gerekiyor.
Bunun için format şöyle olmalı,
I2CWRITE SDA,SCL,$B4,[$07]
I2CREAD  SDA,SCL,$B5,[SICAKLIK.Byte0,SICAKLIK.BYTE1]

bunu dene bakalım ne olacak.
Bu sensörün I2C formatı standart I2C protokolüne yakın ama birerbir uygun değil gibi.
Bu nedenle farklı yöntem gerekebilir okumak için.


Ete

oguztkn


Pull up olması gerektiğini pdf üzeriden görmüştüm. Şimdilik dahili pull up'lar ile deniyorum

Hocam bu hali ile ;
I2CREAD  SDA,SCL,$B5,[SICAKLIK.Byte0,SICAKLIK.BYTE1]

tempk= ((SICAKLIK/50) - 273)

SEROUT2 PORTB.1,84,[dec4 tempk,dec temp,13,10]

Veriyi alabildim.Harici direnç takmadan.(Harici takıp ta deneyeceğim). Yalnız iki haneli olarak gelmekte 33,34,29,28 gibi. Virgülden sonra 1 hane daha göstermek istiyorum.
Bunun için de;

tempk= ((SICAKLIK/50)*100 - 27315)

şeklinde denedim son hane hep sabit olarak kaldı


For ile 10 kere okutup

For x=0 to 9
I2CREAD  SDA,SCL,$B5,[SICAKLIK.Byte0,SICAKLIK.BYTE1]

tempk= ((SICAKLIK/50) - 273)

SICAKLIKToplam=SICAKLIKToplam+tempk
next x

temp=SICAKLIKToplam/10 yapıp denedim yine olmadı.
Virgülden sonrasını nasıl alabilirim ?

ete

Dahili pullup ile olmayacağını söylemiştim. Dahili pullup direnci yanlızca giriş olarak ayarlanmış pinlerde aktif olur. Clok pinin giriş olamaz. Bu nedenle harici direnç bağlamak zorundasın. İkisinide harici yapmanda yarar var.

Ete

oguztkn

Alıntı yapılan: ete - 21 Eylül 2021, 18:04:13Dahili pullup ile olmayacağını söylemiştim. Dahili pullup direnci yanlızca giriş olarak ayarlanmış pinlerde aktif olur. Clok pinin giriş olamaz. Bu nedenle harici direnç bağlamak zorundasın. İkisinide harici yapmanda yarar var.

Ete
Virgülden sonraki basamak durumu için bir öneriniz olabilir mi hocam ?

Hattuşa

Alıntı YapFor x=0 to 9
I2CREAD  SDA,SCL,$B5,[SICAKLIK.Byte0,SICAKLIK.BYTE1]

tempk= ((SICAKLIK/50) - 273)

SICAKLIKToplam=SICAKLIKToplam+tempk
next x

temp=SICAKLIKToplam/10 yapıp denedim yine olmadı.
Virgülden sonrasını nasıl alabilirim ?

usta burda bir hata yokmu? şöyle ki
for döngüsüne girmeden önce SICAKLIKToplam değerini sıfırlamıyorsunuz ya, program for döngüsüne girdiğinde SICAKLIKToplam değeri 0 olmadığı için üzerine ekleme yapıyorsunuz ya, okunan değeri sapıttırır.

bu arada virgülden sonraki değeri alabilmek için kalan işlemi yapmanız lazım,
bunun için
sıcaklık için temp=SICAKLIKToplam/10 ise basic için ondalik =SICAKLIKToplam //10   
C de ise ondalık =SICAKLIKToplam %10 kullanılır

Powered by EzPortal