Max6675, HX711, MPX5700 Sensör Uygulaması

Başlatan aytacmacit, 27 Şubat 2017, 11:17:32

aytacmacit

Merhaba Ustalarım,

Herkese kolay gelsin, birkaç sorum olacaktı yol gösterirseniz çok sevinirim..
Projede kullanmak üzere 5 adet max6675 ve K tipi termokupl, bir adet loadcell ve hx711 , ve 5 adet mpx5700 basınç sensörü kullanacağım.. Kodları adım adım oluşturuyorum, forumdada aratıp tüm yorumları okuduktan sonra yazıyorum.
Öncelikle aklıma takılan nokta şurası ;
Örneğin max6675 ile spi 'dan veri okuduğumda her CS değişimleri arası bir miktar delay gerekiyor.. Bu diğer sensörler içinde geçerli,
ben örnekleme hızının daha yüksek olmasını istiyorum.. nasıl bir yol izleyebilirim acaba ? kullandığım mikrodenetleyiciler , pic ve ardunio (stm32 ve texas da spi dan denemeler yaptım fakat sağlıklı sonuç alamadım o yüzden bu kit ve işlemcilere kaydım..

Teşekkür ederim

skara1214

yani ne demek istediğini tam anlamadım , bence genelde de aynı kanı vardır.
yalnız sıkıntı cs pininin high low süresine kalmaz gibime geliyor. istersen 10 mbaud ile spi haberleşmesi yap, senin sensörlerin  en iyi ihtimalle 10 ms de tepki verirler(müthiş zaman oda). sen 100 hz gibi bir örnekleme zamanı ilede bu 3 sensörü rahat rahat okursun.
Herkes ölür ama herkes gerçekten yaşamaz

aytacmacit

#2
öncelikle teşekkür ederim cevabınız için, deneme amaçlı ardunioda yaptığım için ardunio kodunu paylaşacağım.
Ardunio için kodum ;

#define CLK 9
#define DBIT 10 // so
#define CS 13
#define CS2 12
#include <SoftwareSerial.h>

int v = 0;
int v1 = 0;

float Ctemp, Ftemp,Ctemp2;

void setup()   {
  Serial.begin(9600);
  pinMode(CLK, OUTPUT);
  pinMode(DBIT, INPUT);
  pinMode(CS, OUTPUT);
  pinMode(CS2, OUTPUT);
  digitalWrite(CS, HIGH);
  digitalWrite(CLK, LOW);
  digitalWrite(CS2, HIGH);

}
int spiRead();
int spiRead2();
void loop()   {
  v = spiRead();
  if (v == -1)   {
    Serial.print("No sensor \n");
  }
  else   {
    Ctemp =  v * 0.25;
   // Ftemp = (Ctemp * 9 / 5)+32;
          Serial.print(" kanal1 ");

    Serial.println(Ctemp);
   // Serial.print("\n");
  }
  delay(100);
  v1 = spiRead2();
  if (v1 == -1)   {
    Serial.print("No sensor \n");
  }
  else   {
    Ctemp2 =  v1 * 0.25;
  //  Ftemp2 = (Ctemp * 9 / 5)+32;
      Serial.print(" kanal2  ");

    Serial.println(Ctemp2);
  }
  delay(100);

}

int spiRead()   {
  int value = 0;
  digitalWrite(CS2,HIGH);
    delay(1);

  digitalWrite(CS,LOW);
  delay(2);
  digitalWrite(CS,HIGH);
  delay(220);
  digitalWrite(CS,LOW);
 
  digitalWrite(CLK,HIGH);
  delay(1);
  digitalWrite(CLK,LOW);


  for (int i=14; i>=0; i--) {
    digitalWrite(CLK,HIGH);
    value += digitalRead(DBIT) << i;
    digitalWrite(CLK,LOW);
  }

  if ((value & 0x04) == 0x04) return -1;


  return value >> 3;
}
int spiRead2()   {
  int value = 0;
  digitalWrite(CS,HIGH);
    delay(1);

  digitalWrite(CS2,LOW);
  delay(2);
  digitalWrite(CS2,HIGH);
  delay(220);
  digitalWrite(CS2,LOW);
  digitalWrite(CLK,HIGH);
  delay(1);
  digitalWrite(CLK,LOW);

  for (int i=14; i>=0; i--) {
    digitalWrite(CLK,HIGH);
    value += digitalRead(DBIT) << i;
    digitalWrite(CLK,LOW);
  }

  if ((value & 0x04) == 0x04) return -1;


  return value >> 3;
}

Delay süreleri yüzünden program çok yavaş işliyor. Azalttığım zamanda sonucu doğru okuyamıyorum. Bu delaylardan bir şekilde kurtulmam gerekiyor. Delay yerine nasıl bir yol izleyebilirim  ? Temiz bir okuma içinde gecikme olması öneriliyor okuduğum yazılarda ayrıca..

teşekkürler

skara1214

hocam yukarıda bahsettiğim gibi yani sizin sensörlerizin tepkisi o kadardır. yalnız bu delay  fonksiyonu 1 ms ise delay(220)  yi değiştirmeyi denemelisiniz.
Herkes ölür ama herkes gerçekten yaşamaz

aytacmacit

tamam hocam teşekkür ederim.. birde mpx5700ap sensörü ile ilgili sorum olacaktı.. Bu sensör mutlak basıncı ölçüyor . Mutlak basınç = port basıncı + hava basıncı.. diye biliyorum..
Data sheet : http://www.nxp.com/assets/documents/data/en/data-sheets/MPX5700.pdf

adc ile okuduğum değer ;

int raw = analogRead(A0);
float psi= ((((float)raw/(float)1023+0.04)/0.0012858)*0.145037738)-14.6;

datasheetin alt kısımlarındaki verilen transfer fonksıyonuna tabii tuttuğumda ve -14.6 hava basıncını çıkardığımda o esnada porttaki basıncı okuyor olmam gerekiyor diye yorumluyorum.. fakat 8.15 değerini görüyorum.. O porttada hava basıncı olduğundan dolayı , 14.6 psi hava basıncını görmem gerekmiyor mu ?
teşekkürler..

skara1214

@Klein cevap verse bu soruya daha yararlı olur basınç konusunda uzmandır kendisi...
Herkes ölür ama herkes gerçekten yaşamaz

aytacmacit

@Klein hocamın daha önceki forum yazılarındaki açıklamalarından ;

yaygın kullanımda olan 3  tip sensör var.

1- Absolute
2- Gauge
2- Diferansiyel.

Absolute sensörlerin bir tarafı kapalı.  Tek taraftan port çıkışı var. Ortamdaki gerçek basıncı ölçmek için kullanılır. 1 barlık abs sensörün girişine  basınç uygulanmazsa  çıkış 1 atmosfer basınç gösterir. Eğer porta vakum yaparsanız sıfıra doğru iner.  Eğer sensör 1 bardan yüksek ise , basınç uygulayabilirsiniz. atmosfer şartlarında 1 atmosfer , basınç uyguladığınızda ise , 1atm+basınç kadar çıkış verir.

Gauge sensörler tek yönlü sensörler. Bir tarafı basınç girişidir. Diğer tarafı da açıktır. ancak buraya basınç uygulayamazsınız. sadece vakum uygulayabilirsiniz.

Diferansiyel sensörler ise iki taraflı çalışabilir. iki tarafa da hem basınçhem de vakum uygulanabilir.  genellikle atmosfer basıncında tam skalanın yarısını gösterirler.

Diferansiyel portlu MPX sensörler gerçekte diferansiyel sensör değil. Gauge tipi sensör. Bunun için her ikitaraftan da basınç uygulayamazsınız.
Ancak asıl basınç girişinden uyguladığınız basıncın daha düşüğünü uygulayabilirsiniz.  basınç girişinden  1 bar uyguladıysanız , vakum girişinden en fazla 1 bar uygulayabilirsiniz.  Eğer fark basınç ölçerken bir tarafın basıncı hep diğer taraftan yüksek veya eşit oluyorsa kullanılabilir. (Örneğin filtre kirlilik tespiti)

okudum...


Şimdi benim sensörümde absolute ve 0-7 bar kapasiteye sahip..
port açıkken okumam gereken sanırım 1 atm , yani 14.6 psi...

Kodu şöyle güncellediğimde  ;

int raw = analogRead(A0);
float voltage2= raw*0.0048828125;  //  5: 2^10
float basinc = (((voltage2-5*0.04)/(5*0.0012858))*0.145037738);  // psi

seri monitörde basınç 13.77-13.88 , voltaji ise 0.811-0.815 görüyorum..

output olarak data sheette ; 0.2 to 4.7 V Output  yazıyor.. birşeyleri yanlış yapıyorum yada yanlış anlıyorum ama halen çözemedim

Maxim

mpx sensörlerin formülü kpa birimine göredir psi değil
acaba oradamı hata var?

aytacmacit

@Maxim hocam 0.145037738 ile çarpıyorum , psi e çeviriyorum

Maxim

evet psi çarpımı doğru
fakat sizin formülleri anlamadım ben, bu şekilde baştan bir daha deneyin

önce sensörden gelen voltajı bulalım (ben başka dil kullanıyorum)
Volt = (raw * 5) / 1024

şimdi formüle geçelim
KPA= ((volt /5) - 0.04) / 0.0012858
PSI = kpa * 0.145037738

Klein

Önce formülleri basınçları bir unut.
Öncelikle Sensör çıkışındaki gerilimi doğru okuyor musun?
Daha önce bir kaç kez farklı konularda dile getirdim.
İşin içinde ADC varsa, ADC değeri / 1024 vs.. gibi sabit değerler her zaman yanıltır.
İlla kalibrasyon gerekir.  Ama derseniz ki benim doğruluk beklentim düşük, o zaman burada sorun yok.

1atm = 101.325 Kpa

Sensör değerleri 0.2V - 4.7V  0-700 Kpa arası için.
Kpa başına 0,0064285714285714 volt verecek.
sensörün portu açıkta iken 101.325KPa  = 0,651375 V + 0.2V Offset = 0,851375 V görmeniz gerekir

Gördüğünüz değer normal.

Basınc (KPa)= (ADC(V) - 0,2)  /  0,0064285714285714  olur. bu sonuçtan psi dönüşümünü yaparsınız.

Not:  Her zaman söylediğimi burada da tekrar edeyim. Yukarıda sabit değerler üzerinden hesaplar yaptık. Sensörün ve ADC nin hatası olmadığını varsaydık. Bu yöntem doğru değildir.
Muhakkak kalibrasyon yapmak gerekir. Sitede bir kaç kez bu konu konuşuldu. Basit kalibrasyon konusunda bir kaç şey anlattım. Bu konuları bulup göz atarsanız iyi olur.

aytacmacit

Çok teşekkür ederim @Maxim ve @Klein hocam..
Kalibrasyon konusunuda araştıracağım.
Hocam birde bi sorum daha olacak ;
Bu sensörün data sheetinde testlerde dry air kullanıldığı yazıyor , diğer ortamlarda uzun vadede hassasiyetinin düşeceği söylüyor.
Şimdi bu sensörü herhangi bir motorun yanma odasından static port ile basınç ölçmek istesem , akış olmayacağı için , soğutmayıda sağlasam, sensöre zarar verir mi ve sonucun güvenilirliği tahmini olarak sizce ne olur ? yoksa honeywell 'in heavy duty mhl , px2 sensörleri var , bu sensörlere mi geçiş yapsam ?

Teşekkürler

Klein

Yanma odasından çıkan gazların korozif etkileri ve sensör elementine sızma, kimyasal yapıyı bozma etkileri konusunda bilgim yok.
mpx5999 ve mpx5100 sensörleri uzun süre yüksek saflıkta O2 ile kullandık sorun yaşamadık.
(Belki de yaşadık ama farkında değiliz. Kullanıcılar  uzun vadede sensör verilerinde kayma bildirmedi. Fakat olsa da farketmiş olduklarını sanmam)


aytacmacit


aytacmacit

@Klein hocam merhabalar,

Yukarıda vermiş olduğunuz offset değeri olan 0.2v gauge ve differansiyel sensör için gözüküyor datasheette. Bu sensörler için (offsetmin+offsetmax)/2 = 0.2 volt oluyor ayrıca.. burdaki mantık ile absoulete sensör için offset değeri verilmemiş ama bu denklem ile yola çıkarsam ; 0,3 gibi bir değer geliyor. Bunuda denklemde yerine yazdığımda okuduğum basınç değeri çok düşüyor. offseti 0.165 fln yaptığımda 101 kpa okuyorum. Ama voltaj değeri yine yanlış oluyor.
önceki yorumlarınızdaki bahsettiğiniz ;

1 - ADC girişine 0V uyguladınız(Girişi kısadevre ettiniz)
     ADC değeri 0 olabilir başka bir değer de olabilir. Biz 100 görmüş olalım. bu bizim offsetimiz.
2- ADC kirişine kalibreli kaynaktan max ( örneğimizde 3V olsun) değeri uyguladınız.
    ADC değerimiz 4000 olsun. bu bizim span değerimiz.

Hesaplamalara geçelim.
  ADC girişine bir gerilim uyguladık. kaçV olduğunu bilmiyoruz. ADC'den 3220 okuduk.

        Sonuç = (ADC Değeri  - OFFSET) / (SPAN - OFFSET) * SPAN Gerilimi (örneğimizde 3v)
        Sonuç = (3220 - 100) / (4000 - 100) * 3V
     Sonuç = 2,4V


denklemlerinden offset değerini bulmaya çalışıncada çok alakasız bir değer buluyorum. Nasıl bir yol izleyebilirim hocam  ?

teşekkürler