SHT30 nem sensörü kullanımı ?

Başlatan mustafa_cmbz, 11 Eylül 2020, 22:33:09

mustafa_cmbz

Merhabalar.

Protonda hiç örnek yok.Bulamadım.Aynı şekil si7021 içinde geçerli.

Datasheet inceleyince sht30 daha güzen anlatıyor gibi geldi ama ben bir kaç yerde takıldım.Hatta bir çok yerde takıldım da diyebiliriz.

Mesela en baştan sensör ilk açıldığında sensöre ne göndereceğiz ne formatta alacağız onu anlamış değilim.



https://www.mouser.com/datasheet/2/682/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital-971521.pdf

Hele şu akış diyagramından hiç bir şey anlamadım.

Niye bu kadar karmaşık haberleşme prosedürü olan sensörler üretiliyor anlamış değilim.

Bana rica etsem sht30 ile haberleşmek için sırası ile neyi nasıl göndermem gerektiğini anlatabilirmisiniz ?


Okan AKÇA

Sensörün üreticisinin sitesinde uygulama notu mevcut oradan çevire bilirsiniz.

sadogan

#2
data[0]= 0X2C;
data[1]= 0X0D;
i2c_start();
i2c_write(I2CADRES<<1);// yazama 
i2c_write(data[0]);
i2c_write(data[1]);
i2c_start();
i2c_write((adr<<1 )| 1); // okuma
bekle 100ms
TH = i2c_read();
TL = i2c_read();
crc = i2c_read();
HH = i2c_read();
HL = i2c_read();
crc = i2c_read(0);// son byte
i2c_stop();

OG

