TJ3Bにm5stck UnitV AI Cameraをつなぐ(暫定版)
とりあえず、UnitV AI Cameraを買ってみました。
なぜか。カメラは欲しいけど、Pixyの(たぶん)値段がネックになって?なかなかカメラが普及しないからです。
このUnitVは旧型が2千円ちょっと(現品限りの製造停止品)、新型でも3千円ちょっとで買えます。
※上記は記事作成当時、今(2023.3.29)は5千円超えてます
今回試してるのは旧型です。これと、M5Atom Matrixもいっしょに買いました。こちらも面白いデバイスでいろいろ遊べます。
私はOpenMVとか何にも知らなかったんですが、このCameraを使って色追従しているデモ動画を見つけて、手の出る値段だったのでロボカップジュニアで使えるんではないかと期待して購入してみました。
これと確実につながるM5stack製品でロボット作るのも面白そうだと思いました。
結果、このカメラ本体にI2C slaveのプログラムを記載して、TJ3Bから色の位置データを受信することに成功しました。
まだまだ課題がありますが、とりあえず動いたので、暫定版記事として公開します。
UnitVは、最初どう使うかまったくわからなくて、Firmwareの書き込みソフトとかいろいろ説明すっとばして、いきなり本命のMaixpyというソフトをダウンロードしてUnitVをPCに繋げたら動きました。これについてはいろいろ記事があるんで参考に進めてください。
参考ページ:
UnitV Docs(M5STACKのUnitVのページ)
MaixPyダウンロード(0.2.5)
Firmwareは新しいもののほうが安定するらしいです。結局後からFirmwareも書き込みしましたので古いままで問題あるのかどうかはわかりません。テストぐらいならそのままできました。(2022/05/10 購入後そのままでもMaixPyに接続して動作はしました。)
この時点で、サンプルプログラムを動かして、色設定を変えたら、けっこうちゃんとオレンジボールを認識することを確認。
UnitVはI/O[1]になってもらい、TJ3Bからは、slaveのTJ3B I/O[1]がいるように見せ、代わりにUnitVに応答させることにします。
TJ3Bには手を入れず、他のTJ3Bにさしても動くようにしたいので、C-STYLE上で編集さえすれば動くように、こんなイメージでつなぎます。
TJ3B側のプログラム
# i2c slave test - By: tomoa - 火 1 25 2022
import time
from modules import ws2812
from fpioa_manager import *
fm.register(8)
class_ws2812 = ws2812(8,100)
a = class_ws2812.set_led(0,(5,0,0))
a = class_ws2812.display()
debug = 0
from machine import I2C
I2C_SLAVE_ADDR = 0x18
count=0
register = [1,0,2,0,3,0,4,0,5,0,1,0,2,0,3,0,4,0,5,0,0,0,1,1]
cmdreg = [0,0,0,0,0,0,0,0]
def i2c_on_receive (data):
global count
cmdreg[count]=data
count = count + 1
#if debug : print ("on_receive:", data)
def i2c_on_transmit ():
global count
if cmdreg[1] == 129:
a= cmdreg[2]
if a==10:
a = 0
else:
pass
ret = register[a*2+count]
#if debug : print ("on_transmit, send:", ret,"cmd",a)
count = count + 1
else:
ret=1
return ret
def i2c_on_event (event):
global count
count = 0
#if debug : print("on_event:", event)
#if debug : print ("starting i2c")
i2c = I2C(I2C.I2C1, mode = I2C.MODE_SLAVE, scl=34, sda=35,
freq = 100000, addr = I2C_SLAVE_ADDR,
addr_size = 7,
on_receive = i2c_on_receive,
on_transmit = i2c_on_transmit,
on_event = i2c_on_event)
import sensor
import image
import lcd
import utime
from Maix import GPIO
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((320,120)) #FPSを上げるため上下をカット
sensor.set_vflip(0) #カメラ上下反転
sensor.set_hmirror(0) #カメラ左右反転
sensor.set_auto_gain(0) #検出安定化のためオートゲインオフ
sensor.set_auto_whitebal(0) #検出安定化のためオートホワイトバランスオフ
sensor.run(1)
color = 1
#ターゲットに合わせてRGB(565)LABカラーベースで閾値調整が必要
target_lab_threshold1 =(0, 100, 13, 79, 16, 70) #オレンジ
target_lab_threshold2 =(0, 100, 13, 79, 16, 70) #青
target_lab_threshold3 =(0, 100, 13, 79, 16, 70) #黄
target_lab_threshold = target_lab_threshold1
def color_trace (color):
img=sensor.snapshot()
blobs = img.find_blobs([target_lab_threshold],
x_stride = 2, y_stride = 2, pixels_threshold = 100,
merge = True, margin = 20)
if blobs:
max_area = 0
target = blobs[0]
for b in blobs:
if b.area() > max_area:
max_area = b.area()
target = b
s1 = (target[5]-160)*3+511 #UnitVとM5stackVではカメラ取付向きが違うためxセンター位置を320pix/2,x軸パラメータをtarget[6]→[5]へ変更
s2 = round(target.area()**0.5)*4
tmp=img.draw_rectangle(target[0:4])
tmp=img.draw_cross(target[5], target[6])
c=img.get_pixel(target[5], target[6])
else:
s1 = 0
s2 = 0
#if debug : print(s1, s2)
x = s1.to_bytes(2,'little')
register[0]=x[0]
register[1]=x[1]
x = s2.to_bytes(2,'little')
register[2]=x[0]
register[3]=x[1]
#utime.sleep_ms(100)
a = class_ws2812.set_led(0,(5,5,5))
a=class_ws2812.display()
while True:
if cmdreg[1] == 22:
utime.sleep_ms(1)
cmdreg[1] = 0
color_trace(1)
utime.sleep_ms(5)

コメント
コメントを投稿