Fırınlar, lehimleme aparatları ve bunların benzerleri aletlerin sıcaklık kontrollarını yapmak için birkaç yüz dereceye hatta seramik işleri için 1000oC ye çıkabilen sıcaklıkların ölçülmesi gerekiyor. Bu işler için en uygun seçenek bir K tipi termokupl oluyor. Termokupl çıkışındaki gerilimin yükseltilmesi ve sayısallaştırılması için de popüler seçenek olan Maxim’in max6675 inden yararlanıyorum.
Bu basit iş için STM8 mikro denetleyici ve bir OLED ekran kullanıyorum ama burada anlatılanlar ve kodlar rahatlıkla STM32 ye uygulanabilir.
MAX6675 İLE SICAKLIK ÖLÇÜMÜ
MAX6675, K tipi termokupl’lar ile 0-1024oC arasında ölçümler yapıp sayısal çıkış vermek üzere geliştirilmiş bir tümleşik devre. 0.25oC ölçüm çözünürlüğü var , soğuk nokta kompansasyonu yapıyor ve kullanımı çok basit.
3 ila 5V arasında bir gerilim ile beslenebiliyor. Okuduğu sıcaklığı başka bilgilerle birlikte 16 bit olarak SPI arayüzü üzerinden veriyor. Bu tek yönlü bir iletişim, siz max6675 e birşey yazamıyorsunuz. Bu nedenle MOSI girişi yok.
CS girişini ‘0’ yapıp SCK girişine saat sinyalini uygulayınca, saatin düşen kenarlarında sıcaklık bilgisini SO (yani MISO) çıkışından alıyorsunuz.
Okunan 16 bitin üst 12 biti sıcaklık bilgisi. Geri kalan 4 bit aşağıdaki gibi:
Tek başına entegreyi alıp lehim vb işler ile uğraşmaktansa aşağıdaki gibi bir modül üzerinde alıp kullanmak benim daha çok işime geldi, bir kaç adetlik işlerde max6675 i tek başına alacağınız fiyata bunu alabiliyorsunuz.
STM8 İLE UYGULAMA
STM8 ile Max6675 bağlantıları aşağıdaki gibi:
max6675 CS : C3
max6675 CLK : A1
max6675 SO : A2
max6675 Vcc : 3V3
max6675 GND : GND
Termokupl ile max6675 arasıdaki bağlantı iki adet klemens ile yapılıyor, sadece +/- uçlarına dikkat etmek gerekiyor.
Çok basit haberleşme protokolundan ve mikrodenetleyiciye fazla bir iş düşmemesinden dolayı STM8 in SPI çevre birimini kullanmadım. “Bitbanging” dedikleri şekilde doğrudan sürüp okuyarak çalıştım.
KODLAR HAKKINDA
Projenin STM8 STVD deki kurulumu aşağıdaki gibi:
STVD ile STM8 projesi geliştirme nasıl yapılıyor konusuna burada girmeyeceğim. Bunun için bu linke tıklayabilirsiniz.
Kayan nokta aritmetiğine girmemek için okuduğum sıcaklık değerlerini integer değişkenlerde saklıyorum, ekrana gönderirken ondalık noktalı olarak görüntüleyen bir algoritma kullanıyorum.
Max6675.c dosyası içinde okuma işini yapan fonksiyonlar aşağıda:
uint16_t max6675_readRawValue(void) { uint16_t tmp = 0; uint8_t i;GPIO_WriteLow(M6675_CS_Port, M6675_CS_Pin);// Select 6675
for(i=0;i<15;i++){ tmp = tmp<<1; GPIO_WriteHigh(M6675_CLK_Port, M6675_CLK_Pin); // SET CLK GPIO_WriteLow(M6675_CLK_Port, M6675_CLK_Pin); // RESET CLKif((M6675_SO_Port->IDR & M6675_SO_Pin) != 0x00)// Read input pin
{tmp |= 0x01;} }GPIO_WriteHigh(M6675_CS_Port, M6675_CS_Pin);// Unselect 6675
if (tmp & 4) Termokupl bağlı mı? kopuk mu? {// termokupl takılı değil ya da kopuk tmp = 4095;} else { tmp = tmp >> 3;} //sıcaklık bilgisi 12 üst bitde return tmp; } /* Sıcaklığın tam sayı kısmı fonksiyon değeri olarak, ondalık kesir kısmı da argüman listesindeki değişken üzerinden dönüyor */ int16_t max6675_readTemperature(int16_t *decimal) { int16_t intT; intT = max6675_readRawValue()*102400/ 4096; //Tamsayı kısmı*100 *decimal = intT/100; *decimal = intT-(decimal)100; // Ondalık kesir kısmı intT = intT/100;/*Şimdi tamsayı kısmını gerçek değerine çevirebiliriz. */ return intT; }
Görüldüğü gibi kayan noktalı işlemlerden kaçınmak için max6675.c içindeki readTemperature() fonksiyonunu sıcaklığın ondalık kısmını ayrıca gönderecek şekilde düzenledim. Fonksiyonun dönen değeri sıcaklığın tam sayı kısmını, argüman listesindeki tempFraction değişkeni de ondalık kısmını veriyor.
Ana program aşağıdaki gibi:
initMax6675(); while (1) { temperature = max6675_readRawValue(); //sprintf(buffer,"RAW T:%d\n", temperature); itoa(temperature, buffer, 10); ssd1306_display_string(0, 0, "RAW: "); ssd1306_display_string(4, 0, buffer); t = max6675_readTemperature(&tempFraction); itoa(t, buffer, 10); ssd1306_display_string(0, 1, "T= "); ssd1306_display_string(3, 1, buffer); itoa(tempFraction, buffer, 10); /* Sıcaklık değerinin 100oC den büyük yada küçük olması halinde ondalık kısmın yerleşimini ayarlayarak yazalım (not : bu kodun tek haneli sıcaklıklar için de düzeltilmesi gerekiyor.) */if(t<100) {
// iki haneli isessd1306_display_string(5, 1, ". ");
ssd1306_display_string(6, 1, buffer);}
else {
// üç haneli ise bir digit ileriye yazssd1306_display_string(6, 1, ". ");
ssd1306_display_string(7, 1, buffer);
}
delay_ms(250);
/* USER CODE END WHILE */
SONUÇ
Bu çalışma ile STM8 ve max6675 ile gerçekleştireceğim, muhtemelen PID kontrollu bir sıcaklık kontrol cihazı için gereken ön çalışmayı tamamlamış oldum. Sıcaklığı 0.96″ 128×32 OLED ekran üzerinde veriyor, ekranda başka şeyleri (set değeri, % güç vb) yazabileceğim yerler de kalıyor.
STM8 in kısıtlı bellek alanları nedeniyle kayan nokta aritmetiğinden ve değişkenlerden kaçındım, OLED sürücüsü olarak da kendi kütüphanemi kullandım. Buna rağmen program çıktısının görüntülenmesi sırasında sprintf() fonksiyonunu kullanamadığıma dikkatinizi çekerim.