スキップしてメイン コンテンツに移動

SDカードの BMP を ST7789 LCD (SPI) に表示

 Raspberry Pi Pico や Pico W などのマイコンでは、カラー画像の表示も意外と簡単に行えます。今回は、SPI接続のフルカラーLCD(ST7789) に、SDカードから読み込んだ BMP画像を表示してみます。

📁 SDカードに保存した画像ファイル(BMP形式)を読み取り、📺 ST7789ディスプレイに転送して表示するという構成です。
小さなディスプレイにお気に入りのイラストやロゴ、写真などを表示できるようになります!

🔌 SPI通信ってなに?

ST7789 ディスプレイとは、SPI(Serial Peripheral Interface)通信を使ってやり取りを行います。

SPIとは、以下のような特徴をもった高速なシリアル通信方式です:

  • 1対1 または 1対多 で使える

  • 複数本の信号線(通常4本)で構成される

    • MOSI(Master Out Slave In):データ送信

    • MISO(Master In Slave Out):データ受信(今回は使わない)

    • SCLK(Serial Clock):クロック信号

    • CS(Chip Select):通信相手の選択

  • フルデュプレックス通信(送受信同時)にも対応(今回は片方向のみ)

📷 今回は、Picoが「マスター」、ST7789が「スレーブ」として動作し、画像データを高速に転送していきます。

ライブラリを入れる手順

🖥️ 1 GitHub からライブラリをダウンロード

  1. ブラウザで https://github.com/devbis/st7789py_mpy を開く

  2. st7789py.py をクリック → 右上 “Raw” を押す

  3. 右クリック → 「名前を付けて保存…」

    • ファイル名はそのまま st7789py.py

    • 保存場所は分かりやすいデスクトップなどで OK

⚙️ 2 Thonny を Pico W 向けにセットアップ

  1. Thonny を起動

  2. 右下ステータスバーをクリック →
    Interpreter「MicroPython (Raspberry Pi Pico)」 に変更

  3. Pico W を USB 接続

    • ファームウェア書き込み済みならそのまま

    • まだの場合は BOOTSEL 押しながら挿し、UF2 を書き込み

📂 3 ファイルで Pico W へアップロード

  1. Thonny 右側 “Files” を開く

  2. 上段 “このコンピュータ” に先ほど保存した st7789py.py があることを確認

  3. 下段 “Raspberry Pi Pico” をクリックして Pico W 内を表示

  4. 方法はどちらでも可

    • ドラッグ & ドロップst7789py.py を下段へ放り込む

    • 右クリック “/にアップロード”

  5. 配置場所の注意

    • ルート / でも /lib フォルダでも OK

    • 迷ったら /lib を作ってそこに入れると整理しやすい

配線図



接続方法:

AE-MICRO-SD-DIPの④VDDをRaspberry Pi Pico Wの3.3Vに接続
AE-MICRO-SD-DIPの⑥GNDをRaspberry Pi Pico WのGNDに接続
AE-MICRO-SD-DIPの⑦DATA0をRaspberry Pi Pico WのGPIO16(MISO)に接続
AE-MICRO-SD-DIPの③CMDをRaspberry Pi Pico WのGPIO19(MOSI)に接続
AE-MICRO-SD-DIPの⑤CLKをRaspberry Pi Pico WのGPIO18(CLK)に接続
AE-MICRO-SD-DIPの②CD/DAT3をRaspberry Pi Pico WのGPIO17(CS)に接続

接続方法(ST7789 LCD):

ST7789のVCCをRaspberry Pi Pico Wの3.3Vに接続
ST7789のGNDをRaspberry Pi Pico WのGNDに接続
ST7789のDINをRaspberry Pi Pico WのGPIO19(MOSI)に接続
ST7789のCLKをRaspberry Pi Pico WのGPIO18(SCK)に接続
ST7789のCSをRaspberry Pi Pico WのGPIO22(CS)に接続
ST7789のDCをRaspberry Pi Pico WのGPIO20(DC)に接続
ST7789のRSTをRaspberry Pi Pico WのGPIO21(RST)に接続

