image_transfer_raw_as_the_remote_device.py
# この作品はMITライセンスの下で提供されています。
# Copyright (c) 2013-2023 OpenMV LLC. 全著作権所有。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 画像転送 - リモートデバイスとして
#
# このスクリプトは、"image_transfer_raw_as_the_controller_device.py"を実行している別のOpenMV Camとペアで使用するよう作られています
#
# このスクリプトは、あるOpenMV Camから別のOpenMV Camへフレームバッファを転送する方法を示します。
import rpc
import csi
import struct
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
# 上記のRPCライブラリはOpenMV Camにインストールされており、以下のための複数のクラスを提供します
# OpenMV CamをCAN、I2C、SPI、UART、またはLAN/WLAN経由で制御できるようにします。
################################################################
# OpenMV Camを制御するために使用するインターフェースを選択してください。
################################################################
# 以下の行のコメントを外すと、OpenMV CamをCAN経由で制御できるように設定できます。
#
# * message_id - CANバス上でのデータ転送に使用するCANメッセージ(11ビット)。
# * bit_rate - CANビットレート。
# * sample_point - Tseg1/Tseg2比。通常は75%。(50.0、62.5、75.0、87.5など)
#
# 注: マスターとスレーブのメッセージIDおよびCANビットレートは一致させる必要があります。マスターのCAN Highをスレーブの
# CAN Highに、マスターのCAN Lowをスレーブのcan loに接続してください。CANバスは120オームで終端する必要があります。
#
# interface = rpc.rpc_can_slave(message_id=0x7FF, bit_rate=1000000, sample_point=75.0)
# 以下の行のコメントを外すと、OpenMV CamをI2C経由で制御できるように設定できます。
#
# * slave_addr - I2Cアドレス。
#
# 注: マスターとスレーブのアドレスは一致させる必要があります。マスターのsclをスレーブのsclに、マスターのsdaを
# スレーブのsdaに接続してください。外部プルアップ抵抗を使用する必要があります。最後に、両方のデバイスはグラウンドを共有する必要があります。
#
# interface = rpc.rpc_i2c_slave(slave_addr=0x12)
# 以下の行のコメントを外すと、OpenMV CamをSPI経由で制御できるように設定できます。
#
# * cs_pin - スレーブセレクトピン。
# * clk_polarity - アイドル時のクロックレベル(0または1)。
# * clk_phase - クロックの最初のエッジ(0)または2番目のエッジ(1)でデータをサンプリングします。
#
# 注: マスターとスレーブの設定は一致させる必要があります。CS、SCLK、MOSI、MISOをCS、SCLK、MOSI、MISOに接続してください。
# 最後に、両方のデバイスは共通のグラウンドを共有する必要があります。
#
interface = rpc.rpc_spi_slave(cs_pin="P3", clk_polarity=1, clk_phase=0)
# 以下の行のコメントを外すと、OpenMV CamをUART経由で制御できるように設定できます。
#
# * baudrate - シリアルボーレート。
#
# 注: マスターとスレーブのボーレートは一致させる必要があります。マスターのtxをスレーブのrxに、マスターのrxを
# スレーブのtxに接続してください。最後に、両方のデバイスは共通のグラウンドを共有する必要があります。
#
# interface = rpc.rpc_uart_slave(baudrate=7500000)
################################################################
# コールバック
################################################################
img = None
img_ba = None
img_mv = None
# 呼び出されると、pixformatとframesizeを設定してスナップショットを撮影し、
# 画像を格納するためのフレームバッファの形状を返します。
#
# dataは4バイトのpixformatと4バイトのframesizeです。
def raw_image_snapshot(data):
global img, img_ba, img_mv
pixformat, framesize = struct.unpack("<II", data)
csi0.pixformat(pixformat)
csi0.framesize(framesize)
img = csi0.snapshot()
img_ba = img.bytearray()
img_mv = memoryview(img_ba)
return struct.pack(
"<IIII", csi0.width(), csi0.height(), csi0.pixformat(), img.size()
)
def raw_image_read_cb():
interface.put_bytes(img_ba, 5000) # タイムアウト
# オフセットとサイズを指定して、フレームバッファからデータを読み取ります。
# dataが空の場合、RPC呼び出しの終了後に転送がスケジュールされます。
#
# dataは4バイトのsizeと4バイトのoffsetです。
def raw_image_read(data):
if not len(data):
interface.schedule_callback(raw_image_read_cb)
return bytes()
else:
offset, size = struct.unpack("<II", data)
return img_mv[offset:offset + size]
# コールバックを登録します。
interface.register_callback(raw_image_snapshot)
interface.register_callback(raw_image_read)
# すべてのコールバックが登録されたら、
# リモートイベントの処理を開始できます。interface.loop()は戻りません。
interface.loop()