Basamak yanıtı
Önceki derslerde ilginç uygulamalar geliştirmek istediğimizden bahsetmiştik.
O ilginç uygulamalardan bir tanesi budur. Diğeri belki Newton soğuma deneyi olarak düşünülebilir.
Bu sefer sondan başa doğru gitmeyi düşündük.
Burada kırmızı ve mavi çizgiler bir metalin 5 dakika süreyle ısınma sıcaklıklarını gösteriyor.
İki tane ısıtıcı metale temas edecek şekilde yerleştirilmiş. Bunların arasında bir tane sıcaklık ölçer ile sıcaklıkları kaydediyoruz.
Buna gerçek bir sistemin basamak yanıtı ismi veriliyor.
Bir tane türevli denklemimiz var.
Pembe kesikli çizgiler bu denklemin bir matematik yazılımı ile çözümünü gösteriyor. Bir diğer ifadeyle işlevin kendisini çizdiriyoruz.
Açık yeşil çizgi ise türevli denklemi gösteriyor.
Scipy
kütüphanesi ile bu denklemi çözebiliyoruz.
Metali ısıtmak için kullandığımız ısıtıcıları işaretin doluluk boşluk oranını ayarlayarak kontrol ediyoruz.
Örneğin % 50 doluluk boşluk oranı denilince yarı açık yarı kapalı diye düşünebilirsiniz.
Bir diğer ifadeyle yarısı "1" yarısı "0". Yarısı "YÜKSEK" yarısı "DÜŞÜK".
Ses kartı osiloskopla alınmış %50 doluluk oranındaki bir işareti aşağıda görebilirsiniz.
Başka bilgiler de verilmiş.
İşaretin çevrim süresinin 2 mili saniye, sıklığının da 500 Hz olduğunu görebiliyoruz.
İşaretin doluluk oranını %10 olarak ayarlayalım.
İşaretin doluluğunu değiştirmek için analogWrite komutunu kullanıyoruz.
Örneğin %10 yapmak için Arduino'da
analogWrite(isitici, 25);
komutunu verebiliriz.
Eğer bu değeri 255 yaparsak doluluk oranı % 100 oluyor.
Bu değeri 128 yaparak doluluk oranı % 50 olan bir işaret üretebiliriz.
Sıcaklık ölçümü için DSTH01 kullanıyoruz.
Isıtıcı olarak 2 tane IRF540N mosfet kullanıyoruz. 1k direnç kullanabilirsiniz.
Isıtıcıları beslemek için harici +5V güç kaynağı kullanınız.
İki numaralı uca da kırmızı ışık ve direnç bağlıyoruz. Bu direnç 220 ohm olabilir.
Bu ışığın veri toplama bittiğinde yanıp, sönerek bizi uyarmasını istiyoruz.
Aslında ısıtıcılar ile soğutma bloğu arasına termal macun sürmek düşünebilir.
Hali hazırda üzerlerinde biraz termal ped vardı.
Sadece kalın bakır teller ile ısıtıcıları soğutma bloğuna tutturduk.
Ortada ise sıcaklık ölçer bulunuyor.
Verileri çıkışa yazmak için kullandığımız Arduino yazılımını aşağıda bulabilirsiniz.
#include <Wire.h>
#include <Si7005.h>
const int Si7005_CS_PIN = 8;
Si7005 alici(Si7005_CS_PIN);
int kirmiziIsik = 2;
int isitici = 3;
int ikinciIsitici = 5;
float sicaklik, nem;
void setup()
{
Wire.begin();
Serial.begin(9600);
if (alici.detectSensor())
{
}
else
{
while (1)
{
}
}
pinMode(kirmiziIsik, OUTPUT);
pinMode(isitici, OUTPUT);
pinMode(ikinciIsitici, OUTPUT);
analogWrite(isitici, 128);
analogWrite(ikinciIsitici, 0);
digitalWrite(kirmiziIsik, 0);
for (int i = 0; i < 300; ++i)
{
sicaklik = alici.getTemperature();
sicaklik = sicaklik - 0.5;
Serial.println(sicaklik);
delay(1000);
}
}
void loop()
{
analogWrite(isitici, 0);
analogWrite(ikinciIsitici, 0);
digitalWrite(kirmiziIsik, 1);
delay(1000);
digitalWrite(kirmiziIsik, 0);
delay(1000);
}
Isıtıcıları yukarıda izah etmeye çalıştığımız şekilde işaretin doluluk oranını değiştirerek kontrol ediyoruz.
Arduino ilk çalıştığında 5 dakika süre ile verileri okuyup seri porta yazıyoruz.
İlk ısıtıcının %50 doluluk oranı ile çalışmaya başladığına dikkat ediniz.
analogWrite(isitici, 128);
Veriler yazıldıktan sonra ısıtıcıları kapatıyoruz.
Kırmızı ışık yanıp sönmeye başlıyor.
Ancak bu uygulama verileri sadece seri porta yazıyor.
Aşağıdaki kütüğü serioku.py
ismi ile kaydediniz.
import serial
import sys
seri = serial.Serial('/dev/ttyACM0')
seri.flushInput()
sıcaklıkListesi = []
print(sys.argv[1])
sure = sys.argv[1]
while (len(sıcaklıkListesi) < int(sure)):
satır = seri.readline()
sıcaklık = float(satır[0:len(satır)-2].decode("utf-8"))
print(sıcaklık)
sıcaklıkListesi.append(sıcaklık)
print('Sıcaklık listesi')
print(sıcaklıkListesi)
with open('sıcaklık.txt', 'w') as çıkış:
çıkış.write('\n'.join(str(i) for i in sıcaklıkListesi))
with open('sıcaklık.txt') as kütük:
satırlar = kütük.read().splitlines()
print('Sıcaklıkları tekrar kütükten okuyorum')
for satır in satırlar:
print (float(satır))
Bu uygulamaya okuma süresini geçebiliyoruz.
Örneğin
python serioku.py 300
şeklinde çalıştırırsak 5 dakika süre ile veri okuyacak.
Bu uygulama ile Arduino üzerindeki yazılımın eş zamanlı çalışması gerekiyor.
Bunun için yukarıda gösterildiği gibi serioku.py
uygulamasını çalıştırıp, Arduino üzerindeki sıfırla düğmesine basılı tutup bıraktığınızda uygulamaların eş zamanlı çalıştığını görebilirsiniz.
Sıcaklık değişimi ile ilgili türevli denklemimiz aşağıdaki gibidir.
Türevli denklemi çözmek için matematik yazılımı kullanabiliriz.
Genel çözümü yukarıda bulabilirsiniz.
Sıcaklık değişimi ile ilgili türevlerin elle çözümü için soğuma denklemleri ile ilgili derse bakabilirsiniz.
İlk sıcaklığın $T(0)=23$ olduğunu biliyoruz. Bunu denklemde yerine koyarsak $C_{1}=-50k$ buluruz.
K
katsayısını hesaplamak için ise ölçülen verilerden faydalanıyoruz. 175. saniyedeki sıcaklık $T(175)=30$ yaklaşık 30 °C olduğunu görüyoruz.
Bunu denklemde yerine koyup k için çözersek k sabitinin değeri yaklaşık $0.203312$ olarak bulunuyor.
Bu da ilk şemada kesikli çizgi ile gösterilen işlevi veriyor.
Türevli denklemdeki k
sabitini hesaplarken daha hassas bir hesap yapıyoruz.
$T(300)=34$ olarak ölçmüşüz. Burada dış ortam sıcaklığına a
diyerek k değerini hesaplattırıyoruz.
Böylece dış ortam sıcaklığı 23 °C den 24.5 °C ye çıktığında k
sabiti de değişiyor.
Verileri okuduktan sonra çizen Python programını aşağıda bulabilirsiniz.
import numpy as np
import matplotlib.pyplot as plt
import sys
from scipy.integrate import odeint
if len(sys.argv[1]) > 0:
ilkSıcaklık = sys.argv[1]
else:
ilkSıcaklık = 25
adet = 300 # Saniye cinsinden nokta sayısı (300 adet)
t = np.linspace(0,adet,adet) # Zaman aralığı
# veri
sıcaklıkListesi = []
with open('sıcaklık00.txt') as kütük:
satırlar = kütük.read().splitlines()
for satır in satırlar:
sıcaklıkListesi.append(float(satır))
sıcaklıkListesi2 = []
with open('sıcaklık01.txt') as kütük:
satırlar = kütük.read().splitlines()
for satır in satırlar:
sıcaklıkListesi2.append(float(satır))
ortamSıcaklığı = 23
# hesap
k = 0.203312
y = -50 * k * np.exp(-t/150) + 50 * k + float(ortamSıcaklığı)
# bilgileri giriyoruz
# k'yı ayrıntılı hesaplıyoruz
k= (34 * np.exp(2) - np.exp(2) * float(ortamSıcaklığı)) / (50 * (np.exp(2) - 1))
çalıştırmaSüresi = 150.0 # saniye
dışSıcaklık = float(ortamSıcaklığı)
ilkSıcaklık = float(ilkSıcaklık)
dolulukOranı = 50.0
# türevli denklem
def türevliDenklem(ilkSıcaklık, t, k, dolulukOranı,
çalıştırmaSüresi, dışSıcaklık):
sıcaklıkDeğişimi = ((dışSıcaklık - ilkSıcaklık) + k * dolulukOranı) / çalıştırmaSüresi
return sıcaklıkDeğişimi
sonuç = odeint(türevliDenklem,ilkSıcaklık,t,
args=(k, dolulukOranı, çalıştırmaSüresi,dışSıcaklık))
# Sonuçları yazdır
plt.figure(1)
plt.plot(t,sonuç,'c-',label='Türevli denklem')
plt.plot(t,sıcaklıkListesi,'b.',label='Ölçülen1')
plt.plot(t,sıcaklıkListesi2,'r.',label='Ölçülen2')
plt.plot(t,y,'m',label='Hesap', linestyle = 'dashed')
plt.ylabel('Sıcaklık (°C)')
plt.xlabel('Zaman (saniye)')
plt.legend()
plt.show()
Çalıştırırken aşağıdaki gibi soğutucunun ilk sıcaklığını da belirtebiliyoruz.
python adım.py 24.5
Hesap kısmında kesikli çizgilerle gösterilen işlevi çiziyoruz. Türevli denklemi çözmek için ise Scipy kütüphanesinin odeint
işlevini kullanıyoruz.
args
ile odeint
e ek değişkenler geçebiliyoruz.
Uygulamanın kaynak ve veri kütüklerini buradan indirebilirsiniz.
Gerekli kütüphaneleri kurmak için aşağıdaki komutu kullanabilirsiniz.
pip install -r gerekli.txt
Bu bölüm dersin bir parçası değil.
Ama eğer Laplace dönüşümü dersini takip etti iseniz ve türevli denklemlere meraklı iseniz okumaya devam edebilirsiniz.
Bu noktadan sonra ters Laplace dönüşümünü ile işlevi bulabiliriz.
Yorumlar