1.ST7789LCDに文字を表示するコード

import machine
import time
import st7789py as st7789  # または st7789

# SPIの初期化(PicoのSPI0を使用)
spi = machine.SPI(
    0,
    baudrate=40_000_000,   # 通信速度40MHz
    polarity=1,            # クロック極性
    phase=1,               # クロック位相
    sck=machine.Pin(18),   # SPIクロックピン(GP18)
    mosi=machine.Pin(19),  # SPIデータ出力ピン(GP19)
    miso=None              # 受信は使わないためNone
)

# 色の定義(16ビットカラー 565フォーマット)
BLACK = 0x0000
WHITE = 0xFFFF

# ST7789 320x240液晶ディスプレイの初期化
tft = st7789.ST7789(
    spi,
    240,                   # 横解像度
    320,                   # 縦解像度
    reset=machine.Pin(21, machine.Pin.OUT),  # リセットピン(GP21)
    dc=machine.Pin(20, machine.Pin.OUT),     # D/Cピン(GP20)
    cs=machine.Pin(22, machine.Pin.OUT),     # チップセレクトピン(GP22)
    xstart=0,              # X方向のオフセット(調整可)
    ystart=0               # Y方向のオフセット(調整可)
)

# ── 3. 全面を 1 回塗りつぶしてから描画 ─────────────────
tft.init()
tft.fill(BLACK)               # ここで必ず全面クリア

