STM32F103 İLE DOKUNMATİK PANEL KULLANIMI

Gömülü de olsalar, sistemlerimizin kullanıcılarından giriş beklediği durumlar çok yaygın. Bunun için tuş takımları, tek tek butonlar, klavyeler, döner düğmeler türlü çeşitli araçlar kullanıyoruz. Dokunmatik paneller de en kullanışlı ve yaygın olanlarından. Cep telefonları ile iş çığırından çıkmış durumda. Dokunmatik ekranı olmayan alet kalmadı adeta.

Bu yayında STM32F103 ile rezistif tipte dokunmatik panel kullanımı anlatacağım. Bu panellerin kapasitif olan tipleri cep telefonlarında, tabletlerde kullanılıyor, daha da yetenekliler, onları belki ileride ele alırım, şu anda ihtiyacım yok.

REZİSTİF DOKUNMATİK PANELLERİN KULLANIM PRENSİBİ

Rezistif dokunmatik panellerin yapısını burada anlatmayacağım. İnternette yeterince bilgi var. Dokunmatik ekranlı TFT ler hakkında daha önceki yayınlarımdan birinde bilgi vermiştim. O yazıya ulaşmak üzere burayı tıklayınız. Bu yazı kapsamındaki bilgileri de yeterli bulabilirsiniz.

Dokunmatik panellerde esas olarak X yönünde bir potansiyometre, Y yönünde de ikinci bir potansiyometre ile temsil edilebilecek bir yapı var. Potansiyometrelerin sabit uçlarından birini toprağa, diğerini de besleme kaynağına bağlayıp, hareketli orta uçtan ölçtüğümüz gerilime bakarak pozisyon bilgisine ulaşıyoruz.

Dokunmatik panellerde bu potansiyometreler bağımsız değil, birbirleriyle ilişkili çalışıyorlar. Ekranın normalde birbirine değmeyen iki rezistif film tabakası, ekrana dokununca bastırdığımız noktada birbirlerine temas ediyorlar. Böylece dokunulan yere bağlı olarak ara da bir noktadan birbirine bağlanmış dirençler haline geliyorlar. Ben buna hareketli orta uçlarından birbirine bağlanmış potansiyometreler diyorum.

Bu durumda ölçüm almak üzere orta uca ulaşmak için biraz dolambaçlı bir yol izliyoruz.

Önce bir yönde, örneğin X yönünde ölçüm yapacağımızı düşünelim. X direncinin bir ucunu toprağa, diğer ucunu da besleme gerilimine bağlıyoruz. Y direncinin bir ucunu ölçüm için Analog Digital (ADC2) çeviricinin girişine bağlıyoruz. Diğer ucunu da yüksek empedans ile kapatmak üzere bir GPIO girişe bağlıyoruz.

ŞEKİL 1 : X Yönündeki potansiyometrenin orta ucunu Y direnci ucundan okumak.

Böylece yukarıdaki şekilde görüldüğü gibi X potansiyometresinin orta ucunu ADC2 girişine bağlamış oluyoruz. Buradan ölçeceğimiz gerilim bize, X potansiyometresinin orta ucunun hangi konumda olduğunu verecektir. Dokunmatik ekran söz konusu olduğunda bu nokta, ekranın yatay doğrultuda dokunulan yerine karşı düşecektir.

Y yönündeki ölçüm için de buna benzer şekilde :

ŞEKİL 1 : Y Yönündeki potansiyometrenin orta ucunu X direnci ucundan okumak.

Yukarıdaki şemalarda besleme gerilimi 5 V olarak yazılı ama bizim STM32 sistemimizde Vcc 3.3V, şekilleri düzeltmeye üşendim, kusura bakmayın.

Buradaki dokunmatik film direnç değerleri 2.4″ boyutundaki bir panel için 300-700 Ohm aralığında. Kısa kenar yönünde olan 300 Ohm, uzun kenar yönünde olanı 700 Ohm gibi. Ekrana dokunulduğunda orta uçlardaki gerilim dokunulan noktaya göre 0.5V ila 2.8V arasında bir değer alıyor. Bu parametreler ekrandan ekrana değişen özellikler. Bu nedenle programa bir kalibrasyon algoritması da koymak gerekiyor.

DOKUNMATİK PANELE ERİŞİM

Farklı tiplerde dokunmatik paneller var. Benim elimdeki ucuz tiplerde X yönündeki direncin uçları TFT nin D1 ve CS uçlarına bağlı, Y yönündeki direncin uçları da D0 ve RS uçlarına bağlı. Yani dokunmatik panele ait bu 4 uç, TFT nin 4 pinini ortak olarak kullanıyor.

Dokunulan noktayı okumak istediğimizde bu GPIiO ların fonksiyonlarını değiştirip kullanıyor, sonra TFT moduna geri döndürüyoruz.

