Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => Atmel => Konuyu başlatan: vkoglu - 18 Eylül 2021, 13:03:39

Başlık: Arduino da PT100+Transmitter (4-20mA), 100K NTC termistör ve DS18S20 sıcaklık
Gönderen: vkoglu - 18 Eylül 2021, 13:03:39
Arkadaşlar, Arduino MEGA, Arduino 1.8.13 arayüzünde;
sıcaklık ölçümü için 3 farklı sensör ile yaptığım çalışmaya ait kod aşağıdadır. İyi Çalışmalar.

#include <TimerOne.h>
#include <DallasTemperature.h>

#include <math.h>

// *** LCD header dosyaları ***
#include <AvrI2c_Greiman.h>
#include <LiquidCrystal_I2C_AvrI2C.h>
// adresi öğrenmek için scan_ii2_01.ino çalıştırılabilir.
LiquidCrystal_I2C_AvrI2C lcd(0x27, 20, 4); // sütun, satır

// PT100 için tanımlar
#define PT100 A7 // Pin A7

#define ThermistorPin A1

#define NTC_5v_Kontrol  11 // NTC sürekli voltaj verip ısınmaması için

// 100K NTC termistör için değerler.
int Vo;
float R1 = 10000;
float logR2, R2, T, Tc ;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

// DS18S20 Sensörü Giriş-Çıkışı
// Cihazın one wire adresini bulmak için :
// https://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#define DS18S20_Pin 12 // herhangi bir digital pin olabilir. Pin 12 seçildi.
// Setup a oneWire instance to communicate with any OneWire devices
OneWire ds(DS18S20_Pin);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&ds);
// Burayı ölç ve güncelle.
DeviceAddress insideThermometer = {0x28, 0x4E, 0x96, 0x46, 0x92, 0x0F, 0x02, 0x79};
float DS18S20_Olcum_Degeri; // DS18S20

unsigned long Son_0 = 0;
const unsigned long Aralik_0 = 5000;  // 1000 ms = 1 sn.

// *** SETUP BEGIN ***
void setup() {
  Serial.begin(9600); // Seri iletişim
  // PT100
  pinMode(PT100, INPUT);

// DS18S20 Ölçüm pini
  pinMode(DS18S20_Pin, INPUT); // Pin 12, 2 adet sensör bağlanacak.
  Sensor_Setup();

  // NTC sürekli 5v vermemek için.
  pinMode(NTC_5v_Kontrol, OUTPUT); // Pin 11, NTC ye Sürekli 5V vermemek için kullandım.
  digitalWrite(NTC_5v_Kontrol, LOW); // Normal OUTPUT da LOW = 0V

  // LCD
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0, 0); lcd.print("Setup Basladi..."); // col, row
} // Setup

void Sensor_Setup() {
  sensors.begin(); // ISI sensörleri

  // 12 bit 750ms; 11 bit 375 ms aralıklı oku
  // 10 bit 0.25 derece; 11 bit 0.125 derece, 12 bit =0.0625 degrees C,
  sensors.setResolution(insideThermometer, 11);

  // locate devices on the bus
  int deviceCount = sensors.getDeviceCount();

  Serial.print(deviceCount, DEC);
  Serial.println(" adet ısı sensörü bulundu.");

  Serial.print("Sensor Çozunulurlugu :");
  Serial.println(sensors.getResolution(insideThermometer), DEC);
} // sensor_setup

void loop(){
 
  unsigned long simdi = millis();
 
  if ( simdi - Son_0 >= Aralik_0  ) { // ölçme araliği 3000 ms = 3 sn.
    Son_0 = simdi;
    PT100_Oku();
    DS18S20_Oku();
    NTC_Sensor_Oku();
    Serial.println();
  } // if 
} // loop

// Kullanılan Malzeme :
// https://www.robolinkmarket.com/100k-ntc-sensor