# 5x8ドットの簡易フォントのビットマップ定義
# 文字ごとに5バイトあり、1バイトが1列、ビットが1行分
simple_font = {
    ' '  : [0x00, 0x00, 0x00, 0x00, 0x00 ],
    '!'  : [0x00, 0x00, 0x2f, 0x00, 0x00 ],
    '"'  : [0x00, 0x07, 0x00, 0x07, 0x00 ],
    '#'  : [0x14, 0x7f, 0x14, 0x7f, 0x14 ],
    '$'  : [0x24, 0x2a, 0x7f, 0x2a, 0x12 ],
    '%'  : [0x62, 0x64, 0x08, 0x13, 0x23 ],
    '&'  : [0x36, 0x49, 0x55, 0x22, 0x50 ],
    '\'' : [0x00, 0x05, 0x03, 0x00, 0x00 ],
    '('  : [0x00, 0x1c, 0x22, 0x41, 0x00 ],
    ')'  : [0x00, 0x41, 0x22, 0x1c, 0x00 ],
    '*'  : [0x14, 0x08, 0x3e, 0x08, 0x14 ],
    '+'  : [0x08, 0x08, 0x3e, 0x08, 0x08 ],
    ','  : [0x00, 0x00, 0xa0, 0x60, 0x00 ],
    '-'  : [0x08, 0x08, 0x08, 0x08, 0x08 ],
    '.'  : [0x00, 0x60, 0x60, 0x00, 0x00 ],
    '/'  : [0x20, 0x10, 0x08, 0x04, 0x02 ],
    '0'  : [0x3E, 0x51, 0x49, 0x45, 0x3E ],
    '1'  : [0x00, 0x42, 0x7F, 0x40, 0x00 ],
    '2'  : [0x42, 0x61, 0x51, 0x49, 0x46 ],
    '3'  : [0x21, 0x41, 0x45, 0x4B, 0x31 ],
    '4'  : [0x18, 0x14, 0x12, 0x7F, 0x10 ],
    '5'  : [0x27, 0x45, 0x45, 0x45, 0x39 ],
    '6'  : [0x3C, 0x4A, 0x49, 0x49, 0x30 ],
    '7'  : [0x01, 0x71, 0x09, 0x05, 0x03 ],
    '8'  : [0x36, 0x49, 0x49, 0x49, 0x36 ],
    '9'  : [0x06, 0x49, 0x49, 0x29, 0x1E ],
    ':'  : [0x00, 0x36, 0x36, 0x00, 0x00 ],
    ';'  : [0x00, 0x56, 0x36, 0x00, 0x00 ],
    '<'  : [0x08, 0x14, 0x22, 0x41, 0x00 ],
    ':'  : [0x14, 0x14, 0x14, 0x14, 0x14 ],
    '>'  : [0x00, 0x41, 0x22, 0x14, 0x08 ],
    '?'  : [0x02, 0x01, 0x51, 0x09, 0x06 ],
    '@'  : [0x32, 0x49, 0x59, 0x51, 0x3E ],
    'A'  : [0x7C, 0x12, 0x11, 0x12, 0x7C ],
    'B'  : [0x7F, 0x49, 0x49, 0x49, 0x36 ],
    'C'  : [0x3E, 0x41, 0x41, 0x41, 0x22 ],
    'D'  : [0x7F, 0x41, 0x41, 0x22, 0x1C ],
    'E'  : [0x7F, 0x49, 0x49, 0x49, 0x41 ],
    'F'  : [0x7F, 0x09, 0x09, 0x09, 0x01 ],
    'G'  : [0x3E, 0x41, 0x49, 0x49, 0x7A ],
    'H'  : [0x7F, 0x08, 0x08, 0x08, 0x7F ],
    'I'  : [0x00, 0x41, 0x7F, 0x41, 0x00 ],
    'J'  : [0x20, 0x40, 0x41, 0x3F, 0x01 ],
    'K'  : [0x7F, 0x08, 0x14, 0x22, 0x41 ],
    'L'  : [0x7F, 0x40, 0x40, 0x40, 0x40 ],
    'M'  : [0x7F, 0x02, 0x0C, 0x02, 0x7F ],
    'N'  : [0x7F, 0x04, 0x08, 0x10, 0x7F ],
    'O'  : [0x3E, 0x41, 0x41, 0x41, 0x3E ],
    'P'  : [0x7F, 0x09, 0x09, 0x09, 0x06 ],
    'Q'  : [0x3E, 0x41, 0x51, 0x21, 0x5E ],
    'R'  : [0x7F, 0x09, 0x19, 0x29, 0x46 ],
    'S'  : [0x46, 0x49, 0x49, 0x49, 0x31 ],
    'T'  : [0x01, 0x01, 0x7F, 0x01, 0x01 ],
    'U'  : [0x3F, 0x40, 0x40, 0x40, 0x3F ],
    'V'  : [0x1F, 0x20, 0x40, 0x20, 0x1F ],
    'W'  : [0x3F, 0x40, 0x38, 0x40, 0x3F ],
    'X'  : [0x63, 0x14, 0x08, 0x14, 0x63 ],
    'Y'  : [0x07, 0x08, 0x70, 0x08, 0x07 ],
    'Z'  : [0x61, 0x51, 0x49, 0x45, 0x43 ],
    ''   : [0x00, 0x7F, 0x41, 0x41, 0x00 ],
    '\\' : [0x55, 0x2A, 0x55, 0x2A, 0x55 ],
    ''   : [0x00, 0x41, 0x41, 0x7F, 0x00 ],
    '^'  : [0x04, 0x02, 0x01, 0x02, 0x04 ],
    '_'  : [0x40, 0x40, 0x40, 0x40, 0x40 ],
    '`'  : [0x00, 0x01, 0x02, 0x04, 0x00 ],
    'a'  : [0x20, 0x54, 0x54, 0x54, 0x78 ],
    'b'  : [0x7F, 0x48, 0x44, 0x44, 0x38 ],
    'c'  : [0x38, 0x44, 0x44, 0x44, 0x20 ],
    'd'  : [0x38, 0x44, 0x44, 0x48, 0x7F ],
    'e'  : [0x38, 0x54, 0x54, 0x54, 0x18 ],
    'f'  : [0x08, 0x7E, 0x09, 0x01, 0x02 ],
    'g'  : [0x18, 0xA4, 0xA4, 0xA4, 0x7C ],
    'h'  : [0x7F, 0x08, 0x04, 0x04, 0x78 ],
    'i'  : [0x00, 0x44, 0x7D, 0x40, 0x00 ],
    'j'  : [0x40, 0x80, 0x84, 0x7D, 0x00 ],
    'k'  : [0x7F, 0x10, 0x28, 0x44, 0x00 ],
    'l'  : [0x00, 0x41, 0x7F, 0x40, 0x00 ],
    'm'  : [0x7C, 0x04, 0x18, 0x04, 0x78 ],
    'n'  : [0x7C, 0x08, 0x04, 0x04, 0x78 ],
    'o'  : [0x38, 0x44, 0x44, 0x44, 0x38 ],
    'p'  : [0xFC, 0x24, 0x24, 0x24, 0x18 ],
    'q'  : [0x18, 0x24, 0x24, 0x18, 0xFC ],
    'r'  : [0x7C, 0x08, 0x04, 0x04, 0x08 ],
    's'  : [0x48, 0x54, 0x54, 0x54, 0x20 ],
    't'  : [0x04, 0x3F, 0x44, 0x40, 0x20 ],
    'u'  : [0x3C, 0x40, 0x40, 0x20, 0x7C ],
    'v'  : [0x1C, 0x20, 0x40, 0x20, 0x1C ],
    'w'  : [0x3C, 0x40, 0x30, 0x40, 0x3C ],
    'x'  : [0x44, 0x28, 0x10, 0x28, 0x44 ],
    'y'  : [0x1C, 0xA0, 0xA0, 0xA0, 0x7C ],
    'z'  : [0x44, 0x64, 0x54, 0x4C, 0x44 ]
}

