STM32 Serisi Kartlar Nasıl Kolay Kullanılır (PlatformIO)

asdd1

Merhaba arkadaşlar, 

Bu konuda STM32 serisi kartlar başta olmak üzere bir çok ARM tabanlı, Atmel tabanlı, MSP tabanlı kartların nasıl kolay programlanabildiğine bakacağız. Kullanacağımız yapılar burada anlatılan mbed framework’ unden çok bağımsız olmayacak. Ancak programlamada alternatif bir yol ki keşfettiğimden beri benim de daha çok tercih ettiğim yöntem artık bu yöntem oldu. Desteklediği sistemler yukarıdaki resimde görülmektedir.

Kullanacağımız platform’ un bağlantısına buradan ulaşabilirsiniz. Bu platform u kullanmak için bir özelleşmiş bir ide yok. İnternette sıklıkla kullanılan “Sublime Text”, “Visual Code” yada “Atom” gibi metin düzenleyicilerin eklentisi olarak kullanılmakta. Bu yüzden debug özelleğinin kullanımı oldukça zor. Ancak basit ve debug gerektirmeyen işlemler için oldukça hızlı ve kullanışlı bu yüzden sizlerle paylaşmak istedim. Ben anlatımlarımı “Visual Code” üzerinden yapacağım. Siz kendi kullandığınız metin düzenleyicisini kullanabilirsiniz.

İlk olarak projemizi oluşturalım. Her ide’ de olduğu gibi “New Project” diyerek projemizi oluşturuyoruz.

Resmi görüntülemek için üzerine tıkla
Resmi görüntülemek için üzerine tıkla

“New Project” butonuna basınca önümü gelen ekranda kullandığımızı kartı ve bu kart ile kullanacağımız kütüphaneyi(framework) seçmemizi isteyecek. Ben uygulamamda Nucleo serisi bir kart seçeceğim için “NUCLEO-L476RG” seçtim. Bu yüzden kütüphane olarak mbed göründü. Eğer Arduino kullanmak isterseniz kullanacağınız Arduino modelini seçince kütüphane olarak “Arduino” seçmeniz gerekecektir. En altta görünün “Location” seçeneği ise projeyi oluşturacağımız yeri seçmemize yarıyor. Eğer tik işaretli ise default proje konumuna projeyi oluşturacaktır. Tiki kaldırırsanız projeyi oluşturacağınız yeri seçebilirsiniz.

Resmi büyültmek için üzerine tıkla
Resmi büyültmek için üzerine tıkla

Bu işlemi ilk defa yapıyorsanız seçtiğiniz kartın ve kütüphanenin gerek duyduğu eklentileri indirecektir. Bu işlemi sadece ilk sefer yapacaktır. Yani bir sonraki aynı kart ve aynı kütüphane ile yapacağım işlemde herhangi bir indirmeye gerek duymayacaktır.  Bu adımdan sonra projeyi oluşturduğumuz yerde “src” klasörünün içerisinde “main.cpp” isimli bir dosya olmalı. Eğer yoksa bu konuma bu dosyayı oluşturabilirsiniz. Ardından yazılıma geçebiliriz.

Kütüphane olarak mbed kullandığı için mbed için geçerli olan her şey burdada geçerli olacaktır. Yani siz herhangi bir mbed kütüphanesini burda da kullanabilirsiniz.

Yazılım olarak kütüphanede kullanmak açısından basitin bir tık üstünde bir uygulama tercih ettim. Projemizde bir I2C lcd, bir DHT11 sıcaklık sensörü, bir potansiyometre ve iki adet led bulunmakta. Projemizde DHT’ den ölçtüğümüz değeri LCD üzerinde gösterelim ve bu değer potansiyometre den ayarlanan sıcaklık değerinden büyük olunca kırmızı led yansın. Küçük olunca yeşil led yansın. Bu şekilde basit bir göstergeli termostat yapmış olalım. Header olarak şunları ekleyelim.

#include <mbed.h>
#include <Dht11.h>
#include <TextLCD.h>

Eklediğimiz header lardan da görüğünüz gibi mbed in yanında DHT11 ve I2CLcd kütüphanesi eklememiz gerekli. Bu işlemi şu şekilde yapmalıyız. Öncelikle ihityacımız olan kütüphaneyi bulalım. DHT kütüphanesinin bağlantısına buradan ulaşabilirsiniz. Bu bağlantıya gidince aşağıdaki resimde görünen işaretli yerde yazanları kopyalayalım.

