ラズパイ5追加のセットアップ(1)

    とりあえず動作確認したラズパイ5ですが、目的用途のための動作確認などを、
    1. 起動媒体

まず、間に合わせ使ったsdカードがメチャクチャ遅い、ドラレコから抜いてきたからほぼ寿命終わりらしい

かなり昔のusbメモリにインストして立ち上げた方がはるかに高速、なので追加でSDカード(UHS-1規格)購入してインストすると体感かなりサクサク

shutdown ~ reboot(ログオン完了)時間は、

Shutdown ~ reboot時間
どちらもヘッドレス、
古いmicro SD : 1:40 min/ 2:20 min(媒体終わってるよね)
Stick USB : 1:10 min

SDカード(UHS-1):40 sec(デスクトップモードなのに)

という結果、ついでにsdカードのベンチマークは、

UHS-1カードのPiBenchmarks結果

$ sudo curl https://raw.githubusercontent.com/TheRemote/PiBenchmarks/master/Storage.sh | sudo bash

     Category                  Test                      Result     
HDParm                    Disk Read                 90.82 MB/sec             
HDParm                    Cached Disk Read          90.94 MB/sec             
DD                        Disk Write                32.5 MB/s                
FIO                       4k random read            6317 IOPS (25268 KB/s)   
FIO                       4k random write           845 IOPS (3382 KB/s)     
IOZone                    4k read                   29989 KB/s               
IOZone                    4k write                  3288 KB/s                
IOZone                    4k random read            30032 KB/s               
IOZone                    4k random write           3268 KB/s                

                          Score: 2530                             

ラズパイ5ではおそらく平均的な値だろう

 

2. Pythonのインスト

ラズパイではpyenvを使うことが推奨というかほぼマストです

https://zenn.dev/technicarium/articles/00b32d390e82ec

がわかりやすかったのでこのサイトとPerplexityでPyenvと現状安定版の最終3.13.1をインスト、必要なライブラリは都度

 

3. text2speechでスピーカ機能も確認

音声の入出力にUSB接続のマイクとスピーカーを使いますが、その機能確認含めて、ロワーケースはssd用HAT(見た目ロワ側なのでHATじゃなくてHAB、そのそも上側にはGPIOコントロールのカスタムボードが追加されるし)に置き換えてます

フリーのopen_jtalkのインストと動作確認

open-jtalkインスト
$ sudo apt-get update
$ sudo apt-get install -y open-jtalk open-jtalk-mecab-naist-jdic htsengine libhtsengine-dev hts-voice-nitech-jp-atr503-m001