# 1文字を描画する関数
# x, y: 描画開始座標(左上)
# c: 描画する文字
# color: 文字色
# scale: 文字の拡大倍率(1=原寸、2=2倍など)
def draw_char(x, y, c, color=WHITE, scale=2):
    if c not in simple_font:
        return  # フォント未定義文字は描画しない
    bitmap = simple_font[c]  # 5列のビットマップを取得
    for col in range(5):     # 5列分ループ
        line = bitmap[col]   # 各列のビットパターン
        for row in range(8): # 8行分ループ
            pixel_on = (line >> row) & 1  # そのビットが立っているか判定
            px_color = color if pixel_on else BLACK  # 1なら文字色、0なら背景色
            # 拡大処理:1ドットをscale×scaleの四角に拡大描画
            for dx in range(scale):
                for dy in range(scale):
                    tft.pixel(x + col*scale + dx, y + row*scale + dy, px_color)

# 文字列を描画する関数
# x, y: 描画開始座標
# text: 描画する文字列
# color: 文字色
# spacing: 文字間隔(スケール単位)
# scale: 拡大倍率
def draw_text(x, y, text, color=WHITE, spacing=1, scale=1):
    for i, c in enumerate(text):
        # 1文字ごとに描画開始位置を計算し描画
        draw_char(x + i * (5 * scale + spacing), y, c, color, scale)

# 最初の文字列を原寸(scale=1)で0,0に描画
text = "Hello World!"
x = 0
y = 0
draw_text(x, y, text, WHITE)

# 次の文字列を2倍サイズで、少し下の位置に描画
text = "Raspberry Pi Pico w"
x = 0
y = 20
draw_text(x, y, text, WHITE, scale=2)

# 以下はループで点滅させる例(コメントアウト中)
# while True:
#     draw_text(x, y, text, WHITE)
#     time.sleep(0.5)
#     draw_text(x, y, text, BLACK)
#     time.sleep(0.5)


