Haberler

Raspberry Pi’niz için HDMI Ekranınız Yok mu? Wio Terminal LCD, USB HMI ile İşinizi Görüyor!

Giriş

İlk kez bir Raspberry Pi aldığınızda, Raspberry Pi’ye nasıl giriş yapacağınızı bilmek isteyebilirsiniz, böylece onunla etkileşime geçmeye başlayabilirsiniz. Önceki blogumda, CP2102 USB’den Seri Dönüştürücü kullanarak ve Seeeduino XIAO kullanarak gibi birkaç giriş yönteminden bahsetmiştim.

Ancak, her iki yöntemde de Raspberry Pi’ye bir komut satırı arayüzü aracılığıyla giriş yaptık. Raspberry Pi ile Linux komutları aracılığıyla etkileşimde bulunabiliyorduk, ancak gerçek bir GUI (Grafik Kullanıcı Arayüzü) yoktu. Raspberry Pi ile GUI aracılığıyla etkileşimde bulunmanın tek yolu, onu HDMI bağlantısı aracılığıyla harici bir ekrana bağlamaktır.

Wio Terminal LCD’yi Raspberry Pi GUI olarak kullanmak!

Şimdi, harici bir ekrana bağlanmadan Raspberry Pi’deki GUI’ye erişmenin tamamen yeni bir yolunu açıklamak istiyorum ve bu da bir Wio Terminal kullanarak mümkün.

Wio Terminal, Realtek RTL8720DN tarafından desteklenen kablosuz bağlantıya sahip ATSAMD51 tabanlı bir mikrodenetleyicidir ve 2.4” LCD Ekran, yerleşik ivmeölçer (LIS3DHTR), Mikrofon, Zil, micro-SD kart yuvası, Işık sensörü ve Kızılötesi Verici (IR 940nm) ile donatılmıştır. Ayrıca hem Arduino hem de MicroPython ile uyumludur.

Wio Terminal’daki LCD’yi, Raspberry Pi’deki USB portlarından birine bağlayarak Raspberry GUI’yi görüntülemek için kullanabiliriz. Bu, Raspberry Pi için bir HMI (İnsan Makine Arayüzü) USB ekranı olan Wio Terminal LCD’yi oluşturur. Ayrıca, birden fazla Wio Terminal’e sahipseniz, Raspberry Pi’deki 4 USB portuna toplamda 4 Wio Terminal bağlayabilir ve bunları Genişletme modu/Mirror Modu gibi farklı modlarda çalışacak şekilde ayarlayabilirsiniz. Bunu bu blogda daha sonra tartışacağım. Bu yöntemin yalnızca Raspberry Pi için değil, aynı zamanda Nvidia Jetson Nano, BeagleBone ve Odyssey X86J4105 için de çalıştığını belirtmek isterim!

Wio Terminal Kurulumu

Şimdi, Wio Terminal’daki HMI ekranını çalışır hale getirmek için adım adım ilerleyelim! Wio Terminal’i bu işlem için nasıl kuracağınızı göstereceğim.

Eğer Wio Terminal’i ilk kez kullanıyorsanız, bu sayfayı ziyaret edip Wio Terminal için başlangıç ayarlarını yapmanız daha iyi olacaktır. Bunu yaptıktan sonra aşağıdaki adımlara devam edebilirsiniz.

Wio Terminal’inize bir Arduino programı yüklemeniz gerekiyor ve bunu yapmanın 2 yöntemi var.

Yöntem 1 – Arduino IDE yükleme yöntemi

Adım 1:
Seeed_Arduino_USBDISP kütüphanesi deposunu buradan ziyaret edin.

Adım 2:
“Kod” kısmına gidin ve “ZIP’i İndir” seçeneğini seçin.

Adım 3:
Arduino IDE’yi açın, “Sketch > Kütüphane Ekle > .ZIP Kütüphanesi Ekle” seçeneğine gidin ve indirdiğiniz .zip dosyasını seçin.

