STM32F103 ve SPI DOKUNMATİK PANEL KULLANIMI

STM32F103 ile rezistif dokunmatik panelli TFT kullanılışını daha önce anlatmıştım. O yayında koordinat belirlemek için dokunmatik panelin sensör dirençlerinin uçlarından analog gerilim değerlerini ölçüyorduk. Bunun için de STM32F103 ADC lerini kullanıyorduk.

O yayına ulaşmak için burayı tıklayabilirsiniz : STM32F103 İLE DOKUNMATİK PANEL KULLANIMI.

Bazı ekranlarda ise koordinat bilgileri bir dokunmatik panel kontrol işlemcisi -Touch controller- ile SPI arayüz üzerinden alınabiliyor. Bu durumda mikro denetleyicinin ADC lerini kullanmadan kalem koordinatlarını okuyabiliyoruz. Bu öncekine göre daha esnek, farklı seçenekler sunan bir yöntem oluyor.

SİSTEM KONFİGÜRASYONU

KONFİGÜRASYON BİLGİLERİ

Donanım :

STM32F103RB – S Minikit modülü :
Konnektörler mikrodenetleyicinin bulunmadığı tarafa -PCB üst tarafına- takılı. (Yeni kullanım şekli.)

Minikit_S üzerindeki kesme-bağlama modifikasyonları:

  • TFT_CS pini PB8 den ayrılarak PC15 e aktarıldı
  • TFT üzerindeki TFT_MOSI, TFT_CLK pinleri ile TP_DIN, TP_CLK pinleri birbirine bağlandı (SPI1 ortak kullanılıyor)
  • TP_CS pini PC14 e bağlandı
  • TP_DO pini PA6 (SPI1 MISO) pinine bağlandı
  • TP_IRQ pini PD2 ye bağlandı (Bu IRQ projede kullanılmadı.)
  • SD Kart SD_CS pini PB12 den ayrılarak PC13’e bağlandı. (Bu projeye yönelik değişiklik değil.)

KULLANILAN EKRAN

Elimde 2.4, 3.5 ve 4″ lik dokunmatik panelli TFT ekranlar var. Bunların hepsinde de TSC2046 dokunmatik panel işlemci yongası var. Bu yayında kullandığım TFT 4″ 480×320 ILI7796 sürücülü olanı. TFT sürücü ve boyut seçimleri uygun şekilde yapılarak diğer tip ekranlarla da sorunsuz çalışılabilir.

TSC2046 sol ortada görülen tümleşik devre.

TSC2046 denetleyicisi 8 ya da 12 bitlik ADC çevirileri yaparak, koordinatları SPI üzerinden 0-4096 arasında değişen değerlerle veriyor. SPI saat periyodunun 200ns den kısa olmaması gerekiyor (5 MHz), TFT ile aynı SPI port paylaşılarak kullanılacaksa -ki ben öyle yaptım- SPI saatini bu kadar düşürünce TFT de yavaşlıyor. Bu nedenle, daha iyisi her ikisini de ayrı SPI lar üzerinden sürmek.

ANA KART

CNC R2a Dec 2019 modeli kart kullanılıyor. Bu kartın bu projede diğer modüllere mekanik destek sağlamak ve µC programlama pinlerine kolay erişim sağlamak dışında bir görevi yok. Minikit bağlantı konnektörleri ilk uygulamalardakinin tersine, plaketin alt tarafında bakacak şekilde lehimli. Bu şekilde üst taraftaki Arduino uyumlu paralel konnektör dizisine kolayca erişilebiliyor. Arduino konnektör dizisinin bu projede kullanımı yok.

TFT TERS ADAPTÖRÜ

Minikit-S modülü orijinal tasarımının tersine çevrilmiş olarak kullanıldığından, TFT Pinlerinin dizilimi de aksetmiş durumda. Bunları yeni duruma uydurmak için TFT ile Minikit-S arasında bir alt-üst çevirici adaptörü kullanılıyor.

MODÜLLERİN BİRBİRİNE BAĞLANMIŞ HALİ

Kullandığım kurulum. En alttaki ana kart sadece STM32 nin 4 pin SW programlama pinlerine erişim kolaylığı açısından kullanılıyor. 20 pin JTAG konnektörü ile programlama yapılırsa buna ihtiyaç yok.