// Termistör bir uç 5V, diğerine 100K direnç ile GND
/*  NTC SENSÖR 100K
          (Arduino)
          Vcc (+5V) Not: Sürekli 5v vermemek için burası digital pin write ile belirli bir süre açık kalabilir.            │
        │---│
  ▀----┘ 
  ▀----┐   
        │---┬----------------> Analog Pin (A1)
100K        █ 100K direnç
Termis.      │
            │
            GND (Arduino)
*/
void NTC_Sensor_Oku() { // 100 K NTC için
  int toplam = 0;
 
  digitalWrite(NTC_5v_Kontrol, HIGH);
  delay(2);
 
  // Ortalama değer için;
  for (int i = 0; i < 5 ; i++) {
    toplam = toplam + analogRead(ThermistorPin);
  }
  Vo = toplam / 5;
  // Steinhart eşitliği
  R2 = R1 * (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
  Tc = T - 273.15;
  // Tf = (Tc * 9.0)/ 5.0 + 32.0;
  lcd.setCursor(0, 2); lcd.print("    ");
  lcd.setCursor(0, 2); lcd.print(Tc, 2);
  Serial.print("NTC_Degeri=");Serial.println(Tc,2);
 
  digitalWrite(NTC_5v_Kontrol, LOW);
} // NTC_Sensor_Oku

// Kullanılan Malzeme :
// Su geçirmez DS18S20 sensör.
// https://www.robolinkmarket.com/ds18b20-su-gecirmez-isi-sensoru
// Kaynaklar :
// DB18B20B Tek sensör kullanımı
//https://lezzetlirobottarifleri.com/ds18b20-sicaklik-sensoru/
// Çoklu sensör kullanımı dk 4:00
//https://www.youtube.com/watch?v=fRSGkmnJhpE
// Bağlantı :
/* D
  S ----> VCC (Red)
  1  █
  8  █  4.7 KOhm
  B ----> DQ (Yellow) 
  2
  0 ----> GND (Black)
*/
void DS18S20_Oku(){
  sensors.requestTemperatures(); // tüm sensörlerden veri istiyor.
  DS18S20_Olcum_Degeri = sensors.getTempCByIndex(0); // DS18S20 sensörü
  Serial.print("DS18S20_Olcum_Degeri=");Serial.println(DS18S20_Olcum_Degeri,2);
} // DS18S20_Oku


// Faydalanılan Kaynaklar :
// https://www.ercankoclar.com/2018/10/pt100-sicaklik-sensoru-kullanimi-mikroc/
// https://www.instructables.com/Temperature-Measurement-With-RTD-PT100-4-20mA-Tran/
// Kullanılan Malzeme :
// https://www.tetcis.com.tr/
// Tetcis Ostim Ankara, Portatif rekorlu Termokupl ve transmitter
// Endüstriyel PT100. rekorlu, daldırma tipi,
// Endüstriyel Transmitter. 0-100 derece, 4-20mA çıkışlı, 9-36 VDC besleme
// Bağlantı :
/*
*  A7 (Arduino Pin A7)
*  +
*  │
*  ├------250 Ohm ---- -12V ---> Arduino GND
*  │
*  │
*  T6          T1 ---- +12V   
*      Transmitter
*/
void PT100_Oku(){
  long PT100_Value = 0;
  long PT100_Toplam = 0;
  float f1=0;
  float t1=0;
  float Voltaj, PT100_Direnci, Sicaklik, Sicaklik1,  Sicaklik2;
 
 
  PT100_Toplam=0;
  for (int i=1; i < 6; i++) { // Dengeli Okuma için
      // 0 to 1023 arası değer döner.
      // transmitter üzerinden pt100 oku, cihaz 0..100 celcius, 4..20mA ayarlı.
      PT100_Value = analogRead(PT100);
      PT100_Toplam = PT100_Toplam + PT100_Value;
      delay(1);
  }
  float PT100_Value_f = PT100_Toplam / 5.0;
  // Önce 4..20mA karşılık gelen okunan sayısal değeri 100 ile çarp.
  // Böylece sıcaklık derecesinde virgülden sonra iki haneli değer elde edilebilir.
  PT100_Value = PT100_Value_f * 100;
 
  lcd.setCursor(0, 1); lcd.print("    ");
  lcd.setCursor(0, 1); lcd.print(PT100_Value);   
  // 4mA 0 derece, 20mA ise 100 dereceye karşılık geliyor.
  // Ancak analogRead ile okunan 4mA için 205, 20mA için ise 1023.
  // İki haneli ondalık elde etmek için map 205 ve 1023 değerlerini 100 ile çarp.
  // Sonra, 100 derece karşılığını da 100 ile çarp.
  int Temperature = map(PT100_Value,20500,102300,0,10000);
 
  f1 = Temperature; // Float dönüşümü
  t1 = f1 / 100.0;  // virgülden sonraki değeri bulmak için.
  lcd.setCursor(0, 2); lcd.print("    ");
  lcd.setCursor(0, 2); lcd.print(t1);
  //Serial.print("PT100_Value=");Serial.print(PT100_Value);
  //Serial.print(" f1=");Serial.print(f1);
  Serial.print(" PT100 Sicaklik t1=");Serial.println(t1);
 
} // PT100_Oku