Visual Scripting(VS)の存在意義それほどないかもね

Unity解説本も生成A.I前提で書籍が記述されてるよ

この本一通り実行してみましたが、別にUnityだけじゃないけど、生成A.I標準の世界では、タイトル通りのことが言えると思う

VSも結局のところ、ブロック機能の種類が多いからそれらを覚えるよりも直接C#のコード書いた方が開発速度も速いと思うよ

あと気づいた点は、今のUnityのtutorialはTextMeshPro使っているけど、現在の最新はUI ToolKitだろうから、現状は併存なのだろうけどtutorialはちょっと古めかもしれない

いずれにしてもUnity6になってゲームエンジンとしてはコードを書くことはそれほど比重がないとも言える、ゲームオブジェクトのコンポーネントの多くは設定やエディタあるいはshader graph(見た目)やanimator(動き)のようなVSライクな記述方法で解決がつく割合が増えているから、コードはロジックの記述に限定とも言える

 

admin

ソーラーシステムの電圧ログを取ってみる

車のバッテリー上がり防止用のソーラー充電器のログ取るために多少の改造

① 電池電圧、バッテリー電圧、ソーラーパネル電圧の3チャネルのデートを取得するようにした

② 取り回し改善のために最低限の構造変更

・配線保護のために同サイズの基板をネジで浮かせて取り付ける、電池は浮かせた基板に両面テープで貼り付け

 

 

で、パワコンのところで接続したところ

これでしばらくデータ取ってみる

 

admin

Unity解説本も生成A.I前提で書籍が記述されてるよ

Unity6になって結構変更も多く、かつパッケージの従来互換もなくなったようですが、初めてのUnity本でUnity6の入門本を買ってみた

Unity6になって内部の構造も大幅に変更されて、そのために従来と互換は捨ててます

そもそもUnity Hubから開けるTutorialも従来と変わってるんだけども、この本自体の記述スタイルは、

・VSではなくてC#スクリプトの記述で作成するような形式、スクリプトの量は非常に少ないけどもC#の知識を前提にしないためにスクリプト生成には生成A.I使ってるし、またテクスチャーの生成には画像生成A.I使ってるよ

・実は生成A.I自体が本の執筆時点、おそらく2024秋頃と思うけど、その時点から画像生成A.I(ChatGPTでmaterialのtexture用に画像生成させる)も明らかに進化しているよ

ということで、この先こういう本も生成A.I前提で記述されていくような気がする、生成A.Iの進歩に追いつかない懸念はあるけどね

 

admin

lightsleep有効での電池電圧変化(ラズピコrp2040データロガー)

ようやくそれらしいデータが取れた、何しろ省電力有効にすると電池寿命長くなるから、時間かかると言えば当然と言えば当然ですが

<条件>

・電池:NiH電池の二直、容量1000mAH

・ラズピコ:rp2040のWi-Fi無しモデル

・サンプル周期:10分間隔で電池電圧をSDカードに記録

電池の放電電圧の開始電圧は比較のため合わせてあります(省電力有効は満充電から、省電力無効は放電途中からの測定だから)

SDカードのファイルの見え方、

10月7日の午後から今日の午後までの実行結果、大勢に影響ないけどファイルの日付がなぜこうなるかは理解できていない

青は省電力がほぼ効かない状態での測定、緑はlighsleepをデータサンプリング間隔(10分)で設定してとったデータ

電流測定では22mA vs 4mAだったけど、電池電圧の変化はそれ以上に見えてます、なぜだろう?

 

admin

Karel言語

Maker Faire Tokyo 2025でチェコの人たちが、四十年ぐらい前のマイコンボードを展示していましたが、そこのブラウン管ディスプレイに表示されていたのがKarel言語で記述されていると言っていました

じゃKarel言語って何なのと思ったのと、四十年前の言語が今も生き残っているのかというのは自然な疑問

実はちゃんと生き残っているようで、Pythonでも実装されていました

Pythonでの動かし方は、

% pip install stanfordkarel

でstanfordkarelをインストールする、なぜstanfordの名前がついているかというと、stanfordで学生の授業に使われたという経緯があるからのようです

以下のコードを見ればわかるように、forループはPythonのような形式、ロボットを動かすところは直感的なステートメントになっています

from stanfordkarel import *

def main():
    n = 4
    for i in range(n):
        while front_is_clear():
            move()
        turn_left()

if __name__ == "__main__":
    run_karel_program()

実行は、

% python karel.py