Adım 4:
“Dosya > Örnekler > Seeed_Arduino_USBDISP” kısmına gidin ve iki örnekten birini seçin.

  • Wio Terminal’da daha yüksek bir ekran yenileme hızı istiyorsanız, NullFunctional örneğini Wio Terminal’e yükleyin.
  • Wio Terminal’in aynı zamanda bir USB Fare olarak da çalışmasını istiyorsanız, USBDisplayAndMouseControl örneğini Wio Terminal’e yükleyin. Burada Wio Terminal’daki 5 yönlü anahtarı ve 3 düğmeyi fare olarak kullanabilirsiniz.

Yöntem 2 – uf2 dosyası ile flaş etme yöntemi

Daha pratik bir yöntem var ve bu da Wio Terminal’e örnekler dahil uf2 firmware dosyalarını flaş etmektir.

Adım 1:
Aşağıdaki uf2 dosyalarını indirin:

Adım 2:
Wio Terminal’de güç anahtarını iki kez hızlıca kaydırarak bootloader moduna girin.

Adım 3:
PC’nizde Arduino adında bir harici sürücü görünmelidir. İndirdiğiniz uf2 dosyalarını Arduino sürücüsüne sürükleyin.

Artık Wio Terminal tamamen kuruldu. Şimdi Raspberry Pi’yi de kurma zamanı.

Raspberry Pi Kurulumu

Eğer Raspberry Pi’yi ilk kez kullanıyorsanız, bu sayfayı ziyaret edip Raspberry Pi için başlangıç ayarlarını yapmanız daha iyi olacaktır. Bunu yaptıktan sonra aşağıdaki adımlara devam edebilirsiniz.

Adım 1:
Putty veya başka bir SSH istemcisini Raspberry Pi’ye giriş yapmak için yapılandırdıktan sonra, Raspberry Pi içinde komut satırı arayüzünü açın.

Adım 2:
Aşağıdaki komutu çalıştırarak tüm yapılandırılmış kaynaklardan paket bilgilerini indirin:

sudo apt-get update

Adım 3:
Aşağıdaki komutu terminalde çalıştırarak kernel başlıkları, kernel, build-essential, dkms gibi gerekli paketleri yükleyin:

sudo apt-get install raspberrypi-kernel-headers raspberrypi-kernel build-essential dkms

Adım 4:
Raspberry Pi’de ekran sürücüsünü indirin:

cd ~
git clone https://github.com/Seeed-Studio/seeed-linux-usbdisp

Adım 5:
Sürücüyü yapın ve inşa edin:

cd ~/seeed-linux-usbdisp/drivers/linux-driver
make & sudo make install
sudo reboot

Adım 6:
Yapılandırma dosyalarını sistem konumuna taşıyın:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp.conf /usr/share/X11/xorg.conf.d/

Not:
Seçebileceğiniz farklı ekran yapılandırmaları vardır, varsayılan olarak bir Wio Terminal bir ekran olarak ayarlanmıştır.

Adım 7:
Servisi yeniden başlatın:

sudo service lightdm restart

Adım 8:
Wio Terminal’i Raspberry Pi’nin USB portuna bağlayın ve Raspberry Pi Masaüstü GUI’si sihirli bir şekilde Wio Terminal LCD’de belirecektir!

Not: Eğer ekranda hiçbir şey görünmüyorsa, lütfen aşağıdaki adımları izleyin.

Aşağıdaki komutu terminalde çalıştırın:

sudo raspi-config

Raspberry Pi Yazılım Yapılandırma Aracı açıldığında, aşağıdaki konuma gidin:

Görüntü Seçenekleri > Çözünürlük

“varsayılan” dışında farklı bir çözünürlük seçin

Not:
Bu USB ekran sürücüsü sürümünde sıcak değiştirme desteklenmemektedir

Jetson Nano, Beaglebone ve Odyssey X86 hakkında ne dersiniz?

Ayrıca NVIDIA Jetson Nano, Beaglebone ve Odyssey X86‘ı nasıl kuracağınızı göstereceğim, böylece Wio Terminal bunlar için bir ekran olarak işlev görebilir!