Hızlı bakış ile
cihaz 2,4V ile 5,5V arası çalışıyor, I2C haberleşiyor (1000 kHz'e kadar hızı destekler).

I2C dışındaki pinleri (genel besleme vs pinlerin dışındaki)

pin 6 nRESET  (INPUT)
Donanım reset pini, LOW ise resetlenir, reset durumu dışındaki haller için yani çalışması için boşta bırakılır.

pin 3 ALERT  (OUTPUT)
Alarm kullanılıyorsa alarm çıkışı içindir. Alarm koşulları sağlandıysa H konumunu alır.
Kullanılmıyorsa boşta bırakılmalıdır, kullanılıyorsa cihazın ısınmaması için transistor vs ile buffer yapılmalıdır, yani led vs bağlanmamalı, ısıya sebep olur ve ortam ısısının yanlış ölçümüne sebep olur.

pin 2 ADDR  (INPUT)
Bu pin 2 farklı I2C bus adresi seçme imkanı verir, boşta bırakılmamalı.
pin L ise (address A) I2C adresi   0x44 (default)   =  1000100x
pin H ise (address B) I2C adresi   0x45                 =  1000101x

x nedir?
I2C bus adresi 7 bit'i kapsar. Geri kalan 1 bit (0. bit) read/write komutunun tanımıdır,
write için 0.bit = LOW
read  için 0.bit = HIGH

örnek;
pin L yapılıp I2C bus adresi 0x44 (1000100x) seçildi ise
write komutu yollarken adres 10001000 olmalı  (I2C bus adresi, komut adresi değil)
read  komutu yollarken adres  10001001 olmalı  (I2C bus adresi, komut adresi değil)


Sensör, Tablo 3'te belirtilen güç açma eşik voltajı V POR'a ulaştıktan sonra açılmaya başlar.
Bu eşik voltajına ulaştıktan sonra sensörün idle (boşta bekleme) durumuna girmek için t PU (1ms gibi) zamanına ihtiyacı vardır.
Idle durumuna girildiğinde,  komutlar almaya hazırdır.

Her aktarım dizisi bir START koşulu (S) ile başlar ve I2C-veriyolu spesifikasyonunda açıklandığı gibi bir STOP koşulu (P) ile sona erer.
STOP koşulu (P) opsiyoneldir.

Sensör ölçüm yapmadığında veya data iletişimi yapmadığında enerji tasarrufu için otomatik olarak boşta durumuna (idle state) geçer. Bu idle state kullanıcı tarafından kontrol edilemez.

Ölçümler
- Single Shot   
- Periodic Mode 
yapılabiliniyormuş

Single Shot  mode da;  repeatability (tekrarlanma) seçeneği  low, medium, high olarak 3 secenek varmış, bir de clock stretching için enable/disable seceneği var, Komutlara karşılık gereken hex'ler (2 byte, sırayla command msb ve command lsb) Talo 8 de .

Periodic Mode da; repeatability saniyede 0,5, 1, 2, 4 ve 10 ölçüm/mps ve her biri için de low, medium, high seçenekleri varmış, bunun komut secenekleri de Tablo 9 da, yine aynı 2 byte, sırayla command msb ve command lsb.

sensorun gereksiz ısınmaması için (ısıya yanlış ölçmesin diye)  repeatability sıklığının düşük tutulması tavsiye ediliyor


Single Shot; 
İşlem akışları I2C usulunce adımlanır ;
İşlemciden giden (tablo 8 tonlama yapılmamış beyaz alanlar),
bir S (start), peşinden I2C adres (write'a ayarlanmış) byte'ı, peşinden 16 bitlik komut (2 byte) 
işlemci gönderirken sensör, her byte arasında alındığını belirtmek için bir ACK bitine sebep olur (SDA pinini LOW'a çeker, sonra serbest bırakır ve pini pulluplar H'a çeker), (tablo 8 gri tonlanmış alanlar)
Komut alınınca sensör ölçüm işlemine başlar.
Bu arada measurement  duration  için SDA ve SCL pini serbest bırakılmış halde bir süre geçiyor

clock stretching enable veya disable olarak secenek farkı (Tablo 8 de ortadaki akışın 2 farklı hali) ,
-clock stretching enable ise SCL pinini sensör yönetiyor (ölçüm devam ederken LOW'a çekerek), işlemci bu pini takip ediyor, sensor ölçmeyi bitirince  sensor verilerini göndermeye başlıyor
-clock stretching disable ise SCL pini serbest olduktan sonra ölçüm süresi bekleniyor, sonra işlemci I2C bus adresi read'e ayarlanmış olarak gönderiyor, ve sensör verilerini göndermeye başlıyor.

Sensorun verileri,  TEMP ve RH  ikiside 16 bit (2 byte)lık veriler, bunlar şu sırayla geliyor;
Temp MSB byte + Temp LSB byte + CRC (hemen önce gelen 2 byte'ın CRC'si) + RH  MSB byte + RH  LSB byte + CRC (hemen önce gelen 2 byte'ın CRC'si)


Benzer şekilde diğer akışlar da anlaşılabilir
Yanlış anladığım bir yer varsa arkadaşlar düzeltsin lütfen.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

mustafa_cmbz

@OG hocam merhabalar.

Bu güzel anlatımın için çok teşekkür ederim.

Anladığım kadarı ile birşeyler denemek istedim fakat sonuç şuan sıfırda.

Bana bu işi tam anlamıyla öğretirmisin.Bu sensörü protonda tam olarak sağlıklı bir şekilde nasıl okuruz.?

Bu uğraş benim elimde hep bir referans olacak bu nem sensörleri vs. ile ilgili..

NEM_OKU:
  
  HBStart
  HBusOut %10001010    '   ŞUAN YAZMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  HBusOut $24
  HBusOut $0B
  Stop
  
  DelayMS 5
  
  HBStart
  HBusOut %10001011    '   ŞUAN OKUMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  HBStop
  
  DelayMS 5
  
  HBStart
  HBusOut %10001011 
  HBusIn $45, [ISI_HAM.HighByte , ISI_HAM.LowByte , CRC1 , NEM_HAM.HighByte, NEM_HAM.LowByte ,CRC2]
  Return


anladığım kadarı ile yapabildiğim budur. bu ack ile nack olayını ise hiç anlamadım.

OG

#5
Mustafa ben bu sensörlerden hiç kullanmadım,

kod da Stop var, bütün işlemleri durdurur, herhalde dalgınlık HBStop olmalı.

Ayrıca HBusxxx kullanırken I2C yi donanım olarak kullanırsın MSSP modulun ayarları dikkatlice yapılmalı, SCL SDA pinleri doğru kullanılmalı ve Hbusin - Hbusout Declare lerin doğru olmalı
Ayarlamaların doğru yapıldığını ISIS'de olan başka I2C örneklerine uyarlayarak test edip sonra gercek uyarlamaya gecebilirsin

Bir de data'da Tablo 8 de sanki bir gariplik var,
2 kere read komutu gönderilmesi 2 kere okuma beklemesi yapılması bana biraz tuhaf geldi, sanki birisi olmamalı ama bu benim düşüncem. Stop hatasını düzelttikten sonra da çalışmaz ise birisi kaldırarak denebilir.

Altta bazı ilave ve değişiklikler ile

NEM_OKU:

  HBStart
  HBusOut %10001010    '   ŞUAN YAZMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  HBusOut $24
  HBusOut $0B
  HBStop                ''' stop HBStop olarak düzeltildi
  
  Clrwdt        ''' dikkat WDT = ON olarak calışıyorsan emniyet için eklendi, DelayMS ler reset attırabilir
  DelayMS 5
  Clrwdt        ''' dikkat WDT = ON olarak calışıyorsan emniyet için eklendi, DelayMS ler reset attırabilir
  
  HBStart
  HBusOut %10001011    '   ŞUAN OKUMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH

  ''' kapatılan altta 4 satır var ( data tablo 8 de tuhaflık dediğim konu )
''  HBStop
  
''  DelayMS 5
  
''  HBStart
''  HBusOut %10001011 
  HBusIn %10001011, [ISI_HAM.HighByte , ISI_HAM.LowByte , CRC1 , NEM_HAM.HighByte, NEM_HAM.LowByte ,CRC2]
  HBStop            ''' dikkat eklendi
Return
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

mustafa_cmbz

Bir çok şekilde denedim olmuyor.

  NEM_OKU:

  HBStart
  HBusOut %10001010    '   ŞUAN YAZMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  HBusOut $2C
  HBusOut $0D
         
  HBStart
  HBusOut %10001011    '   ŞUAN OKUMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  DelayMS 100
  
 
  HBusIn  %10001011, [ISI_HAM.HighByte , ISI_HAM.LowByte , CRC1 , NEM_HAM.HighByte, NEM_HAM.LowByte ,CRC2]
  HBStop            ''' dikkat eklendi
  Return 


  NEM_HESAPLA:
  RH=(NEM_HAM/65536-1)* 100 
  Return 
 

ekranda ham veriler sensör bağlı olsada olmasada "65535" olarak çıkıyor..


mustafa_cmbz

birde benim anlamadığım bu ack ve nack olayları

bunu işlmeci de gönderiyor sht30 da bu ack ve nack larıda doğru okumak gerekmiyor mu ?

ete

ACK ve NACK derleyici tarafından otomatikman yapılan bir iş. Bir nevi el sıkışma şeklinde düşünebilirsiniz.I2C haberleşmesinde standart bir işlem anlayacağınız.
SHT-30 data sheetine baktımda Cihaz kodu yada adresi $44 olarak verilmiş iken siz $44 sayısını sola shift edip $8A olarak kullanmışsınız. Yanlışlığın burada olduğunu düşünüyorum.
Data sheet de chaz adresi $44 (%0100 0100) olarak verilmiş ve açıklamada da bu adresin MSB tarafındaki 7 biti tarafından temsil edildiğini belirtiyor. Ama Tablo-7 deki açıklamaya bakılırsa burada bir terslik olduğunu düşünüyorum. Zira açıklamada adres $44 olarak kullanılacak ise 2 nolu ADDR pini VSS ye bağlı olmalıdır denilmiş. $45 olarak kullanmak içinde ADDR pininin VDD ye bağlanması gerektiği belirtilmiş.
Şöyle bir bakacak olrsak $44 binary olarak %01000100 şeklinde ve $45 in ise binary olarak %01000101 şeklinde uygulanması gerekir. Bu adreslerin 0 nolu biti (LSB) ise okuma yada yazma yapıldığını belirlemektedir. Terslik burada MSB bitlerini alırsam adres olarak $45'i kullanamam. Zİra bit-0 zaten 1 bu durumda mantık soldaki 7 biti değilde sağdaki 7 biti kullanırsan iş düzelir diyor. Doğrusu nedir tartışalım derim.
C dilindeki kütüphanelere baktığımda adres olarak hep $44 kullanıldığını görüyorum. Aslında data sheet de hiç yardımcı değil. Bu tür karışıklık pek çok I2C adres bilgisinde görülüyor. Bunu önlemek için genelde adresler %1000100x şeklinde binary olarak veriliyor. Burada Xyazma veya okuma biti şeklinde olunca hiç bir karışıklık olmadan adresi kullanmak mümkün oluyor. Ama bu sensörde adres bana kalırsa karışıklık yaratıyor.

Bütün I2C cihazlarında Data ve CLK hattına mutlaka 4K7 pullup direnci bağlanması gerekiyor. O söylediğiniz ACK ve NACK işlemleri bu pullup dirençleri sayesinde doğru çalışacaklardır.
Ayrıca 2 nolu ADDR pininin boşta bırakılmaması mutlaka VSS ye (Cihaz Adresi $44) yada VDD ye bağlanması (Cihaz adresi $45) gerektiği belirtilmiş.
Bütün bunlar doğru ise okuma nında doğru olması gerekir. Bunun içinde Adres değeri üzerinde oynamak gerekir diye düşünüyorum.


Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

OG

@ete
hocam, genelde I2C adreslemeyi bit.0 'ı anmadan söylerler, çünkü o hep r/w işlevi içindir,
hatta çoğunlukla I2C adres 6 bit dir, bit.7 de genelde 1 olarak sabit bir, eğer o da adres olarak 6 bite eklenirse 7 bitli olarak bir değer ile anılır.

I2C bus adres için 8 bitli (byte) yapı, örnek bit dizisi;
YaaaaaaX

Y sabit ve 1,
aaaaaa I2C adres (6 bit)
X r/w biti

benim cihazlarda karşılaştığım genel durum bu.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

ete

Elbette anlattığın gibidir. Bunu bende biliyorum. Ama o kadar çok kafa karışıklığı yaratıyorki pek çok kez başıma geldi. Başıma geldi derken benden bu konuda yardım isteyen üyelerin başına gelmiş olaylardan bahsediyorum. Doğru dürüst data sheet hazırlayan firmalar mutlaka binary gösterim ile Adres bilgisini veriyor ve %0100100(R/W) şeklinde gösteriyorlar. Burada R/W ilk biti temsil ediyor. (SHT25 data sheet'ine bakın) Bu gösterimin hiç bir tartışmaya yol açması mümkün değil. Ama rakam verirsen mecburen 8 bitlik rakam veriyorsun. Bu durumda hangi bitlerin adresi temsil etiğini belirtmen gerekir. Bu data sheet de de MSB tarafındaki 7 bit adresi temsil ettiği söylenmiş. Bunu şöyle anlarım $44 (%0100 0100) için. Adres=%0100100X) Ama sen LSB tarafından 7 bit almışsın (%1001000X) sebebini anlayamadım? Sebep genel anlamda bu şeklide olmalı diye düşündüğün için olsa gerek.Bu fikirde SHT30 data sheet2indeki ADDR (2nolu) pinin VDD veya VSS ye bağlı olması durumunu da açıklıyor aslında. Bu ADDR pini meseleside benim kafamı karıştırıyor. Zira onu dikkate alırsam sağdan 7 biti adres olarak kullanmam gerekir. Ama açıklamaya (MSB tarafından 7 bit) bakarsam Soldan 7 biti kullanmam gerekir. 
İşin doğrusunu bu sensörü okuyabilen (elinde olup da) birisinin koduna bakıp anlayacağız herhalde).

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

OG

Alıntı YapBunu şöyle anlarım $44 (%0100 0100) için. Adres=%0100100X) Ama sen LSB tarafından 7 bit almışsın (%1001000X) sebebini anlayamadım? Sebep genel anlamda bu şeklide olmalı diye düşündüğün için olsa gerek.Bu fikirde SHT30 data sheet2indeki ADDR (2nolu) pinin VDD veya VSS ye bağlı olması durumunu da açıklıyor aslında. Bu ADDR pini meseleside benim kafamı karıştırıyor. Zira onu dikkate alırsam sağdan 7 biti adres olarak kullanmam gerekir.

2 farklı adres ($44 ve $45) seçilebildiğine göre böyle düşünmek mecbur gibi

$44 veya $45 'i sağa yaslayarak düşünmek her şeyi karıştırır,
adres r/w bitine müdahale etmiş olur, 2 farklı adres verilemez duruma gelir.

$44 = 1000100
$45 = 1000101
ikisi arasındaki tek fark 0. bit

$44 veya $45 zaten 7 bit, ustteki sebeple sağa yaslayamayız.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

mustafa_cmbz

Alıntı YapPlease note that the I2C address is represented through
the 7 MSBs of the I2C read or write header. The LSB
switches between read or write header
. The wiring for
the default address is shown in Table 7 and Figure 11.
The ADDRpin must not be left floating.Please note that
only the 7 MSBs of the I2C Read/Write header constitute
the I2C Address.

Bu kısımda tam olarak ne demek istiyor? sanki adres pininin vdd yada gnd pinine göre sağa yada sola olarak okuma yazma biti değişiyor mu diyor anlamadım.çeviri tam anlamlı gelmiyor

OG

Üstte dediğim husus
7 bitlik adres ve sola yaslanmalı (MSB),
benim anladığım bu,
ve adres pinini boşta bırakmayın ikazı, ya vdd ya gnd.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

mustafa_cmbz

   Device = 18F25K22
   Declare Xtal = 20
   
   Declare LCD_Type 0
   Declare LCD_DTPin PORTB.0
   Declare LCD_ENPin PORTB.5 
   Declare LCD_RSPin PORTB.4 
   Declare LCD_Interface 4
   Declare LCD_Lines 2
   
   Declare HSDA_Pin PORTC.4
   Declare HSCL_Pin PORTC.3
   Declare Hbus_Bitrate  400
   
   All_Digital = True
  
  
   Symbol BUZZER = PORTB.7
   Output BUZZER 
  
  
   Dim NEM_HAM      As Word 
   Dim ISI_HAM      As Word 
   Dim CRC1         As Byte
   Dim CRC2         As Byte
   Dim CRC_CALC     As Byte
   
   Dim A As Byte 
   A=0
   NEM_HAM=0
   ISI_HAM=0 
   
 
   
   
   Dim RH           As Word 
   RH=0
'----------------------------  
   
   Cls : DelayMS 3000

  

  

   ANA:
   Print At 1,1,"NEM: ",Dec5 RH
   Print At 2,1,"ISI: ",Dec5 ISI_HAM
   DelayMS 2000
   GoSub NEM_OKU
   GoSub NEM_HESAPLA
  
   GoTo ANA 
   
  
  NEM_OKU:
  
  GoSub MELODI


  HBStart
  HBusOut %10001000    '   ŞUAN YAZMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  HBusOut $2C
  HBusOut $0D
  HBStop 
  
  

         
  HBStart
  HBusOut %10001001    '   ŞUAN OKUMA MODUNDA  '   WRİTE İÇİN 0.bit = LOW - READ İÇİN 0.bit = HIGH
  'HBusOut $2C
  'HBusOut $0D
                        
  

  HBusIn  %10001001,[ ISI_HAM.HighByte ,ISI_HAM.LowByte ,CRC1 , NEM_HAM.HighByte,NEM_HAM.LowByte , CRC2]
  HBStop            ''' dikkat eklendi
  
  GoSub MELODI
  Print At 1,1,"YAZILDI  "
  Cls : DelayMS 2000
  Return 


  NEM_HESAPLA:
  RH=(NEM_HAM/65536-1)* 100 
  Return  
 

Kodumun tamamı bu..ama bir türlü olmadı.

adres pinim 10k ile gnd ye bağlı.kartın üzerinden bunu teyit ettim.bir yerde bir şeyi atlıyoruz ama bulamadım hala.