女性の声のインスト
$ wget https://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.7/MMDAgent_Example-1.7.zip
$ unzip MMDAgent_Example-1.7.zip
$ sudo cp -r ./MMDAgent_Example-1.7/Voice/* /usr/share/hts-voice/

合成音声(text2speech)のサンプルコード(Perplexityで作成)

#
# pactl set-sink-volume @DEFAULT_SINK@ +10%      音量アップ
#
import subprocess
import os
from datetime import datetime

def jtalk(text):
    open_jtalk = ['/usr/bin/open_jtalk']
    mech = ['-x', '/var/lib/mecab/dic/open-jtalk/naist-jdic']
    htsvoice = ['-m', '/usr/share/hts-voice/nitech-jp-atr503-m001/nitech_jp_atr503_m001.htsvoice']
    speed = ['-r', '1.0']
    outwav = ['-ow', 'out.wav']
    cmd = open_jtalk + mech + htsvoice + speed + outwav
    
    try:
        proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = proc.communicate(input=text.encode('utf-8'))
        
        if proc.returncode != 0:
            print(f"Error in open_jtalk: {stderr.decode('utf-8')}")
            return
        
        if not os.path.exists('out.wav'):
            print("Error: out.wav was not generated.")
            return
        
        # Raspberry Pi での音声再生
        subprocess.call(['aplay', 'out.wav'])
    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == '__main__':
    current_time = datetime.now().strftime("%H時%M分")
    text = f"現在の時刻は{current_time}です。"
    jtalk(text)

 

4. マイク機能の確認

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 2: SF558 [SF-558], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

のように見えているので、Linuxの基本コマンドで確認

// record
$ arecord -d 5 -r 12000  out.wav
// play
$ aplay out.wav

後ペリフェラルではカメラ必要だけど、それはリサーチの後だな、それにステッピングモータとか駆動させるとACアダプタ5Aで足りるのかな?

 

admin

 

raspberry pi 5のインストなど

ラズパイの現行ハイエンド(8GB品)を購入、今までラズパイ1、zero、picoしか購入履歴ないから史上最高性能、ヒートシンクつけたら見ることないから取り付け前の写真

最終的にはssdで高速化と高信頼性化しますが、とりあえずsdカードでインスト(ほぼ動作確認)してみた

osはssdへの書き込み考慮して、必要ないけどデスクトップバージョンをインスト、sshは書き込み時点のオプション選択でオンにしておかないと手も足も出ないから忘れずに、同時にWi-Fiの設定もしておきます、こちらは最悪有線LAN使えばいいけども

ラズパイの基板保護(特に裏面のチップ部品)のために拾ってきたstlファイルでロワーカバー造形、sdカードとの干渉部分は追加で加工しないと後で泣く(sdカード持ち上げ方向の力ではんだ剥離します

sdカード差込部

デスクトップ版のosインストしても、モニターもキーボードも持っていないからvncでデスクトップ画面をmacから操作します

https://qiita.com/ktamido/items/82ed2f5bd324d4721096

x11を有効化してmac標準のvncではつながらなかったからvnc viewerをインスト、設定だろうけどスクショ撮れなかったからカメラで撮影の画面

 

admin

 

 

HUB75 LEDアレイ表示にテキストのイメージ化機能も追加

https://isehara-3lv.sakura.ne.jp/blog/2025/01/23/hub75-ledアレイの表示画像を任意に変更できるようにし/

作成されてるイメージのアップロードだけではなく、テキスト入力してそれをイメージ化して送信するように機能追加、フォントはMacでは、

fontPath:=“/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc”
を使っていますが、ラズパイではヘッドレスでフォントもインストールされてないからそこから始めたないとダメ

コードのGitHubへのリンクに変更はありません

<ブラウザ画面>

<表示されたイメージ>

LEDアレイでの表示ポジションや縮尺、倍率などの改良の余地はありますが、機能的にはこれでほぼ完成形

 

admin

 

 

 

HUB75 LEDアレイの表示画像を任意に変更できるようにした

固定した画像ファイルを選択するだけではイマイチだから、webサーバー(ラズパイzero)にブラウザ経由で任意の画像をアップロードして、サーバー側で画像の圧縮処理、rgb抽出を行いTCPでラズピコに送信して表示させるようにした

構成はwebアプリをgolangで作成し、ラズピコ側のコードも対応して変更、途中でデータロスはできないからUDPはあり得なくてTCPは前提

コード生成はPerplexityが無償でもgolangでは使えるコードが出てくるので活用、多分コードの生産性からいったら倍以上にはなる

<web application code>

https://github.com/chateight/golang/tree/master/image

<raspberry pi pico code>

https://github.com/chateight/hub75_led_array_image_upload/tree/main

ラズパイzeroでの実行速度は150KBぐらいのイメージファイルでLEDアレイに表示されるまで2秒ちょっとといったところ(Wi-Fi転送は過去の経験で1MB/secは出るからほぼイメージ処理の時間)だけど実用的には問題ないレベル

ラズピコ側でTCP通信するのにどうやるのかを検索してもイマイチだったので、それもPerplexityからの回答で、主要なコードを抜き出すとこんな感じ、

void setup(){
  IPAddress staticIP(192, 168, 1, 200); 
  IPAddress gateway(192, 168, 1, 1);
  IPAddress subnet(255, 255, 255, 0);

  WiFi.config(staticIP, gateway, subnet);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi...");
  }
  server.begin();
}

void loop() {
  client = server.accept(); // TCP start
  // if network is active
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        // receive binary data
        int bytesRead = 0;
        unsigned long startTime = millis();
        
        // Read all available data within a 500ms window
        while (client.available() && (millis() - startTime < 500) && bytesRead < MAX_BUFFER) { 
      receivedData[bytesRead] = client.read(); 
      bytesRead++; 
     }
        
        // response to the server
        const char* response = "Resp from Pico W!";
        client.write(response, strlen(response));
      }
  }

今更ながらコード作成でもLLMはもはや必需品で、用途ごとに要求されるものが違うからそれは人間社会と同じかもしれない

 

admin

 

 

さくらレンタルサーバーのDB(MySQL)がようやく移行

多分ようやくなのだろうけれども、データベースサーバーの更新(5.7系 -> 8系)への移行の催促が来ていたので移行

事前にメニューで移行処理(移行先にコピーして二重で持つだけ)の予約、実行完了後に、実際に使われるデータベースを、コントロールパネルのファイルマネージャーからwp-config.phpのデータベース指定先に書き換え(/** MySQL のホスト名 */)、保存して、正規のページにアクセスして正常に表示されれば、移行が完了しているということです

WoedPressだけなので作業自体は簡単、

 

admin

golang/Rustのラズパイ/ラズピコ向けのクロス環境について

ラズパイ/ラズピコ限定の話になりますが、現時点での整理です