Resmi büyültmek için üzerine tıkla
Resmi büyültmek için üzerine tıkla

Kopyaladığımız şey bir komut satırı komutu olup kütüphane dosyalarının olması gereken yerde bu komutu çalıştırmamız gerekiyor. Kütüphane dosyaları projeyi oluşturduğumuz yerdeki “lib” isimli dosyanın altında bulunması gerekiyor. Bu yüzden komut satırı ile bu klasöre geldikten kopyaladığımız komutu çalıştırmamız gerekiyor. Bu işlemi I2CLcd kütüphanesi için de yapmalıyız. Kütüphaneye buradan ulaşabilirsiniz. Bunun dışında platformio’ nun kendi kütüphaneleri de mevcuttur. Yani siz platformio’ nun kendi kütüphane arşivinden ihtiyacınız olan kütüphaneyi çekebilirsiniz. Bizim ihtiyacımız olan kütüphaneler platformio kütüphanesinde olmadığı için bu yöntemi tercih ettik. En son proje ağacı görüntümüz şu şekilde olmalıdır.

Resmi büyültmek için üzerine tıkla
Resmi büyültmek için üzerine tıkla

Ana değişkenlerimiz şu şekilde ayarlıyalım. Tanımladığımız iki led termostat durumunu göstermek için.  Bu ledleri D3 ve D4 pinlerine bağladık. DHT D8 pinine bağlı. Potansiyometre A0 pinine LCD ise I2C pinleri olan D14 ve D15′ e bağlı. Detaylı gösterime aşağıdaki fritzing şemasından ulaşabilirsiniz.

DigitalOut ledG(D3), ledR(D4);              //durum ledleri
Dht11 sensor(D8);                           //dht 
I2C i2c_lcd(D14, D15);      
TextLCD_I2C lcd(&i2c_lcd,  0x4E, TextLCD::LCD16x2);     //i2c lcd
AnalogIn pot(A0);                           //potansiyometre
InterruptIn btn(USER_BUTTON);

Ayrıca üstte tanımlı bir interrupt bulunmakta bunu da LCD’ nin ışığının durumunu değiştirmek için kullandık. Hemen her STM üzerinde bir kullanıcı tanımlı bir buton bulunmakta. Bu butona basınca LCD’ nin ışığının durumunu değiştirdik. Bu interrupt’ un callback’ i aşağıdaki gibi yaptık.

//ekran ışığı değişim buton interrupt callback i
void changeBackLight()
{
    if(lightStat)
    {
        lcd.setBacklight(TextLCD_Base::LightOn);
    }else{
        lcd.setBacklight(TextLCD_Base::LightOff);
    }
    lightStat = !lightStat;
}

Arduino’ da olduğu gibi bir setup fonksiyonu burda mevcut değil. Bu yüzden Main fonksiyonun içerisinde sonsuz döngüden ayarlamaları yapmamız gerekli. Bu ayarlamalarda hem LCD, Interrupt ve timer ayarlamalarını yaptık hem bazı basit görselleştirmeler yaptık.

//başta lcd ışığını yak ve cursor u kapat
    lcd.setBacklight(TextLCD_Base::LightOn);
    lcd.setCursor(TextLCD::CurOff_BlkOff);

    //lcd i temizle ve başlangıç yazılarını yaz
    lcd.cls();
    lcd.setAddress(0, 0);
    lcd.printf("...Termostat...");
    lcd.setAddress(1, 1);
    lcd.printf("Oguzhan Baser");

    //timer ları başlat
    timDHT.start();
    timLCD.start();

    //buton interruptuna callback i bağla
    btn.fall(changeBackLight);

    wait(2);
    lcd.cls();

Daha sonra sonsuz döngü içerisinde 100ms’ de LCD’ deki değeri güncelleyelim. Bu 100 ms’ lik süreye ihtiyaç duymamızın sebebi ekranın sürekli yneilenmesinden kaynaklı ekran hareketliliğini önlemek. “setAddress” fonskiyonu sutün ve satır cinsinden imlecin yerini gösterir. Ayarladığınız adrese göre “printf” fonksiyonu yazmaya başlayacaktır. “termStat” değişkeni ise termostat durumuna göre yazının değişmesi içindir.