Adım 1:
Nvidia Jetson Nano ve Odyssey X86J4105 (Ubuntu) için, aşağıdaki gibi Linux sürücüsünü kurun, terminalde aşağıdakileri çalıştırın:

sudo apt install --reinstall linux-headers-$(uname -r)

Not:
Odyssey X86J4105 için yalnızca ubuntu ve debian OS üzerinde test ettik. Diğer Linux OS’lar çalışmayabilir.

Adım 2:
Ekran sürücüsünü indirin

cd ~
git clone https://github.com/Seeed-Studio/seeed-linux-usbdisp

Adım 3:
Sürücüyü oluşturun ve derleyin

cd ~/seeed-linux-usbdisp/drivers/linux-driver
make & sudo make install
sudo reboot

Adım 4:
Yapılandırma dosyalarını sistem konumuna taşıyın

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp.conf /usr/share/X11/xorg.conf.d/

Adım 5:
Servisi yeniden başlatın

sudo service lightdm restart

Adım 6:
Wio Terminal’i Jetson Nano, Beaglebone veya Odyssey X86’ya bağlayın ve Wio Terminal LCD’sinde ilgili GUI’yi göreceksiniz!

Daha fazla Wio Terminal’iniz mi var? Hepsini ekran olarak kullanalım!

Eğer birden fazla Wio Terminal’iniz varsa, bunları farklı çalışma modlarıyla içerik göstermek için kullanabilirsiniz. Örneğin, bir Raspberry Pi kullanıldığında ve 4 Wio Terminal’iniz varsa, tüm 4 Wio Terminal’i Raspberry Pi üzerindeki 4 USB portuna bağlayabilir ve Wio Terminal’leri 4 farklı yapılandırmada içerik gösterecek şekilde yapılandırabilirsiniz.

Bunu basitçe 10-disp.conf dosyasını düzenleyerek yapabilirsiniz.

Kurulum 1

# Dört ekran genişletme
# desen: 1  2  
#        : 3  4

Bu, seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ altında bulunan 10-disp-1.conf dosyasıdır, bu dosyayı /usr/share/X11/xorg.conf.d/ konumuna kopyalayın ve adını 10-disp.conf olarak değiştirin:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp-1.conf /usr/share/X11/xorg.conf.d/10-disp.conf

Kurulum 2

# Dört ekran genişletme
# desen: 1
#        : 2  3  4

Bu, seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ altında bulunan 10-disp-2.conf dosyasıdır, bu dosyayı /usr/share/X11/xorg.conf.d/ konumuna kopyalayın ve adını 10-disp.conf olarak değiştirin:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp-2.conf /usr/share/X11/xorg.conf.d/10-disp.conf

Kurulum 3

# Dört ekran genişletme
# desen: 1  2  3  4

Bu, seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ altında bulunan 10-disp-3.conf dosyasıdır, bu dosyayı /usr/share/X11/xorg.conf.d/ konumuna kopyalayın ve adını 10-disp.conf olarak değiştirin:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp-3.conf /usr/share/X11/xorg.conf.d/10-disp.conf

Kurulum 4

# Dört ekran kopya görüntü

Bu, seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ altında bulunan 10-disp-4.conf dosyasıdır, bu dosyayı /usr/share/X11/xorg.conf.d/ konumuna kopyalayın ve adını 10-disp.conf olarak değiştirin:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp-4.conf

Raspberry Pi’de Python betikleri çalıştırarak Wio Terminal LCD’sinde GUI görüntüleme

Sadece Raspberry Pi Masaüstü GUI’sini Wio Terminal LCD’sinde görüntülemekle kalmaz, aynı zamanda Raspberry Pi komut satırında Python betikleri çalıştırabilir ve bir grafik kütüphanesi kullanarak Wio Terminal LCD’sinde grafikler görüntüleyebilirsiniz.

PyQt5

Yaygın grafik kütüphanelerinden biri PyQt‘dir. Bu kütüphaneyi kullanabilir, bir Python kodu yazabilir ve Wio Terminal LCD’sinde etkileşimli grafikler görüntülemek için Raspberry Pi’de çalıştırabilirsiniz. Burada PyQt’nin en son sürümü olan PyQt5’i kullanacağız.

Raspberry Pi’de PyQt’yi aşağıdaki adımları izleyerek kurabilirsiniz.

Adım 1:
pyqt5 için bağımlılıkları kurun

sudo apt update
sudo apt install python3 python3-distutils python3-pyqt5 

Adım 2:
Ekran için makroları dışa aktarın

export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1

Not:
Burada fb1 birinci ekran, fb2 ikinci, fb3 üçüncü ve devamı şeklindedir. Makroları kontrol etmek için echo $QT_QPA_PLATFORM komutunu kullanabilirsiniz.

Temel Örnek

Burada Wio Terminal LCD’sinde 3 düğme görüntüleyerek PyQt5 kütüphanesinin temel kullanımını göstereceğim.

Adım 1:
Aşağıdaki kodları kopyalayın ve buttons.py adında bir Python dosyası oluşturun. Ardından bu dosyayı Raspberry Pi’ye taşıyın

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget

app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('QHBoxLayout')
layout = QHBoxLayout()
layout.addWidget(QPushButton('Sol'))
layout.addWidget(QPushButton('Merkez'))
layout.addWidget(QPushButton('Sağ'))
window.setLayout(layout)
window.show()
sys.exit(app.exec_())

Adım 2:
Bundan sonra, bu dosyayı çalıştırın

python3 buttons.py

Wio Terminal LCD’sinde 3 düğmenin görüntülendiğini göreceksiniz.

PyQt5’te Tetris

Tetris oyununu Raspberry Pi’de çalıştırabilir, Wio Terminal’de görüntüleyebilir ve bağlı bir klavye kullanarak blokları kontrol edebilirsiniz. Bu örnek Jan Bodnar tarafından yapılmıştır ve tüm kredi ona aittir.

Adım 1:
Bu demoyu kullanmak için, aşağıdaki kodu bir Python dosyasına kopyalayın, adını tetris.py olarak belirleyin.

“`python
#!/usr/bin/python3

“””
ZetCode PyQt5 eğitimi

Bu bir Tetris oyunu klonudur.

Yazar: Jan Bodnar
Web sitesi: zetcode.com
“””

import random
import sys

from PyQt5.QtCore import Qt, QBasicTimer, pyqtSignal
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QMainWindow, QFrame, QDesktopWidget, QApplication

class Tetris(QMainWindow):

def __init__(self):
super().__init__()

self.initUI()

def initUI(self):
“””uygulama arayüzünü başlatır”””

self.tboard = Board(self)
self.setCentralWidget(self.tboard)

self.statusbar = self.statusBar()
self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)

self.tboard.start()

self.resize(180, 380)
self.center()
self.setWindowTitle(‘Tetris’)
self.show()

def center(self):
“””pencereyi ekranın ortasına yerleştirir”””

screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move(int((screen.width() – size.width()) / 2),
int((screen.height() – size.height()) / 2))

class Board(QFrame):
msg2Statusbar = pyqtSignal(str)

BoardWidth = 10
BoardHeight = 22
Speed = 300

def __init__(self, parent):
super().__init__(parent)

self.initBoard()

def initBoard(self):
“””tahtayı başlatır”””

self.timer = QBasicTimer()
self.isWaitingAfterLine = False

self.curX = 0
self.curY = 0
self.numLinesRemoved = 0
self.board = []

self.setFocusPolicy(Qt.StrongFocus)
self.isStarted = False
self.isPaused = False
self.clearBoard()

def shapeAt(self, x, y):
“””tahta pozisyonundaki şekli belirler”””

return self.board[(y * Board.BoardWidth) + x]

def setShapeAt(self, x, y, shape):
“””tahtada bir şekil ayarlar”””

self.board[(y * Board.BoardWidth) + x] = shape

def squareWidth(self):
“””bir karenin genişliğini döndürür”””

return self.contentsRect().width() // Board.BoardWidth

def squareHeight(self):
“””bir karenin yüksekliğini döndürür”””

return self.contentsRect().height() // Board.BoardHeight

def start(self):
“””oyunu başlatır”””

if self.isPaused:
return

self.isStarted = True
self.isWaitingAfterLine = False
self.numLinesRemoved = 0
self.clearBoard()

self.msg2Statusbar.emit(str(self.numLinesRemoved))

self.newPiece()
self.timer.start(Board.Speed, self)

def pause(self):
“””oyunu duraklatır”””

if not self.isStarted:
return

self.isPaused = not self.isPaused

if self.isPaused:
self.timer.stop()
self.msg2Statusbar.emit(“duraklatıldı”)

else:
self.timer.start(Board.Speed, self)
self.msg2Statusbar.emit(str(self.numLinesRemoved))

self.update()

def paintEvent(self, event):
“””oyundaki tüm şekilleri çizer”””

painter = QPainter(self)
rect = self.contentsRect()

boardTop = rect.bottom() – Board.BoardHeight * self.squareHeight()

for i in range(Board.BoardHeight):
for j in range(Board.BoardWidth):
shape = self.shapeAt(j, Board.BoardHeight – i – 1)

if shape != Tetrominoe.NoShape:
self.drawSquare(painter,
rect.left() + j * self.squareWidth(),
boardTop + i * self.squareHeight(), shape)

if self.curPiece.shape() != Tetrominoe.NoShape:

for i in range(4):
x = self.curX + self.curPiece.x(i)
y = self.curY – self.curPiece.y(i)
self.drawSquare(painter, rect.left() + x * self.squareWidth(),
boardTop + (Board.BoardHeight – y – 1) * self.squareHeight(),
self.curPiece.shape())

def keyPressEvent(self, event):
“””tuş basma olaylarını işler”””

if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape:
super(Board, self).keyPressEvent(event)
return

key = event.key()

if key == Qt.Key_P:
self.pause()
return

if self.isPaused:
return

elif key == Qt.Key_Left:
self.tryMove(self.curPiece, self.curX – 1, self.curY)

elif key == Qt.Key_Right:
self.tryMove(self.curPiece, self.curX + 1, self.curY)

elif key == Qt.Key_Down:
self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY)

elif key == Qt.Key_Up:
self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)

elif key == Qt.Key_Space:
self.dropDown()

elif key == Qt.Key_D:
self.oneLineDown()

else:
super(Board, self).keyPressEvent(event)

def timerEvent(self, event):
“””zamanlayıcı olayını işler”””

if event.timerId() == self.timer.timerId():

if self.isWaitingAfterLine:
self.isWaitingAfterLine = False
self.newPiece()
else:
self.oneLineDown()

else:
super(Board, self).timerEvent(event)

def clearBoard(self):
“””tahtadan şekilleri temizler”””

for i in range(Board.BoardHeight * Board.BoardWidth):
self.board.append(Tetrominoe.NoShape)

def dropDown(self):
“””bir şekli aşağı bırakır”””

newY = self.curY

while newY > 0:

if not self.tryMove(self.curPiece, self.curX, newY – 1):
break

newY -= 1

self.pieceDropped()

def oneLineDown(self):
“””bir satır aşağı gider”””

if not self.tryMove(self.curPiece, self.curX, self.curY – 1):
self.pieceDropped()

def pieceDropped(self):
“””şekil bırakıldıktan sonra, tam satırları kaldırır ve yeni bir şekil oluşturur”””

for i in range(4):
x = self.curX + self.curPiece.x(i)
y = self.curY – self.curPiece.y(i)
self.setShapeAt(x, y, self.curPiece.shape())

self.removeFullLines()

if not self.isWaitingAfterLine:
self.newPiece()

def removeFullLines(self):
“””tahtadan tüm tam satırları kaldırır”””

numFullLines = 0
rowsToRemove = []

for i in range(Board.BoardHeight):

n = 0
for j in range(Board.BoardWidth):
if not self.shapeAt(j, i) == Tetrominoe.NoShape:
n = n + 1

if n == 10:
rowsToRemove.append(i)

rowsToRemove.reverse()

for m in rowsToRemove:

for k in range(m, Board.BoardHeight):
for l in range(Board.BoardWidth):
self.setShapeAt(l, k, self.shapeAt(l, k + 1))

numFullLines = numFullLines + len(rowsToRemove)

if numFullLines > 0:
self.numLinesRemoved = self.numLinesRemoved + numFullLines
self.msg2Statusbar.emit(str(self.numLinesRemoved))

self.isWaitingAfterLine = True
self.curPiece.setShape(Tetrominoe.NoShape)
self.update()

def newPiece(self):
“””yeni bir şekil oluşturur”””

self.curPiece = Shape()
self.curPiece.setRandomShape()
self.curX = Board.BoardWidth // 2 + 1
self.curY = Board.BoardHeight – 1 + self.curPiece.minY()

if not self.tryMove(self.curPiece, self.curX, self.curY):
self.curPiece.setShape(Tetrominoe.NoShape)
self.timer.stop()
self.isStarted = False
self.msg2Statusbar.emit(“Oyun bitti”)

def tryMove(self, newPiece, newX, newY):
“””bir şekli hareket ettirmeyi dener”””

for i in range(4):

x = newX + newPiece.x(i)
y = newY – newPiece.y(i)

if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
return False

if self.shapeAt(x, y) != Tetrominoe.NoShape:
return False

self.curPiece = newPiece
self.curX = newX
self.curY = newY
self.update()

return True

def drawSquare(self, painter, x, y, shape):
“””bir şeklin karesini çizer”””

colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]

color = QColor(colorTable[shape])
painter.fillRect(x + 1, y + 1, self.squareWidth() – 2,
self.squareHeight() – 2, color)

painter.setPen(color.lighter())
painter.drawLine(x, y + self.squareHeight() – 1, x, y)
painter.drawLine(x, y, x + self.squareWidth() – 1, y)

painter.setPen(color.darker())
painter.drawLine(x + 1, y + self.squareHeight() – 1,
x + self.squareWidth() – 1, y + self.squareHeight() – 1)
painter.drawLine(x + self.squareWidth() – 1,
y + self.squareHeight() – 1, x + self.squareWidth() – 1, y + 1)

class Tetrominoe(object):
NoShape = 0
ZShape = 1
SShape = 2
LineShape = 3
TShape = 4
SquareShape = 5
LShape = 6
MirroredLShape = 7

class Shape(object):
coordsTable = (
((0, 0), (0, 0), (0, 0), (0, 0)),
((0, -1), (0, 0), (-1, 0), (-1, 1)),
((0, -1), (0, 0), (1, 0), (1, 1)),
((0, -1), (0, 0), (0, 1), (0, 2)),
((-1, 0), (0, 0), (1, 0), (0, 1)),
((0, 0), (1, 0), (0, 1), (1, 1)),
((-1, -1), (0, -1), (0, 0), (0, 1)),
((1, -1), (0, -1), (0, 0), (0, 1))
)

def __init__(self):

self.coords = [[0, 0] for i in range(4)]
self.pieceShape = Tetrominoe.NoShape

self.setShape(Tetrominoe.NoShape)

def shape(self):
“””şekli döndürür”””

return self.pieceShape

def setShape(self, shape):
“””bir şekil ayarlar”””

table = Shape.coordsTable[shape]

for i in range(4):
for j in range(2):
self.coords[i][j] = table[i][j]

self.pieceShape = shape

def setRandomShape(self):
“””rastgele bir şekil seçer”””

self.setShape(random.randint(1, 7))

def x(self, index):
“””x koordinatını döndürür”””

return self.coords[index][0]

def y(self, index):
“””y koordinatını döndürür”””

return self.coords[index][1]

def setX(self, index, x):
“””x koordinatını ayarlar”””

self.coords[index][0] = x

def setY(self, index, y):
“””y koordinatını ayarlar”””

self.coords[index][1] = y

def minX(self):
“””min x değerini döndürür”””

m = self.coords[0][0]
for i in range(4):
m = min(m, self.coords[i][0])

return m

def maxX(self):
“””max x değerini döndürür”””

m = self.coords[0][0]
for i in range(4):
m = max(m, self.coords[i][0])

return m

def minY(self):
“””min y değerini döndürür”””

m = self.coords[0][1]
for i in range(4):
m = min(m, self.coords[i][1])

return m

def maxY(self):
“””max y değerini döndürür”””

m = self.coords[0][1]
for i in range(4):
m = max(m, self.coords[i][1])

return m

def rotateLeft(self):
“””şekli sola döndürür”””

if self.pieceShape == Tetrominoe.SquareShape:
return self

result = Shape()
result.pieceShape = self.pieceShape

for i in range(4):
result.setX(i, self.y(i))
result.setY(i, -self.x(i))

return result

def rotateRight(self):
“””şekli sağa döndürür”””

if self.pieceShape == Tetrominoe.SquareShape:
return self

result = Shape()
result.pieceShape = self.pieceShape

for i in range(4):
result.setX(i, -self.y(i))
result.setY(i, self.x(i))

return result

def main():

app = QApplication([])
tetris = Tetris()
sys.exit(app.exec_())

if __name__ == ‘__main__’:
main()
“`

Adım 2:
Sonrasında, bu dosyayı çalıştırın

“`

python3 tetris.py

Artık Wio Terminal LCD’sinde Tetris oynayabilirsiniz; yön tuşları ve boşluk tuşunu kullanarak oyunu kontrol edebilirsiniz.

PtQtGraph ile Bilimsel Grafikler

PyQtGraph, PyQt4 / PySide ve numpy üzerine inşa edilmiş saf Python grafik ve GUI kütüphanesidir. Matematik, bilim ve mühendislik uygulamalarında kullanılmak üzere tasarlanmıştır.

Şimdi bir bilimsel grafiğin nasıl görüntüleneceğine dair bir örneğe bakalım.

Adım 1:
PyQtGraph için bağımlılıkları yükleyin

sudo apt update
sudo apt install python3 python3-distutils python3-pyqt5 python3-pip python3-numpy -y
sudo pip3 install pyqtgraph

Adım 2:
Aşağıdaki kodu bir Python dosyasına kopyalayın, adını graph.py olarak belirleyin

# -*- coding: utf-8 -*-
"""
Ortak görüntü analizi araçlarını gösterir.
Burada gösterilen birçok özellik, ImageView
widget'ı tarafından zaten sağlanmaktadır, ancak burada kullanıcı arayüzü üzerinde daha ince kontrol sağlayan daha düşük seviyeli bir yaklaşım sunuyoruz.
"""
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
 
 
# Görüntü verilerini sütun öncelikli yerine satır öncelikli olarak yorumla
pg.setConfigOptions(imageAxisOrder='row-major')
 
pg.mkQApp()
win = pg.GraphicsLayoutWidget()
win.setWindowTitle('pyqtgraph örneği: Görüntü Analizi')
 
# Görüntüyü görüntülemek için bir çizim alanı (ViewBox + eksenler)
p1 = win.addPlot(title="")
 
# Görüntü verilerini görüntülemek için öğe
img = pg.ImageItem()
p1.addItem(img)
 
# Bir görüntü bölgesini seçmek için özel ROI
roi = pg.ROI([-8, 14], [6, 5])
roi.addScaleHandle([0.5, 1], [0.5, 0.5])
roi.addScaleHandle([0, 0.5], [0.5, 0.5])
p1.addItem(roi)
roi.setZValue(10)  # ROI'nin görüntünün üstünde çizildiğinden emin olun
 
# İzokurva çizimi
iso = pg.IsocurveItem(level=0.8, pen='g')
iso.setParentItem(img)
iso.setZValue(5)
 
# Kontrast/rengin kontrolü
hist = pg.HistogramLUTItem()
hist.setImageItem(img)
win.addItem(hist)
 
# İzokurva seviyesini ayarlamak için sürüklenebilir çizgi
isoLine = pg.InfiniteLine(angle=0, movable=True, pen='g')
hist.vb.addItem(isoLine)
hist.vb.setMouseEnabled(y=False) # kullanıcı etkileşimini biraz daha kolay hale getirir
isoLine.setValue(0.8)
isoLine.setZValue(1000) # izokurva çizgisini kontrast kontrollerinin üzerine getirin
 
# ROI verilerini görüntülemek için başka bir çizim alanı
win.nextRow()
p2 = win.addPlot(colspan=2)
p2.setMaximumHeight(250)
win.resize(800, 800)
win.show()
 
# Görüntü verilerini oluştur
data = np.random.normal(size=(200, 100))
data[20:80, 20:80] += 2.
data = pg.gaussianFilter(data, (3, 3))
data += np.random.normal(size=(200, 100)) * 0.1
img.setImage(data)
hist.setLevels(data.min(), data.max())
 
# Düzleştirilmiş verilerden izokurvalar oluştur
iso.setData(pg.gaussianFilter(data, (2, 2)))
 
# Görüntünün konumunu ve ölçeğini ayarla
img.scale(0.2, 0.2)
img.translate(-50, 0)
 
# Görüntüyü sığdırmak için yakınlaştır
p1.autoRange()  
 
# Kullanıcı etkileşimini işlemek için geri çağırmalar
def updatePlot():
    global img, roi, data, p2
    selected = roi.getArrayRegion(data, img)
    p2.plot(selected.mean(axis=0), clear=True)
 
roi.sigRegionChanged.connect(updatePlot)
updatePlot()
 
def updateIsocurve():
    global isoLine, iso
    iso.setLevel(isoLine.value())
 
isoLine.sigDragged.connect(updateIsocurve)
 
def imageHoverEvent(event):
    """Fare imlecinin altındaki konumu, pikseli ve değeri gösterir.
    """
    if event.isExit():
        p1.setTitle("")
        return
    pos = event.pos()
    i, j = pos.y(), pos.x()
    i = int(np.clip(i, 0, data.shape[0] - 1))
    j = int(np.clip(j, 0, data.shape[1] - 1))
    val = data[i, j]
    ppos = img.mapToParent(pos)
    x, y = ppos.x(), ppos.y()
    p1.setTitle("pos: (%0.1f, %0.1f)  pixel: (%d, %d)  value: %g" % (x, y, i, j, val))
 
# Görüntüyü özel hover fonksiyonumuzu kullanacak şekilde ayarlayın. 
# Bu genellikle önerilmez (ImageItem'ı alt sınıflandırmalısınız),
# ancak bu kadar basit bir kullanım için işe yarar. 
img.hoverEvent = imageHoverEvent
 
## Qt olay döngüsünü başlatın, etkileşimli modda çalışmıyorsanız veya pyside kullanmıyorsanız.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

Adım 3:
Bundan sonra, bu dosyayı çalıştırın

python3 graph.py

Artık Wio Terminal’de farklı bilimsel grafikler göreceksiniz!

PyQtGraph’ın scripti ile fare çökmesi yaşıyorsanız, raspberry pi’nin masaüstünü devre dışı bırakmak için sudo raspi-config -> Boot options -> Desktop/CLI -> Console Autologin komutunu kullanabilirsiniz.

Ayrıca farklı PyQtGraph scriptlerini farklı ekranlarda aşağıdaki gibi çalıştırabilirsiniz

Usermod SDK

Raspberry Pi Masaüstü GUI’nizi Wio Terminal LCD’sinde görüntülemenin yanı sıra, PC’nizi de Wio Terminal LCD’sinde görüntüleyebilirsiniz. Daha fazla bilgi için buraya tıklayın.

Sonuç

Bu blog için anlatacaklarım bu kadar. Wio Terminal’i Raspberry Pi, Jetson Nano, BeagleBone ve ODYSSEY-86 ile bir ekran olarak kullanabilmeniz için nasıl kuracağınızı net bir şekilde anladığınızı umuyorum! Artık bunu bir sonraki projelerinizde uygulamaya başlayabilirsiniz!

Leave a Reply

Your email address will not be published. Required fields are marked *