Dokunmatik panellerin biraz daha iyi olanlarında 4 direnç ucu ile erişim değil, bir SPI arayüzü üzerinden alıyoruz. Bu durumda bir kesme -Interrupt- sinyali de oluyor. Bu çok daha kullanışlı bir çözüm ama bu tip dokunmatik paneller daha pahalı, benim kullandıklarım gibi ucuz TFT lerde de o kadar yaygın değil.

KULLANDIĞIM STM32 MODÜL

Paralel girişli TFT lere uygun olan modülüm MINIKIT_P olarak andığım aşağıdaki kart:









Bu kit STM32F103RB, yani 64 pinli yongalar kullanıyor. Touch panel uygulaması için burada verdiğim kodu hiç değiştirmeden STM32F103C8, 48 pinli MCU lar için de kullanabiliriz, ama benim elimde paralel girişli TFT nin doğrudan takılabileceği tek geliştirme kiti bu. Bu kit hakkında bilgi almak için tıklayınız.

Eğer Nucleo üzerinde kullanılacak ise TFT_D0 … TFT_D7 ve TFT kontrol pin tanımlarını, ADC seçim ve girişlerini ona uygun olarak değiştirmek gerekir.

STM32 ANALOG SAYISAL ÇEVİRİCİLERİN AYARLANMASI

Dokunmatik panel potansiyometrelerinin orta uçlarındaki gerilim değerlerini okuduğumuzu söylemiştim. Bu okuma işini ADC1 ve ADC2 çevre birimleri ile yapıyorum. ADC1 de GPIO A0 pininde Channel 0’ı, ADC2 de de GPIO A1 pininde Channel 1 girişinden okuma yapıyoruz. Bunlar TFT nin RS ve CS uçları ile ortak olan dokunmatik X ve Y dirençlerinin alt uçlarına bağlı GPIO pinleri. Şekil 1 ve Şekil 2 ye bakınız.

Bu durumda projemizde ADC1 ve ADC2 yi aktif hale getirerek ayarlarını yapmamız gerekiyor.

Şimdi STM32 CubeIDE üzerinden yapılacak ayarlara geçelim. MCU seçimi, harici osilatör seçimi ve SWD ayarlarını tekrar göstermeden atlıyorum.

Sistem saat ayarları

Sistemimizi harici kristal osilatör ie 72 MHz de çalıştırıyoruz, ADC1_2 saatini maksimum değeri olan 12 MHz e ayarlayabilmek için ADC Prescaler değerini /6 olarak seçiyoruz.

TFT miz 8 bit paralel girişli. Hem bu data girişlerini hem de kontrol girişleri için bunların bağlı olduğu GPIO ları aşağıdaki gibi ayarlıyoruz.

Buradaki TFT_CS ve TFT_RS dışındaki tüm GPIO ler Output PP, NoPull; SpeedLow olarak ayarlı.

TFT_CS ve TFT_RS nin özel durumu var, bunları Touch Panel kullanırken ADC girişleri olarak kullanacağız. TFT ye hizmet ederken de diğer pinler gibi Output PP olacaklar. Bu iki çalışma modundan ADC olanını SM32CubeIDE içinden yapalım, zira bu durumda IDE’nin hazırlanmasını isteyeceğimiz daha fazla kod var. GPIO Output olarak kullanmak istediğimizde iş çok daha basit, kendi ekleyeceğimiz kodlarla ayarları program akışı içinde değiştiririz.

Yukarıdaki ekran kopyasında PA0 – TFT_CS pinin ADC1_IN0 olarak seçilmesini görüyoruz. Sağ tarafta Analog grubu içinde ADC1 tıklanınca, ona ilişkin parametre penceresi de görüldüğü gibi beliriyor.

PA1 – TFT_RS pinini de ADC2_IN1 olarak aşağıdaki gibi seçiyoruz. Alında bunu da ADC1_IN1 olarak seçip çalışabilirdik, nasıl olsa ADC sıkıntımız olmadığından fazla düşünmeden böyle bir seçim yaptım. ADC2 yi farklı parametreler ile başka amaçlarla kullanacak olsak diğer seçeceği kullanırdım.

ADC1 ve ADC2 nin parametrelerini de varsayılan değerleri ile kullanıyoruz. Örnekleme süresini 1.5 saat periyodu, yani 0,125 µs olarak bıraktım. Bir gürültü sorunu yaşasaydım bunu arttırırdım.

ADC2 parametreleri, ADC1 de bunun aynısı

PROJEYE EKLENEN DOSYALAR

Aşağıda Project Explorer penceresinde seçili olarak görünen TFT_Basic TouchPanel klasörlerini bir başka projemden kopyalayarak buraya yapıştırdım. Bu iki paket benim hazırladığım kodlardan oluşuyor.

TFT_Basic.c/h dosyalarını daha önceki yayınlarımda anlatmıştım. touch.c/h dosyalarını da bu yayında anlatacağım.

PROJECT PATH VE DEFINE AYARLARI