① golang : ラズパイ用にはcgoがあるとターゲットマシン用にgolangとc用に二種類のコンパイラが必要になるので、単純化のためにはcgo freeのライブラリだけ使って、(現時点ではcgoライブラリはほぼ回避手段があるはず)クロスコンパイルを実行する

たとえば、ラズパイzero用バイナリならば、以下のようなコンパイルオプションつけて実行できる

% GOOS=linux GOARCH=arm GOARM=6 go build -o rasp_zero

ラズピコで組み込み用にはgolangというのは選択肢にはならないしそもそも手段があるのか、golang使うならRustでしょう

② Rust:ラズパイ用はCross + Dockerが一番素直か、Intel MacならばVM上のUbuntuでもtoolchainが存在してるからできるけど

https://www.freecodecamp.org/news/embedded-rust-programming-on-raspberry-pi-zero-w/#heading-how-to-set-up-cross-compilation

ラズピコは組み込みだからクロスビルドしかなくて、Baker link. ENV + Rancher Desktop(docker)がCross + Dockerに相当する機能で使える、ラズピコはデバッガ(debug probe)を簡単に使えるという点でもBaker link. ENVが良さそう、おそらくBaker link. ENVと類似のツールはこの先出てくるかもしれないけど、いずれにしてもそれは仮想環境を使ったもので開発環境を自分で作ることが必要なケースはそれほどないはず(Docker用のイメージ作成は別にして)、いまだラズピコでRustはかなりニッチではあるから歩みは遅いかもしれないが

 

admin

CrossでRustのコンパイル時のパラメタ制限解除

Rustのクロスコンパイル環境でCrossを使う

以前の記事で、cross使う時には

CROSS_CONTAINER_OPTS=”–platform linux/amd64″

を先頭に付加しないと動作しなかったけれども、今日使ってみると、

% CROSS_CONTAINER_OPTS="--platform linux/amd64" cross build --target arm-unknown-linux-gnueabihf  —release 
The application panicked (crashed).
Message:  byte index 1 is not a char boundary; it is inside '—' (bytes 0..3) of `—release`
Location: /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/str/mod.rs:659

のようなエラーが出て起動できない、単純に削除して$ cross build *********で動作するようになってました(そこに至るまでにはcrossで–releaseを付加するとなぜがエラーは継続して、–releaseを削除すると動いて、その後に–release追加というこれも不可思議な現象を経由してます)

ちなみにIntel MacでDockerで環境インストして動かしてみると、なぜかDockerのuser権限なくてもコンパイルできてしまいます

 

admin

golangにおけるcgo freeドライバに関連して

二年ぐらい前には、まだcgoしか無いようなドライバもそこそこ存在してましたが、cgo freeのドライバに変えてコンパイルをすっきりさせた方が良さそうです

cgo freeでは無いドライバが含まれるコードを普通にコンパイルしてラズパイzeroで実行させると、

$ ./rasp_zero
2025/01/12 17:17:17 "Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub": 
	create table foo (id integer not null primary key, name text);
	delete from foo;

と言われるし、cgo対応のlinkerはいまいち不明だし、というわけで以下のリンクのサンプルコード(実は上のエラーメッセージはオリジナルのソースをコンパイルしてます)をcgo freeドライバに入れ替え

https://zenn.dev/teasy/articles/go-sqlite3-sample

github.com/mattn/go-sqlite3

を、

modernc.org/sqlite

に変更して、db openのコードを変更するだけでcgo freeとなって、

% GOOS=linux GOARCH=arm GOARM=6 go build -o rasp_zero

でコンパイルするとラズパイzeroで動くバイナリが出力されます