で起動しますが、ソースを見てわかるようにmain()が直接起動されるわけではなくて、run_karel_program()でプレイグラウンドが起動されて、起動されたプレイグラウンドからmain()を呼び出す形式を取ります

以下は実行させてみた動画

実はプレイグラウンドのカスタマイズもできるようです

KarelのキャラクタがGopherに似てる気がしますが、直接の関連は無いようで親しみやすいキャラクタを使うというところが共通点のようです

小中学生のテキストベースの学習言語としても面白いかなと思います

 

admin

そこにも落とし穴あったか、(ラズピコmicroPython)

ラズピコのmicroPythonで以下のようなコードではRTC割り込み受け付けられません

つまりlight sleep()で無限に待つ設定にして、RTC割り込みを受けようとしてもラズピコのmicroPython実装では、lightsleep中は他の割り込み受け付けは機能しません

    try:
        while True:
            if alarm_triggered:
                alarm_triggered = False
                clear_alarm_flag()
                time.sleep_ms(5)
                set_alarm()
                value1 = round((adc0.read_u16() >> 4) * 3.3 * 3 / 4096, 2)
                value2 = round((adc1.read_u16() >> 4) * 3.3 * 2 / 4096, 2)
                print(value1, value2)
                if value2 > 2.0:
                    logger.write(rtc, value1, value2)
                machine.lightsleep()
    except KeyboardInterrupt:
        print("terminated")

従って、やりたい機能を実装しようとすると、

machine.lightsleep()でRTC割り込みと同等の値(最大値)を設定してやらないとダメ、電池寿命計ろうと思って無限待ちにしたら最初のRTC割り込みしか実行されず、それ以降のRTC割り込みは発生しなくなってしまった

まあラズピコの実装レベルはその程度のようです

 

admin

1-wireの温度センサーを使う

ラズピコのデータロガーの使い道で温度の記録は主要な用途かも知れないけど、屋外で使うには防水性が必要

ds18x20は1-wire製品で単品では防水性はないけれども、それを金属管に入れて防水性を確保したものが安く販売されているので購入、Amazonで3本セットで販売のもの

SHT30との測定値の差を見るために以下のコードを使用、GP2は推奨の4.7KΩでプルアップ、プルアップしなくてもそれらしい値は出てくるけど、本来的にはかりそめだと思った方が良い、特に複数本つなぐとそれなりに静電容量も増加するし

import time
import machine, onewire, ds18x20
from machine import Pin, I2C

# I2C1 (SDA=GP6, SCL=GP7)
i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq=100000)

# --- SHT30 定義 ---
SHT30_ADDR = 0x44
SHT30_CMD_MEASURE = b'\x2C\x10' # set to highspeed response mode

def read_sht30():
    i2c.writeto(SHT30_ADDR, SHT30_CMD_MEASURE)
    time.sleep(0.008)
    data = i2c.readfrom(SHT30_ADDR, 6)
    temp_raw = data[0] << 8 | data[1]
    hum_raw  = data[3] << 8 | data[4]
    temperature = -45 + (175 * temp_raw / 65535)
    humidity    = 100 * hum_raw / 65535
    return temperature, humidity

# 1-Wire の設定(例: GP2)
dat = machine.Pin(2)

# 1-Wire バス作成
ow = onewire.OneWire(dat)
ds = ds18x20.DS18X20(ow)

# バス上のデバイスをスキャン(複数のDS18B20が繋がっている場合あり)
roms = ds.scan()
print('Found DS devices:', roms)

while True:
    # 温度変換開始
    ds.convert_temp()
    time.sleep_ms(750)   # 最大分解能(12bit)の変換待ち時間
    
    for rom in roms:
        temp = ds.read_temp(rom)
        print('Device', rom, 'Temp={:.1f} C'.format(temp))
    
    print('-' * 40)

    try:
        t, h = read_sht30()
        print("SHT30   Temp={:.1f} C  Hum={:.0f} %".format(t, h))
        print("-" * 40)
    except Exception as e:
        print("Error:", e)
    time.sleep(2)

<実行結果>

今回使用のセンサーのIDもプリントアウトするようにしてます、複数箇所の測定をする時にはセンサーで見て分かる識別手段が必要

測定値で1.5℃ぐらい差があるけども、これはアプリによっては許容範囲、おそらく3本それぞれでもばらつきはあるはず

ロガー自体をケースに入れて、センサーを複数本使ってログを取るような形式になるはず

 

admin

Grove shieldでi2c接続