Derleyicinin yeni eklediğimiz dosyalara erişebilmesi için Project/Settings/… menüsü altında ulaşacağımız includes Paths penceresine aşağıdaki satırları eklememiz gerekiyor.

Bazı proje seçeneklerini de aşağıdaki gibi Defines penceresinde eklememiz gerekiyor:

TOUCHPANEL : Dokunmatik ekranımız olduğunu bildiriyoruz
PARALLELMODE : TFT Ekranımızın paralel 8 bit girişli olduğunu bildiriyoruz
TFT_320x240 : TFT Ekranımızın çözünürlüğü
CNC_P : TFT Ekranın 8 bit data girişinin hangi GPIO larda olduğunu bildiriyoruz, CNC_P modülü ile uyumlu olsun diyoruz. Bu benim hem CNC hem de STM32 MINI_P kitimdeki durum.

PROGRAM KODLARI

Ekranda dokunulan noktayı algılamak üzere, GPIO ları buna göre ayarlayıp ADC1 ve ADC2 yi çalıştırmamız gerekiyor.

Girişleri dokunmatik fonksiyon ve TFT foksiyonları arasında değiştirip eski haline getiren fonksiyonumuz aşağıdaki gibi. Bu fonksiyonun ne yaptığını anlamak için Şekil 1 ve Şekil 2 yi göz önünde tutmak gerekiyor:

touch.c içindeki en alt seviye fonksiyonumuz aşağıdaki gibi:

Bu fonksiyon, seçilen ADC den tek bir okuma yaparak geri dönüyor. Biz bunu aşağıdaki fonksiyon ile 5 defa çağırarak okumaların ortalamasını alıyoruz.

Burada 5 okumanın en küçük ve en büyüklerini ortalamaya dahil etmiyoruz. Okuma sayısını ve ortalama harici tutulacak en büyük, en küçük okuma sayılarını READ_TIMES ve LOST_VAL parametrelerini değiştirerek ayarlayabiliriz.

Okumaları piksel’e çevirerek bizim için daha anlamlı sonuçlar elde etmek üzere aşağıdaki fonksiyonumuzu kullanıyoruz:

Burada okumayı piksele çevirirken kullandığımız parametreler touch.c dosyasının baş tarafında aşağıdaki varsayılan değerleri ile tanımlanıyor. Bunları elimdeki TFT ye göre ayarladım.

Bu parametreler TP_Adjust adlı kalibrasyon fonksiyonumuz ile değiştirilebiliyor. EEPROM var ise oraya kaydedilip bir sonraki açılışta kullanılabiliyor. Bu kalibrasyon fonksiyonunu bu sürümde anlatmayacağım. Yazı çok uzadı çünkü.

_m_tp_dev tp_dev=
{
0,         //uint16_t x0
0,         //uint16_t y0
0,         //uint16_t x
0,         //uint16_t y
0,         //uint8_t sta
0.45,      //float xfac  Varsayılan: 320/711=0.45 (Ekranın efektif genişliği %71.1)
0.33,      //float yfac  Varsayılan: 240/727=0.33 (Ekranın efektif yüksekliği %72.7)
-45,   //short xoff x offset Default: -45 (x=0 noktası +45 pikselde görünüyor)
-40,       //short yoff  y offset Default: -40 (y=0 noktası +40 pikselde görünüyor)
0,     //touchtype default landscape modu
};

Yukarıdaki kod içine koyduğum açıklamalar yeterli görülse de touch.h içinde yer alan _m_tp_dev tip tanımını aşağıda tekrar veriyorum:

typedef struct
{
uint16_t x0;
uint16_t y0;
uint16_t x; 
uint16_t y;        
uint8_t  sta;
float xfac;
float yfac;
short xoff;
short yoff;    
uint8_t touchtype;
} _m_tp_dev;

Bu da demo/test fonksiyonumuz, bunu main.c içinden çağırıyoruz :

MAIN.C İÇİNDE YAPILAN EKLEMELER

Ana fonksiyon doysmız main.c yi CubeIDE hazırlamıştı. Bu demo için sadece aşağıdaki eklemeleri yapmak yeterli oluyor:

TFT fonksiyonları için :

USER CODE 2 Blokuna TFT ayarlarını yapan ve dokunmatik panel test fonksiyonunu çağıran satırlar :

SONUÇ

Bu fonksiyonları CNC uygulamalarımda sıklıkla kullanıyorum. Ekrandaki 16×8 piksellik butonları tıklamakta herhangi bir sorun yaşamıyorum.
Hoşnut olmadığım durum kullandığım TFT Touch Panellerin bir kesme sinyali üretmemesi. Elimdeki TFT ekranları satın alırken henüz dokunmatik fonksiyonları kullanmaya henüz başlıyordum. Bilinçli bir seçim olmamış anlaşılan. Bir yandan da fiyat faktörü var. Amatör çalışmaları harçlıklar ile yürütmek gerekiyor.

Bu yayının sonu – Selçuk Özbayraktar Temmuz 2020