処理の流れ

  • 🐍 ライブラリ読み込み
    machine, time, st7789py をインポートして準備。

  • 🔧 SPI を初期化
    Pico W の SPI0(GP18–GP19)を 40 MHz/モード 3 で設定。

  • 🖥️ ST7789 オブジェクト生成
    TFT の解像度 240 × 320 と各 GPIO(DC GP20, RST GP21, CS GP22)を指定して作成。

  • 🚀 ディスプレイ初期化 & 画面クリア
    tft.init()tft.fill(BLACK) で黒塗りし、描画バッファをリセット。

  • 🅰️ 5×8 ドット簡易フォント定義
    ASCII 文字ごとに 5 バイトのビットマップを辞書に格納。

  • ✏️ 1 文字描画関数 draw_char 定義

    • ビットマップを読み取り

    • 各ビットを scale×scale の四角に拡大しながら tft.pixel() で出力。

  • 📝 文字列描画関数 draw_text 定義
    draw_char を文字数ぶん呼び出し、間隔と拡大率を調整して配置。

  • 🖋️ 「Hello World!」を原寸で描画
    draw_text(0, 0, "Hello World!", WHITE)

  • 🖋️ 「Raspberry Pi Pico w」を 2 倍で描画
    draw_text(0, 20, "...", WHITE, scale=2) で大きな文字を表示。

2.基本図形(円・線・三角・四角・星)とランダム色表示サンプル

import machine
import time
import st7789py as st7789
import random
import math  # 星描画で使用

# SPI初期化(Pico SPI0、GPIO18=SCK、GPIO19=MOSI)
spi = machine.SPI(0, baudrate=40_000_000, polarity=1, phase=1,
                  sck=machine.Pin(18), mosi=machine.Pin(19), miso=None)

# ST7789初期化 240×320画面サイズ
tft = st7789.ST7789(spi, 240, 320,
                    reset=machine.Pin(21, machine.Pin.OUT),
                    dc=machine.Pin(20, machine.Pin.OUT),
                    cs=machine.Pin(22, machine.Pin.OUT),
                    xstart=0, ystart=0)

WHITE = 0xFFFF
BLACK = 0x0000

tft.init()         # ディスプレイ初期化
tft.fill(BLACK)    # 画面全体を黒でクリア

# Bresenhamのアルゴリズムを使った直線描画関数
def draw_line(x0, y0, x1, y1, color):
    dx = abs(x1 - x0)     # X軸の差分
    dy = -abs(y1 - y0)    # Y軸の差分(符号を反転)
    sx = 1 if x0 < x1 else -1  # Xの進む方向
    sy = 1 if y0 < y1 else -1  # Yの進む方向
    err = dx + dy         # 誤差初期値
    while True:
        tft.pixel(x0, y0, color)  # 指定座標にピクセルを描画
        if x0 == x1 and y0 == y1: # 終点に到達したら終了
            break
        e2 = 2 * err
        if e2 >= dy:  # 誤差調整・X軸方向移動
            err += dy
            x0 += sx
        if e2 <= dx:  # 誤差調整・Y軸方向移動
            err += dx
            y0 += sy

# Bresenhamの円描画アルゴリズムを使った円の輪郭描画関数
def draw_circle(x0, y0, radius, color):
    x = radius
    y = 0
    err = 0

    while x >= y:
        # 円の8方向の対称点を描画
        tft.pixel(x0 + x, y0 + y, color)
        tft.pixel(x0 + y, y0 + x, color)
        tft.pixel(x0 - y, y0 + x, color)
        tft.pixel(x0 - x, y0 + y, color)
        tft.pixel(x0 - x, y0 - y, color)
        tft.pixel(x0 - y, y0 - x, color)
        tft.pixel(x0 + y, y0 - x, color)
        tft.pixel(x0 + x, y0 - y, color)

        y += 1
        if err <= 0:
            err += 2 * y + 1
        if err > 0:
            x -= 1
            err -= 2 * x + 1

