0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USBからデータを受け取る

Posted at

Raspberrypi pico でデータを受信し、LCDディスプレイに表示

開発環境

  • Raspberrypi_pico: thonny
  • PCからの送信: メモ帳

Pin配置

ラズベリーパイピコ.jpg

✅ GPIOと物理ピン対応表

Raspberry Pi Picoでは、GPIO番号物理ピン番号が異なるため注意が必要です。

物理ピン GPIO番号 用途例

| 40 | GPIO21 | 未使用またはI2C切替用 |
| 38 | GPIO20 | 未使用またはI2C切替用 |
| 22 | GPIO17 | SCL(I2Cクロック) |
| 21 | GPIO16 | SDA(I2Cデータ) |


✅ I2C 初期化コード(GPIO16 / GPIO17 使用)

from machine import I2C, Pin
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)  # GPIO17=SCL, GPIO16=SDA
print(i2c.scan())  # I2Cデバイスが見つかればアドレスが表示される


```main.py
from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd
import sys

# LCDの初期化
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)
lcd = I2cLcd(i2c, 0x3F, 2, 16)
lcd.clear()
lcd.putstr("USB Listening...")

# ASCIIフィルター関数(英数字+記号のみ許可)
def ascii_only(text):
    return ''.join(c for c in text if 32 <= ord(c) <= 126)

# 入力バッファ
buffer = ""

# メインループ
while True:
    try:
        char = sys.stdin.read(1)
        if char == '\n':
            clean_text = ascii_only(buffer)
            lcd.clear()
            lcd.putstr(clean_text[:16])  # 16文字以内にカット
            print("Received:", clean_text)
            buffer = ""
        else:
            buffer += char
    except Exception as e:
        lcd.clear()
        lcd.putstr("Error occurred")
        print("Error:", e)
        break

lib/pico_ic2_lcd.py

Raspberrypi pico 内に lib フォルダを作成し、pico_ic2_lcd.py を作成し以下のコードを書く

pico_ic2_lcd.py
# forked from https://github.com/T-622/RPI-PICO-I2C-LCD/
import utime
import gc

from lcd_api import LcdApi
from machine import I2C

# PCF8574 pin definitions
MASK_RS = 0x01       # P0
MASK_RW = 0x02       # P1
MASK_E  = 0x04       # P2

SHIFT_BACKLIGHT = 3  # P3
SHIFT_DATA      = 4  # P4-P7

class I2cLcd(LcdApi):
    
    #Implements a HD44780 character LCD connected via PCF8574 on I2C

    def __init__(self, i2c, i2c_addr, num_lines, num_columns):
        self.i2c = i2c
        self.i2c_addr = i2c_addr
        self.i2c.writeto(self.i2c_addr, bytes([0]))
        utime.sleep_ms(20)   # Allow LCD time to powerup
        # Send reset 3 times
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        utime.sleep_ms(5)    # Need to delay at least 4.1 msec
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        utime.sleep_ms(1)
        self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
        utime.sleep_ms(1)
        # Put LCD into 4-bit mode
        self.hal_write_init_nibble(self.LCD_FUNCTION)
        utime.sleep_ms(1)
        LcdApi.__init__(self, num_lines, num_columns)
        cmd = self.LCD_FUNCTION
        if num_lines > 1:
            cmd |= self.LCD_FUNCTION_2LINES
        self.hal_write_command(cmd)
        gc.collect()

    def hal_write_init_nibble(self, nibble):
        # Writes an initialization nibble to the LCD.
        # This particular function is only used during initialization.
        byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA
        self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytes([byte]))
        gc.collect()
        
    def hal_backlight_on(self):
        # Allows the hal layer to turn the backlight on
        self.i2c.writeto(self.i2c_addr, bytes([1 << SHIFT_BACKLIGHT]))
        gc.collect()
        
    def hal_backlight_off(self):
        #Allows the hal layer to turn the backlight off
        self.i2c.writeto(self.i2c_addr, bytes([0]))
        gc.collect()
        
    def hal_write_command(self, cmd):
        # Write a command to the LCD. Data is latched on the falling edge of E.
        byte = ((self.backlight << SHIFT_BACKLIGHT) |
                (((cmd >> 4) & 0x0f) << SHIFT_DATA))
        self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytes([byte]))
        byte = ((self.backlight << SHIFT_BACKLIGHT) |
                ((cmd & 0x0f) << SHIFT_DATA))
        self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytes([byte]))
        if cmd <= 3:
            # The home and clear commands require a worst case delay of 4.1 msec
            utime.sleep_ms(5)
        gc.collect()

    def hal_write_data(self, data):
        # Write data to the LCD. Data is latched on the falling edge of E.
        byte = (MASK_RS |
                (self.backlight << SHIFT_BACKLIGHT) |
                (((data >> 4) & 0x0f) << SHIFT_DATA))
        self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytes([byte]))
        byte = (MASK_RS |
                (self.backlight << SHIFT_BACKLIGHT) |
                ((data & 0x0f) << SHIFT_DATA))      
        self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E]))
        self.i2c.writeto(self.i2c_addr, bytes([byte]))
        gc.collect()

コードを書き終えたら実行して thonny を閉じます。

Thonnyのシェル(REPL)は、USBシリアル(仮想COMポート)を常時占有しています
つまり、他のプログラム(pyserialなど)からはCOMポートを開けなくなるのです
これは Windows のCOMポート仕様による制限で、同時に1つのアプリしかCOMポートを開けません

PCからデータ送信するコード

PCから実行するPythonはコマンドプロンプトから実行しました

python usb_post_form.py
usb_post_form.py
import tkinter as tk
import serial
import time

# COMポート設定(環境に合わせて変更)
PORT = 'COM6'
BAUD = 9600

def send_message():
    message = text_entry.get()
    if not message:
        status_label.config(text="メッセージが空です")
        return
    try:
        ser = serial.Serial(PORT, BAUD)
        time.sleep(2)  # 接続安定待ち
        ser.write((message + '\n').encode('utf-8'))  # 改行を忘れずに
        ser.close()
        status_label.config(text="送信成功")
    except Exception as e:
        status_label.config(text=f"送信失敗: {e}")

# ウィンドウの作成
root = tk.Tk()
root.title("LCD送信フォーム")

# メッセージ入力欄
text_entry = tk.Entry(root, width=30, font=('Arial', 14))
text_entry.pack(pady=10)

# 送信ボタン
send_button = tk.Button(root, text="送信", command=send_message, width=20, height=2)
send_button.pack(pady=10)

# ステータス表示
status_label = tk.Label(root, text="", fg="blue")
status_label.pack(pady=10)

# 実行
root.mainloop()

IMG_6003.jpg

cmd.png

IMG_6006.jpg

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?