Switch scienceで販売されてる、ラズピコ用のグローブシールド

https://www.switch-science.com/products/7109?_pos=11&_sid=85b9241fd&_ss=r

数年前に買ったけど初めて使ってみた、但しちゃんとした回路図が見つからないから実物で追っかけないとi2cの接続先わからなかった

以下のコードの、

i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq=100000)

がI2C1の接続先になってます

import time
import machine, onewire, ds18x20
from machine import Pin, I2C

# I2C1 (SDA=GP6, SCL=GP7)
i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq=100000)

# --- SHT30 定義 ---
SHT30_ADDR = 0x44
SHT30_CMD_MEASURE = b'\x2C\x10' # set to highspeed response mode

def read_sht30():
    i2c.writeto(SHT30_ADDR, SHT30_CMD_MEASURE)
    time.sleep(0.008)
    data = i2c.readfrom(SHT30_ADDR, 6)
    temp_raw = data[0] << 8 | data[1]
    hum_raw  = data[3] << 8 | data[4]
    temperature = -45 + (175 * temp_raw / 65535)
    humidity    = 100 * hum_raw / 65535
    return temperature, humidity

# --- メイン ---
while True:
    try:
        t, h = read_sht30()
        print("SHT30   Temp={:.1f} C  Hum={:.0f} %".format(t, h))
        print("-" * 40)
    except Exception as e:
        print("Error:", e)
    time.sleep(2)

こんな感じで吐き出してきます

SHT30   Temp=28.5 C  Hum=62 %
----------------------------------------
SHT30   Temp=28.6 C  Hum=62 %
----------------------------------------

アプリケーションは防水機能のある温度センサーが必要で、ポピュラーなのはds18x20の先端がsusパイプで覆われたやつが使えそうです

インターフェースが1-wireなので、増設も並列につなげていけばできるけど読み出し時間はかなりかかるらしい、なぜ増設した時に個体識別できるかはds18x20が出荷時点で固有のIDが付与される、つまりMACアドレスなどと同じ理屈、から可能ということ

 

admin

電池駆動のデータロガーを作ってみる(5) — ラズピコの省電力はイマイチ

結局ラズピコ2は、

① microPythonはlightsleepもdeepsleepも実装が不完全

② pico-sdkはSDカードアクセスライブラリが無いぽい

③ Arduino IDEはi2cの設定Wire()関数でUSBの通信が切れる

ということで、ラズピコ2はまだ環境がイマイチなので、ラズピコでやってみた

<結果>

① ラズピコはおそらく周辺回路のデザインによるだろうけど、lightsleepでもdeepsleepでもスリープ状態の電流は4mA程度(単三電池2本使用で)だから、電池容量1,000mAでほぼ10日がmax

② deepsleep使うアプリ書き込んでしまうと、ThonnyやVScodeのようなUSBシリアル使うツールは使えなくなる、リセットするにはdeskモードにして、

% picotool erase
Erasing:              [==============================]  100%

picotoolで初期化が必要

③ 消費電流に差がなくて、余計な初期化処理が走るdeepsleepにラズピコでは使い道がなさそうだ

ラズピコでもGrove経由で色々なセンサーへの接続はできるので、サンプリング対象を変えればロガーとして使うことはできる

ということで、当初の目論見の数ヶ月を単三電池2本でというのはラズピコでは無知というのが結論、アプリ次第で一週間もてば十分なケースもあるし、電池容量増やせば期間延長もできるわけだけども

 

admin

ラズピコのmicroPython(番外編)

microPython用のIDE、具体的にはThonny、VScodeの拡張機能MicroPicoを使ってのいくつかの気づき

・IDEとはUSB経由での通信だけど、例えばVScode上でのコード実行は実際はRAM上に展開して実行される、従ってラズピコにmain.pyがすでに存在している時には、実行(run)も無効だし、ラズピコ側も動作停止する(USBシリアル使っている時には競合するから、停止ということ)

・ラズピコへのコード(***.py)の転送はThonnyが直感的で便利、但しここでもUSBは共有できないからVScodeは終了しておかないとダメ

・したがって、microPythonへファームさえ書き込んでしまえば、それ以降はIDEにはファイルに見せる操作は不要

ラズピコ2はいろんな機能がいまだサポートされてないようだから、今回のプロジェクトは前世代のラズピコに変えるつもり、それならmicroPythonのmichine.lightsleepやdeepsleepも動作するだろうからそれで十分だよ

 

admin