# 四角形の塗りつぶし描画関数
def draw_filled_rect(x, y, w, h, color):
    for i in range(x, x + w):
        for j in range(y, y + h):
            tft.pixel(i, j, color)

# 等辺三角形を下向きに描画する関数
def draw_triangle(x0, y0, size, color):
    # 頂点(x0,y0)から下方向に広がる三角形
    for i in range(size):
        for j in range(-i, i + 1):
            tft.pixel(x0 + j, y0 + i, color)

# 星形を簡易的に5本の放射線で描く関数
def draw_star(x0, y0, size, color):
    angles = [0, 72, 144, 216, 288]  # 5方向の角度(度)
    cx, cy = x0, y0
    length = size
    tft.pixel(cx, cy, color)  # 星の中心点を描画
    for angle in angles:
        rad = math.radians(angle)
        x1 = int(cx + length * math.cos(rad))
        y1 = int(cy + length * math.sin(rad))
        draw_line(cx, cy, x1, y1, color)  # 中心から外側に線を描く

# 画面枠線(四辺)をそれぞれ異なる色で描画
draw_line(10, 10, 230, 10, st7789.color565(255, 0, 0))      # 上辺(赤)
draw_line(10, 10, 10, 310, st7789.color565(0, 255, 0))      # 左辺(緑)
draw_line(10, 310, 230, 310, st7789.color565(0, 0, 255))    # 下辺(青)
draw_line(230, 10, 230, 310, st7789.color565(255, 255, 255))# 右辺(白)

# 円の中心座標設定(画面中央)
cx, cy = 120, 160

# 半径100から5まで4ずつ減らしながら色をランダムに変えて大きい円から小さい円まで順に描画
for r in range(100, 4, -4):
    color = st7789.color565(random.getrandbits(8), random.getrandbits(8), random.getrandbits(8))
    draw_circle(cx, cy, r, color)
    time.sleep(0.2)

# 半径2のごく小さい赤い円を描画
draw_circle(cx, cy, 2, st7789.color565(255, 0, 0))
time.sleep(1)

# 画面を真っ黒でクリア
tft.fill(BLACK)
time.sleep(0.5)

# ランダムに50個の図形を描画
shapes = ['circle', 'triangle', 'rect', 'star']

for _ in range(50):
    shape = random.choice(shapes)  # 図形種類をランダムに選択
    x = random.randint(20, 220)    # X座標をランダム指定
    y = random.randint(20, 300)    # Y座標をランダム指定
    # RGBそれぞれ0〜255のランダム色を16bitカラーに変換
    color = st7789.color565(random.getrandbits(8), random.getrandbits(8), random.getrandbits(8))
    size = random.randint(10, 30)  # サイズを10〜30でランダム指定

    # 選ばれた図形に応じて描画関数を呼び出す
    if shape == 'circle':
        draw_circle(x, y, size, color)
    elif shape == 'triangle':
        draw_triangle(x, y, size, color)
    elif shape == 'rect':
        draw_filled_rect(x, y, size, size, color)
    elif shape == 'star':
        draw_star(x, y, size, color)
   
    time.sleep(0.3)  # 描画間隔を0.3秒あける

# メインループ(何もしない)
while True:
    time.sleep(1)



3.SDカードの BMP を ST7789 LCD (SPI) に表示

import machine, os, sdcard, uos, st7789py as st7789
import time, struct

# ── 1. SDカード初期化(SPI0, 400kHz・mode0)───────────────────────
spi = machine.SPI(
    0, baudrate=400_000, polarity=0, phase=0,
    sck=machine.Pin(18), mosi=machine.Pin(19), miso=machine.Pin(16)
)
sd_cs = machine.Pin(17, machine.Pin.OUT, value=1)

# 電源安定待機 & SDカード初期化リカバリ(80クロック)
time.sleep_ms(100)
spi.write(b'\xFF' * 10)  # CS=Highで80クロック送信(10byte

# SDカード初期化 & マウント
sd = sdcard.SDCard(spi, sd_cs)
uos.mount(sd, "/sd")
print("SD内容:", os.listdir("/sd"))

# ── 2. SPI再設定(ST7789用:40MHz・mode3)──────────────────────
spi.init(baudrate=40_000_000, polarity=1, phase=1)

# ST7789 初期化
tft = st7789.ST7789(
    spi, 240, 320,
    reset=machine.Pin(21, machine.Pin.OUT),
    dc   =machine.Pin(20, machine.Pin.OUT),
    cs   =machine.Pin(22, machine.Pin.OUT),
    xstart=0, ystart=0
)
tft.init()
tft.fill(0)

# ── 3. 24bit BMP → RGB565 変換 & 表示関数 ─────────────────────
def rgb565(r, g, b):
    return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)

def show_bmp(fname, x=0, y=0):
    path = "/sd/" + fname
    with open(path, "rb") as f:
        if f.read(2) != b"BM":
            print("BMPではありません"); return
        f.seek(10); ofs = struct.unpack("<I", f.read(4))[0]
        f.seek(18); w   = struct.unpack("<I", f.read(4))[0]
        h   = struct.unpack("<I", f.read(4))[0]
        f.seek(28); bpp = struct.unpack("<H", f.read(2))[0]
        f.seek(30); cmp = struct.unpack("<I", f.read(4))[0]
        if bpp != 24 or cmp != 0:
            print("非圧縮24bit BMPのみ対応"); return

        pad = (w * 3 + 3) & ~3
        buf = bytearray(w * 2)

        for row in range(h):
            f.seek(ofs + (h - 1 - row) * pad)
            line = f.read(w * 3)
            for col in range(w):
                b = line[col*3]
                g = line[col*3+1]
                r = line[col*3+2]
                c = rgb565(r, g, b)
                buf[col*2]   = (c >> 8) & 0xFF
                buf[col*2+1] =  c       & 0xFF
            tft.blit_buffer(buf, x, y + row, w, 1)

# ── 4. BMP画像表示 ──────────────────────────────────────────────
show_bmp("2168_0.bmp", 0, 0)

# ── 5. SDカードの安全な終了処理 ───────────────────────────────
uos.umount("/sd")                              # アンマウント
sd_cs.init(machine.Pin.IN, machine.Pin.PULL_UP)  # CSピンを入力に戻す
spi.deinit()                                   # SPI停止
sd = None                                      # オブジェクト解放






コメント

このブログの人気の投稿

Raspberry Pi Pico Wを使ってみよう

   Raspberry Pi Pico W(ラズベリーパイ ピコ ダブリュー) は、英国 Raspberry Pi 財団が 2022 年に発売した Wi-Fi 搭載マイコンボードです。従来の「Raspberry Pi」と聞くと Linux が動くシングルボードコンピュータ(SBC)を思い浮かべがちですが、Pico W は マイクロコントローラ (MCU)に分類され、いわゆる “組み込み開発” を手軽に始められるデバイスです。搭載 MCU はデュアルコア Arm Cortex-M0+(133 MHz 動作)の RP2040 。ここに Infineon 製 CYW43439 チップが追加され、 2.4 GHz IEEE 802.11 b/g/n Wi-Fi(BLE 対応 FW も提供中) が使えるのが最大の特徴です。  開発言語は MicroPython や CircuitPython が真っ先に紹介されることが多いのですが、 公式 Pico SDK を使えば C/C++ でも本格的に開発 できます。SDK は CMake ベースで Windows/macOS/Linux いずれでも利用可能。さらに、Arduino Core RP2040 が整備されたことで Arduino IDE 2.x からも “スケッチ感覚” で書き込みが可能 になりました。したがって、 「まずは Python でサッと試す」 「より高速化や省メモリ化が必要になったら C/C++ へ移行」 といった二段構えの学習ルートが取れるのが魅力です。 メニュー(基礎編) 01. Raspberry Pi Pico Wの開発環境を整える。 02. スイッチで 発光ダイオード(LED) を点灯・消灯させる 03. タイマーで発光ダイオード(LED)を1秒ごとに点滅させる 04. シリアル通信(オウム返し ) 05. シリアル通信(発光ダイオードの点灯・消灯) 06. サーボモーターを動かしてみよう(SG90制御入門) 07. DCモータを動かす(PWM) 08. IRリモートでRGBLED点灯 09. アナログ電圧を測定する(ADCの基本) 10. GPIO割り込み処理 11. リレーを駆動してLEDを制御する 12. DFPlayer で MP3 再生 13. 7 セグ 4 ...