YAZILIM

selcuk_f103rb_touch_R3 kodu kullanılıyor. Bu uygulamada TP kontrol yongası TSC2046 sürücü kodları olan tsc2046_touch.c/h dosyaları proje dosyaları içinde uygulama tarihindeki (19.11.2020) halleri ile kayıtlı. Bundan sonrası için bu dosyalar ortak erişim alanı olan havuz’a alınacak.

STM32 CubeIDE PROJE KURULUMU

Proje kurulum ayarları aşağıdaki gibi:

TFT ve dokunmatik panel ile TSC2046 aynı SPI çevre aracı üzerinde, yani SPI1 i ortaklaşa kullanıyorlar. TP_CS ve TFT_CS çıkışları ile cihaz seçimi yapıyorum.

Bu da STM32 CubeIDE proje dosya yapısı:

KODLAR

TSC2046 DAN KOORDİNATLARI OKUMAK

TSC2046 dan koordinat okumak için 8 bitlik bir komut gönderip, ardından 16 bitlik okuma yapmak gerekiyor. Bu komutun yapısı şöyle:

  • 1. bit : Start biti , bu daima “1”
  • 2,3,4. bitler : X, Y, Z eksenleri, sıcaklık ve batarya okumaları için çoklayıcı konum ayarları
  • 5. bit : 8 ya da 12 bit ADC çevrim modu seçimi
  • 6. bit : Diferansiyel ya da tek kutuplu ölçüm modu seçimi
  • 7 ve 8. bitler : Power down modu seçimi

Ben diferansiyel ölçüm modunu tercih ettim, bu mod parazitlere karşı daha güvenli ölçüm sağlıyor. Bu durumda farklı ölçümler için gönderdiğim komutlar aşağıdaki gibi oluyor. Komuta eklenen 0x80 start bitini oluşturuyor.

  • X ekseni ölçümü için 0x50 | 0x80 = 0xD0
  • Y ekseni ölçümü için 0x10 | 0x80 = 0x90
  • Z ekseni ölçümü için 0x30 | 0x80 = 0xB0 (Bu kalem basıncı için, temas direnci)

Bu komutlardan birini gönderdikten sonra ADC için 1 ms süre tanıyıp 16 bitlik veriyi geri okuyoruz. Verinin ilk biti ile son 3 biti gözardı ediliyor, geri kalan 12 bit okunan ADC değerini veriyor. Bu işi yapan fonksiyonumuz TSC2046_Touch.c dosyamız içindeki TSC2046_SendCommand(uint8_t cmd) fonksiyonumuz. Adı yanıltmasın, sadece komut göndermiyor, gelen yanıtı da alıyor.

SendCommand bizim en alt seviye fonksiyonumuz. X,Y eksenleri ile kalem basıncını okuyan Z ekseni okuma işini aşağıdaki 3 fonksiyon ile yapıyoruz:

Touch.h dosyası

Buradaki CMD_X_AXIS, CMD_Y_AXIS, CMD_Z_AXIS ve CMD_Default parametrelerinin taımlandığı TSC2046_Touch.h dosyası aşağıdaki gibi:

DOKUNMATİK PANEL EKSENLERİ İLE TFT EKSENLERİNİN EŞLEŞTİRİLMESİ

Ekranın kullanılış yönüne bağlı olarak, dokunmatik panel X-Y eksenleri ile TFT nin X-Y eksenleri aynı olmayabilir. Bunun için okunan koordinatları, ekranı nasıl tuttuğunuza bağlı olarak TFT eksenlerine karşı düşürmek gerekiyor. Bu işi TSC2046_GetTouch_ADC() fonksiyonu ile yapıyoruz. Fonksiyon iki ekseni de okuyup bu eşleştirmeyi yapıyor.

ADC DEĞERLERİNİN OKUNARAK PİKSEL DEĞERLERİNE ÇEVRİLMESİ

Kullanıcı arayüz fonksiyonumuz TSC2046_GetTouchData(). Bu fonksiyon ekrana dokunulup dokunulmadığını kalem basıncını okuyarak algılıyor, eğer dokunuldu ise X ve Y eksenlerinden istenen sayıda -burada 10 adet- örnek alarak bunların ortalamalarını alıyor.