実はcgo free以外に、M1 Macの動作ではgo run ***では動作しても、./***では起動も終了もしないという不思議な現象が出てましたが、この件も一緒に解決、ただしこの現象ではIntel Macでは出ないという怪しげな現象でした

orm(例えばgormなど)もcgo freeにできるので、今後はcgoが必要なのはおそらくよほどな時になりそうです

<コードは>

sql.open()が変わっただけです

package main

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	_ "modernc.org/sqlite"
)

func main() {
	os.Remove("./foo.db")

	// original
	// db, err := sql.Open("sqlite3", "./foo.db")
	//
	db, err := sql.Open("sqlite", "./foo.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	sqlStmt := `
	create table foo (id integer not null primary key, name text);
	delete from foo;
	`
	_, err = db.Exec(sqlStmt)
	if err != nil {
		log.Printf("%q: %s\n", err, sqlStmt)
		return
	}

	tx, err := db.Begin()
	if err != nil {
		log.Fatal(err)
	}
	stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()
	for i := 0; i < 100; i++ {
		_, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i))
		if err != nil {
			log.Fatal(err)
		}
	}
	tx.Commit()

	rows, err := db.Query("select id, name from foo")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var id int
		var name string
		err = rows.Scan(&id, &name)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(id, name)
	}
	err = rows.Err()
	if err != nil {
		log.Fatal(err)
	}

	stmt, err = db.Prepare("select name from foo where id = ?")
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()
	var name string
	err = stmt.QueryRow("3").Scan(&name)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(name)

	_, err = db.Exec("delete from foo")
	if err != nil {
		log.Fatal(err)
	}

	_, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')")
	if err != nil {
		log.Fatal(err)
	}

	rows, err = db.Query("select id, name from foo")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var id int
		var name string
		err = rows.Scan(&id, &name)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(id, name)
	}
	err = rows.Err()
	if err != nil {
		log.Fatal(err)
	}
}

P.S.  2025/1/13

”実はcgo free以外に、M1 Macの動作ではgo run ***では動作しても、./***では起動も終了もしないという不思議な現象が出てました”

この件に関連して、DB(sqlite3)を使う別のコードではビルドもできず、やはりIntel Macでは問題なくビルドできて動作したので、おそらくVenturaのアップデートと関連ありますね

 

admin

Docker Desktopがマルウェア扱いになる

おそらくMac OSのsequoiaと関連していてDocker Desktopのアップデートが原因思われますが、このようなエラーが出て起動できません

検索すると、https://zenn.dev/masakiee/articles/4c6f7e68a5a31c

同じような事例は見えるのでworkaroundで緊急避難はできるようですが、

恒久対策は検討中、

https://www.dockerstatus.com

January 8, 2025 10:41 PST
January 8, 2025 18:41 UTC[Identified] The root cause has been identified: some files in existing installations are incorrectly signed which can be fixed by copying correctly signed files from the Docker.app application bundle.

We are working on a proper fix.

まあDocker Desktopは使わないで、Rancher Desktop(Baker link.ですでにインスト済み)に移行してしまうというのもありだろうね、Rustのクロス環境はPodman + Podman DesktopだからあまりDocker Desktopにこだわる必要もない

ついでに、% docker versionで見てみると、Client(rancher-desktop)もServerもgolangで書かれてるんだね

% docker version
Client:
 Version:           27.2.1-rd
 API version:       1.45 (downgraded from 1.47)
 Go version:        go1.22.7
 Git commit:        cc0ee3e
 Built:             Tue Sep 10 15:41:09 2024
 OS/Arch:           darwin/arm64
 Context:           rancher-desktop

Server:
 Engine:
  Version:          26.1.5
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.22.5
  Git commit:       411e817ddf710ff8e08fa193da80cb78af708191
  Built:            Fri Jul 26 17:51:06 2024
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          v1.7.17
  GitCommit:        3a4de459a68952ffb703bbe7f2290861a75b6b67
 runc:
  Version:          1.1.14
  GitCommit:        2c9f5602f0ba3d9da1c2596322dfc4e156844890
 docker-init:
  Version:          0.19.0
  GitCommit:        

 

admin

Baker link. 起動手順についての補足

Baker link. ENVは今少し不安定(Dockerの対応するコンテナを削除しないと動かない時がある)のように見えるので、手順を補足説明

<環境>

M1 MacBook Air sequoia

cargo/rustc 1.82.0

Rancher Desktop 1.16.0

<手順>

基本は、

https://baker-link.org/Blink/Baker_link_Env_page.html

ですが、途中いくつか鬼門あるので手順を記載

① historyから作成済みならば、作成済みプロジェクトの履歴からクリックして開く

② 「コンテナで再度開く」を選択

ここでコンテナにファイルが存在しない状態、つまりVScodeでソースコードが開かない時があって、その場合にはDockerのコンテナ(dockerという名前)を削除して最初からやるとうまくいく、imageはbaker-link-envという名前でこれが残っていればコンテナ展開されるだけ、このイメージがDockerに存在していなければBaker link. ENVがダウンロードするんだろう

③ probe-rs見つからないと言われる -> install/failどちらも無視

④ F5でデバッガ起動

⑤ 「cargo buildを見つけられません」のポップアップ -> 「このままデバッグ」を選択(すでに作成済みなので)

もし現在のソースファイルでビルドされていなければ、bash(Docker コンソール)でビルドする(qemu-system-aarch64使っているのでそこそこ遅い)

F5を押したタイミングでラズピコにDocker上のビルドされたバイナリを転送するようです

⑥ デバッグボタンが現れる

 

⑦ デバッグボタン列の一番左の青ボタンでデバッグが起動する

この時にはdfmtコンソール現れてデバッグ開始できる状態になってます

コンソールで前回の出力と連続しているけれども、INF0 Program start!がソースの22行目に埋め込まれてるinfo!(“Program start!”);からの出力でデバッグ開始の確認になります

 

admin