スイッチで発光ダイオード(LED)を点灯・消灯させる

 スイッチを使って発光ダイオード(LED)を制御してみましょう。今回は、スイッチをオンにすると LED が点灯し、オフにすると消灯するように動作させます。もちろん、スイッチと LED を直接接続するのではなく、適切な回路を介して制御します。 1.回路 GPIO16 はデジタル入力として使用し、内部プルアップを有効にします。GPIO15 は出力として設定します。なお、接続には 1kΩ(1キロオーム)の抵抗を使用します。 【ソースコード】 # スイッチで LED を ON / OFF する簡単な例 #   GPIO15 : LED(出力)— LOW で消灯、HIGH で点灯 #   GPIO16 : スイッチ(入力)— 内部プルアップ抵抗を使用 # # ※ 配線例 #   LED のアノード → 1 kΩ 抵抗 → GPIO15 #   LED のカソード → GND #   スイッチ片側   → GPIO16 #   スイッチ反対側 → GND # # ★ 動作 #   スイッチを押す(GPIO16 が LOW)   → LED 点灯 #   スイッチを離す(GPIO16 が HIGH) → LED 消灯 from machine import Pin    # GPIO 制御ライブラリ import utime               # 時間関連(今回は使用しないが拡張用に読み込み) led = Pin ( 15 , Pin.OUT)                 # GPIO15 を出力モードに設定(LED 用) sw   = Pin ( 16 , Pin.IN, Pin.PULL_UP)     # GPIO16 を入力モード+内部プルアップ有効 while True:     if sw. value () == 1 :      # プルアップなので押していないときは 1   ...

シリアル通信(オウム返し)

 Raspberry Pi Pico Wは単体で使うのも便利ですが、パソコンや他のマイコンなど、さまざまな機器と通信できるとさらに活用の幅が広がります。 そこで今回は「シリアル通信」について紹介します。 まずは、パソコンから送られてきたデータをPico Wが受け取り、同じデータをそのままパソコンに送り返す、いわゆる「オウム返し(エコー)」を実装してみましょう。 シリアル通信とは? シリアル通信は、マイコンとパソコンや他の機器がデータを1ビットずつ順番に送受信する通信方式です。Raspberry Pi Pico WではUART(Universal Asynchronous Receiver/Transmitter)というハードウェアを使って実現します。 接続回路  id      TX       RX        baudrate     parity    stopbit  0  GPIO0 GPIO1   9600  なし  1  1  GPIO4 GPIO5   9600  なし  1 今回はUART1(GPIO4:TX、GPIO5:RX)を使用します。 ソースコード例 from machine import UART, Pin # UART1ポートを9600bpsで初期化(ボーレートを指定) sirial = UART ( 1 , 9600 ) # UARTの詳細設定: 9600bps 、データビット8、パリティ無し、ストップビット1で初期化 sirial. init ( 9600 , bits = 8 , parity = None, stop = 1 ) # UARTで文字列を送信する(※MicroPythonではバイト列で送るのが正しいため b '' にしたほうが安全) sirial. write (b 'Hello World \n\r ' )  # 起動時に「Hello World」を送信 # メインループ while True:     # 受信バッファにデータが存在するかチェック     if sirial. any () > 0 : ...