//100ms de bir lcd değerlerini güncelle
        if(timLCD.read_ms() > 100)
        {
            lcd.setAddress(0, 0);
            lcd.printf("Sicaklik: %d", dhtTemp);
            lcd.setAddress(0, 1);
            lcd.printf("Ayar: %d", setTemp);
            timLCD.reset();
            if(termStat)
            {
                lcd.setAddress(10, 1);
                lcd.printf("Acik");
            }else{
                lcd.setAddress(10, 1);
                lcd.printf("Kapali");                
            }
        }

DHT sensör, kullandığı haberleşme protokolü gereğince 2 saniye de bir okunması gerekmektedir. Bu yüzden yine bir zamanlayıcı kullanmamız gerekli. Ayrıca lcd’ deki fazlalık karakterleri temizlemek adına bu 2 saniyelik vakit geçince lcd’ yi temizledik.

        //2sn de bir dht' yi oku ve lcd yi temizle
        if(timDHT.read_ms() > 2000)
        {
            lcd.cls();
            sensor.read();
            dhtTemp = sensor.getCelsius();
            timDHT.reset();
        }

En son olarak ledlerin durumunu sensör sıckalığı ve ayarlanan sıcaklığa göre değiştirmek kaldı. Termostat gibi elektonik cihazlarda sürekli açılıp kapanmayı önlemek için o anki sıcaklığın ayarlanan sıcaklığın biraz üstüne çıkması beklenir. Ayarlanan sıcaklığın belli bir miktar üzerine çıkınca ısıtma işlemi durdulur. Aynı durum soğuma da geçerlidir. Biz bu işlemi yazılımda şu şekilde gerçekleştirdik.

//ledlerin durumunu sıcaklığa göre değiştir
        if(dhtTemp > setTemp + 2)
        {
            ledR = 0;
            ledG = 1;
            if(termStat)
            {
                lcd.cls();
                lcd.setAddress(0, 0);
                lcd.printf("Sicaklik: %d", dhtTemp);
                lcd.setAddress(0, 1);
                lcd.printf("Ayar: %d", setTemp);
                lcd.setAddress(10, 1);
                lcd.printf("Kapali");
            }
            termStat = false;
        }else if(dhtTemp < setTemp - 2){
            ledG = 0;
            ledR = 1;
            if(!termStat)
            {
                lcd.cls();
                lcd.setAddress(0, 0);
                lcd.printf("Sicaklik: %d", dhtTemp);
                lcd.setAddress(0, 1);
                lcd.printf("Ayar: %d", setTemp);
                lcd.setAddress(10, 1);
                lcd.printf("Acik");
            }
            termStat = true;
        }

if sorgusu içerisindeki ikinci sorgu hem termosat’ ın son durumunu hafızada tutup lcd’ ye yazdırmak hem de ilk durum değişim anında lcd’ ye yazdırma işlemini bir defa yapılması içindir. “termStat” değişkenin durumlara göre değişimi ile bu tek sefer yazırma işlemi yapılmıştır. Daha sonra döngünün başındaki lcd’ ye yazdırma kısmında termostat durumu tekrar gösterilmiştir.

Yazılım kısmımız bu kadar. Buradaki yazılımın tamamına buradaki bağlantıdan ulaşabilirsiniz. Şimdi gelelim devre şemamıza. Fritzing ortamında çizilmiş devre şeması aşağıdaki gibidir.

Resmi büyültmek için üzerine tıkla
Resmi büyültmek için üzerine tıkla

Resimde görülen LCD ile üstünde LCM1602 yazan modül arasındaki bağlantıyı sizin yapmanıza gerek yoktur. I2C Lcd’ nin varsa muhtemelen birleşmiş vaziyettedirler. Birleşmemişse pinleri doğru konumlandırıp lehimlemeniz yeterlidir. Sadece Soldaki 4 bağlantıyı STM üzerinde doğru yerlere bağlamalısınız. Son olarak led’ lerin önüne direnç bağlamayı unutmayınız. STM serisi kartlar pin çıkışlarından en fazla 10-15 mA akım verebilirler. Led leri doğrudan bağlarsanız fazla akım geçeceği için kartın pinlerine zarar verebilirsiniz.

Umarım yardımcı olabilmişimdir. İyi çalışmalar dilerim…

 

 

 

2 Comments

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir