ラズパイピコ&LCDモジュールで文字の大きさを変更する

QOL -生活-

前回に続いて、ラズパイピコでのLCD表示を触っていく。

引数で文字サイズを変えられないか

調べていくと、サンプルコード中のframebufライブラリは、デフォルトでフォントサイズの変更をサポートしていないとのこと。

ということで、少しコードを変える。

コードを書き換える

スケールアップ関数を追加する。

from machine import Pin, SPI, PWM
import framebuf
import time

# 定数の設定(LCDのピン番号)
BL = 13
DC = 8
RST = 12
MOSI = 11
SCK = 10
CS = 9

class LCD_1inch14(framebuf.FrameBuffer):
    def __init__(self):
        # LCDの解像度
        self.width = 240
        self.height = 135
        
        # ピンの初期化
        self.cs = Pin(CS, Pin.OUT)
        self.rst = Pin(RST, Pin.OUT)
        
        # SPI通信の初期化
        self.cs(1)
        self.spi = SPI(1)
        self.spi = SPI(1,1000_000)
        self.spi = SPI(1,10000_000,polarity=0, phase=0,sck=Pin(SCK),mosi=Pin(MOSI),miso=None)
        self.dc = Pin(DC,Pin.OUT)
        self.dc(1)
        
        # フレームバッファの作成
        self.buffer = bytearray(self.height * self.width * 2)
        super().__init__(self.buffer, self.width, self.height, framebuf.RGB565)
        
        # LCDの初期化
        self.init_display()
        
        # カラー定義
        self.red = 0x07E0
        self.green = 0x001f
        self.blue = 0xf800
        self.white = 0xffff

    def write_cmd(self, cmd):
        """LCDにコマンドを送信"""
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([cmd]))
        self.cs(1)

    def write_data(self, buf):
        """LCDにデータを送信"""
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(bytearray([buf]))
        self.cs(1)

    def init_display(self):
        """LCDの初期設定"""
        self.rst(1)
        self.rst(0)
        self.rst(1)
        
        self.write_cmd(0x36)
        self.write_data(0x70)

        self.write_cmd(0x3A) 
        self.write_data(0x05)

        self.write_cmd(0xB2)
        self.write_data(0x0C)
        self.write_data(0x0C)
        self.write_data(0x00)
        self.write_data(0x33)
        self.write_data(0x33)

        self.write_cmd(0xB7)
        self.write_data(0x35) 

        self.write_cmd(0xBB)
        self.write_data(0x19)

        self.write_cmd(0xC0)
        self.write_data(0x2C)

        self.write_cmd(0xC2)
        self.write_data(0x01)

        self.write_cmd(0xC3)
        self.write_data(0x12)   

        self.write_cmd(0xC4)
        self.write_data(0x20)

        self.write_cmd(0xC6)
        self.write_data(0x0F) 

        self.write_cmd(0xD0)
        self.write_data(0xA4)
        self.write_data(0xA1)

        self.write_cmd(0xE0)
        self.write_data(0xD0)
        self.write_data(0x04)
        self.write_data(0x0D)
        self.write_data(0x11)
        self.write_data(0x13)
        self.write_data(0x2B)
        self.write_data(0x3F)
        self.write_data(0x54)
        self.write_data(0x4C)
        self.write_data(0x18)
        self.write_data(0x0D)
        self.write_data(0x0B)
        self.write_data(0x1F)
        self.write_data(0x23)

        self.write_cmd(0xE1)
        self.write_data(0xD0)
        self.write_data(0x04)
        self.write_data(0x0C)
        self.write_data(0x11)
        self.write_data(0x13)
        self.write_data(0x2C)
        self.write_data(0x3F)
        self.write_data(0x44)
        self.write_data(0x51)
        self.write_data(0x2F)
        self.write_data(0x1F)
        self.write_data(0x1F)
        self.write_data(0x20)
        self.write_data(0x23)
        
        self.write_cmd(0x21)

        self.write_cmd(0x11)

        self.write_cmd(0x29)
    
    def show(self):
        """LCDにバッファの内容を描画"""
        self.write_cmd(0x2A)
        self.write_data(0x00)
        self.write_data(0x28)
        self.write_data(0x01)
        self.write_data(0x17)
        
        self.write_cmd(0x2B)
        self.write_data(0x00)
        self.write_data(0x35)
        self.write_data(0x00)
        self.write_data(0xBB)
        
        self.write_cmd(0x2C)
        
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(self.buffer)
        self.cs(1)
    
    def text_scaled(self, text, x, y, color, scale=1):
        """拡大表示するテキスト描画関数"""
        # 一時的なフレームバッファを作成(文字描画用)
        temp_fb = framebuf.FrameBuffer(bytearray(8 * len(text) * 8), 8 * len(text), 8, framebuf.MONO_HLSB)
        temp_fb.fill(0)  # 背景をクリア
        temp_fb.text(text, 0, 0, 1)  # 文字を描画
        
        # 各ピクセルを拡大して描画
        for yy in range(8):
            for xx in range(8 * len(text)):
                if temp_fb.pixel(xx, yy):  # 文字のピクセルがある場合
                    self.fill_rect(x + xx * scale, y + yy * scale, scale, scale, color)
    
if __name__ == '__main__':
    # LCDのバックライト設定
    pwm = PWM(Pin(BL))
    pwm.freq(1000)
    pwm.duty_u16(32768)  # 最大値65535の半分

    # LCDの初期化
    LCD = LCD_1inch14()
    LCD.fill(LCD.white)  # 画面を白でクリア
    
    # テキストを拡大表示
    LCD.text_scaled("Raspberry", 20, 20, LCD.blue, scale=3)
    LCD.text_scaled("PicoGo", 20, 60, LCD.green, scale=2)
    LCD.text_scaled("Pico-LCD-1.14", 20, 100, LCD.red, scale=1)
    
    # 画面更新
    LCD.show()

以下の部分がスケールアップ関数。

def text_scaled(self, text, x, y, color, scale=1):
        """拡大表示するテキスト描画関数"""
        # 一時的なフレームバッファを作成(文字描画用)
        temp_fb = framebuf.FrameBuffer(bytearray(8 * len(text) * 8), 8 * len(text), 8, framebuf.MONO_HLSB)
        temp_fb.fill(0)  # 背景をクリア
        temp_fb.text(text, 0, 0, 1)  # 文字を描画
        
        # 各ピクセルを拡大して描画
        for yy in range(8):
            for xx in range(8 * len(text)):
                if temp_fb.pixel(xx, yy):  # 文字のピクセルがある場合
                    self.fill_rect(x + xx * scale, y + yy * scale, scale, scale, color)

実行してみると、文字のサイズが変わった。

文字が荒いのは、8×8ピクセル内での文字を無理やりスケールアップしているため。

メモリが限られるため、大元の文字のサイズは変えない方が良いかもしれないとのこと。

以下ChatGPTの回答。

MicroPythonのframebufモジュールでは、デフォルトで用意されているフォントサイズは1種類(8×8)しかありません。
スケールアップを使わずにフォントサイズを変更するには、以下の方法があります。

方法1: 事前に大きなフォント画像を用意して描画
framebufではカスタムフォントがサポートされていないため、画像としてフォントデータを作成し、LCDに描画する方法が有効です。
BMPやPBM形式のフォント画像をSDカードやフラッシュメモリに保存し、それを読み込んで表示する。
方法2: フォントデータをプログラム内に埋め込む
文字ごとにピクセルデータを配列で定義し、特定の座標に描画する方法です。
方法3: 他のライブラリを使用する
lvgl (LittlevGL) や Adafruit_GFX のようなグラフィックライブラリを使用することで、異なるサイズのフォントを利用できます。
ただし、MicroPythonではメモリが限られるため、使用するフォントのサイズには注意が必要です。

次回以降、もう少しきれいな文字表示ができないか検討してみる。

タイトルとURLをコピーしました