Ekrana dokunulduğunu algılamak için TSC2046 nün IRQ pinini kullanmıyoruz. O da bir alternatif olarak düşünülebilirdi.

Elde edilen değerleri TP_Calibrate yapısındaki katsayılardan yararlanarak piksel değerlerine çevirerek kullanıma sunuyor.

TP_Calibrate yapısı içindeki parametrelerin belirlenmesi Calibrate() fonksiyonu içinde yapılıyor.

KALİBRASYON FONKSİYONU – TSC2046_Calibrate()

Bu fonksiyonun her bir ekran için bir defa çalıştırılıp parametrelerin EEPROM’a kaydedilmesi yeterli. Ben şimdilik bu değerleri EEPROM’a kaydetmeyip SetDefaultParameterValues() adlı fonksiyon içinde varsayılanlar ile ayarlıyorum.

EEPROM’da Scale.x/Y ve bias.X/Y değerlerinin saklanması yeterli.

İleride kalibrasyon seçeceğine bir buton ile ulaşılması uygun olacak.

Bu fonksiyon ekranın sol üst köşesine ve sağ alt köşesine bilinen koordinatlarda birer nokta çizerek bunlara dokunulmasını istiyor, algılanan koordinat ile olması gereken arasındaki farklara bakarak düzeltme katsayılarını hesaplıyor.

Bu değerler ekrandan ekrana değişebiliyor, bu nedenle bir buton ile kalibrasyon fonksiyonunun devreye sokulması düşünmeli.

VARSAYILAN KALİBRASYON DEĞERLERİNİN YÜKLENMESİ

Varsayılan kalibrasyon değerleri ve ekran yönü ile ilgili ayarlamalar bu fonksiyon içinde yapılıyor. Bunu ana program içinde dokunmatik fonksiyonları kullanmaya başlamadan önce bir kere çağırmak gerekiyor.

TEST PROGRAMI

Test programımız ekranda dokunulan noktada bir benek oluşturuyor. Kalemi ilerlettiğinizde ard arda beliren noktacıklardan oluşan bir çizgi çizebiliyorsunuz. Ancak yavaş hareket ettirmeniz lazım, yoksa çizgi değil, birbirini izleyen aralıklı noktalar dizisi oluşuyor, bu durum dokunmatik algılama hızının düşük olmasından kaynaklanıyor. Yavaşlık STM32 den değil, TSC2046 nin hızından dolayı.

Ayrıca her bir eksen için 10 okuma yapıp ortalama alıyoruz. Benim kurulumumda buna gerek olmadığını, tek okumanın da yeterli olduğunu görüyorum. On katı hızlandırılabilir yani, ama kullanım amacım resim çizmek değil, ekrandaki tuşlara basmak olduğundan böyle bırakıyorum.

SONUÇ

Bu çalışma da böylece tamamlanmış oldu. Şimdi bunu yeni model CNC de uygulamaya koyacağım.

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

2 Replies to “STM32F103 ve SPI DOKUNMATİK PANEL KULLANIMI”

  1. Merhabalar,
    Benim gibi ilk kez TSC2046 kullanacak kişiler için harika bir kaynak olmuş.
    Emeğiniz için teşekkür ederim.

    1. Özgür Bey hemen bir uyarıda bulunayım. Bunu yayınladıktan sonra farkedip düzelttiğim bir bug var. TSC2046_GetTouch_data fonksiyonunda ortalama hesaplayan ../sample satırlarnın “sample” değerinin “0” olması durumuna bağışıklığı yok. Bazan hatalı dokunma algısı oluşup, ardından koordinat okunamazsa böyle bir durumla karşılaşılabiliyor. Kodun düzeltilmiş halini de yayınlarım, ama o zamana kadar aklınızda olsun, kendiniz de bir kontrol ekleyerek düzeltebilirsiniz.

      Ayrıca ilerideki bir sürümde istatistik yöntem kullanmak için okunan örnekleri iki dizide sakladığım satırları da atlayabilirsiniz.

      Selamlarımla,

Comments are closed.