2025年2月2日日曜日

raspberry pi zero 2wの初期設定メモ

1.初期設定:
1.1.初期イメージ作成:
以下からPiImagerをダウンロードし、PCにインストール
https://www.raspberrypi.com/software/
PiImagerで、以下を設定しmicrosdカードに書き込む
・RASPBERRY PI ZERO 2 W,RASPBERRY PI OS(64-BIT),SDカードストレージを選択し、
・カスタマイズ設定で編集を選択し、
 ・一般タブで、ホスト名、ユーザ名、WIFI設定、ロケール設定を設定し
 ・サービスでSSHを有効にし、パスワード認証を使うを選択
イメージを書き込んだSDカードをraspberrypizero2wに刺して、raspberrypizero2wのマイクロUSBに通電。
・PCのコマンドプロンプトから、さっき設定したユーザ名とホスト名を使って"ssh [ユーザ名]@[ホスト名]"で接続。パスワードで接続。
sudo apt update
sudo apt full-upgrade
sudo rpi-update
sudo reboot

PCから"ssh [ユーザ名]@[ホスト名]"で接続。
sudo raspi-config を実行し、3 Interface Option から I2CとSPIを有効にしてリブート。

1.2.dockerインストール
http://docker.jp/PDF/docker-getting-started-guide-for-linux.pdf
と、
https://www.cqpub.co.jp/interface/download/2025/2/IF2502T2%E3%83%AA%E3%82%B9%E3%83%88.zip
のS3_list.txtを見ながら実施。

PCから"ssh [ユーザ名]@[ホスト名]"で接続。
curl -fsSL https://get.docker.com/ | sh


sudo usermod -aG docker $USER
exit でいったんログオフし、もう一度PCから"ssh [ユーザ名]@[ホスト名]"で接続。

id でdockerグループに所属を確認。

インストール結果確認。以下コマンドで「Hello from Docker!」が表示されることを確認。
docker run hello-world

メモリが少なくてchromiumもfirefoxも起動できないのであまり意味がないかもしれないけど、VNCサーバを起動するとするなら、
sudo raspi-config を実行し、3 Interface Option から VNCを有効にする。

そのほか、ssh接続にパスワードじゃなくて鍵を使うとすると、キーペアを作って公開キーをraspberry pi側に、秘密鍵をPC側に置いておく
キー作成
ssh-keygen -f keypair
公開鍵登録
umask 0077
mkdir ~/.ssh
cat keypair.pub >> ~/.ssh/authorized_keys
umask 0022
rm keypair.pub
PCから、"sftp [ユーザ名]@[ホスト名]"で接続。
以下のsftpコマンドで秘密鍵を取得
get keypair
rm keypair
exit

getした秘密鍵(keypair)をPCの%USERPROFILE%\.sshフォルダ(無ければ作る)にファイル移動。
%USERPROFILE%\.ssh\config ファイルに以下を追記
===
Host [raspberrypizero2wのホスト名]
    HostName [raspberrypizero2wのホスト名]
    User [raspberrypizero2wの接続ユーザー名]
    IdentityFile "[%USERPROFILE%を展開したフォルダ名]\.ssh\keypair"
===



インタフェース2月号によると、コンテナからGPIOなどを使うには、
1.ホスト側でGPIOを使っているユーザのID、グループIDを合わせる必要があることと
2.コンテナの/devをホスト側の/devにアクセスできるようにマウントする必要があることと
3.サービスの権限をつける必要がある
ようです。

1.は、Dockerfileで、イメージを作る時にイメージ側にgroupadd,useradd,をして、
  ホスト側のpiユーザである、ユーザID:1000,グループID:1000を設定して、
   USER命令で実行ユーザをUID,GIDが共に1000のユーザで起動するようにすること
2.は、compose.ymlで、services:(サービス名):の下のvolumes:で配列の一つに/dev:/devを指定すること
3.は、compose.ymlで、services:(サービス名):の下でprivileged: true を指定する必要があることです。

確かに、これをやってP.37のリスト3のDockerfile(ただしADDの行を除く)とリスト4のcompose.ymlを作成し、
[touch .env_file-develop]した後、docker compose up -d を実行して、
docker exec -it [コンテナハッシュ] /bin/bash
で入ると、プロンプトでログインユーザ名がrootではなくDockerfileでUSERで指定したユーザとなっていて、
pip install gpiozero
pip install Rpi
pip install lgpio
pip install pigpio
をやった後、以下のpythonスクリプトを実行したらGPIO18に接続したLEDが点滅した
===
from gpiozero import LED
from time import sleep

led = LED(18)

while True:
    led.on()
    sleep(0.5)
    led.off()
    sleep(0.5)
===



追記:imageにPI OS Liteを使っても同じように設定できた。
PI OS はrunlevel 5 (X環境)で動いているけど、PI OS Liteはrunlevel 3 (CUIのマルチユーザーモード)で動いているので、
Liteの方が消費リソースが少なくていい感じかも。

2025年2月1日土曜日

pipicoで可変抵抗器2

そういえばアナログスティックは2方向の可変抵抗器でした。
これを使ってUSBマウスのようにマウスカーソル操作してみます。

接続はこんな感じ
アナログスティックのGND,+5V,VRx,VRyをpicoのGND(38),3.3V(36),ADC1(32),ADC0(31)に接続して circuitpythonのコードはこんな感じ import time import usb_hid from adafruit_hid.mouse import Mouse from analogio import AnalogIn from board import * potentiometer1=AnalogIn(A0) potentiometer2=AnalogIn(A1) mouse = Mouse(usb_hid.devices) while True: x=-int((potentiometer1.value-65536/2)/65536*50) y=int((potentiometer2.value-65536/2)/65536*50) if abs(x)<2 : x=0 if abs(y)<2 : y=0 mouse.move(x,y,0) time.sleep(0.01)

最近のユニバーサル基板って切って小さくできるものなのかな?

久しぶり(約40年ぶり)にユニバーサル基板を買ってみた。
100円の小さ目のもの。
今住んでいるところの近くで電子工作用部品を扱っているところを知らないので、ネット通販。
raspberry pi picoやzero,ロータリーエンコーダやタクトスイッチを買ったときに一緒に購入。
(秋月で購入。全部で11,000円に届かなかったので送料が500円。picoは2つかったのだけど、zeroも2つ買っておけば、送料無料になっていたなぁ。)
で、納品書をよく読むと、片面ガラスコンポジット・ユニバーサル基板って書いてある。 これって、基板を切ったりできるものなのかな?

raspberry pi zero2wのピンヘッダはんだ付け終わり。あ!

やっちまったあ。

ピンヘッダをつける向きが逆だった! このピンヘッダの配置位置だとブレッドボードに直接させない。(刺したら1行目のピンと2行目のピンがショートしてしまう。) ケーブルで出してブレッドボードに指しても、ピンの表裏が逆なので列反転か行反転のいずれかを選ばなければならない。 2行20列なので、まだ行反転の方が扱える。(扱えないが。) というわけで、5VとGNDの表記のピンの逆側の行にピン接続をしてみて導通を確認。
こいつは外部機器を使わないサーバ的や用途として使い、もう1つpi zero 2wを買おうかなぁ。 最近だと仮想化が当たり前の感じだし、Interface2025年2月号にpi zeroもdocker化できそうなことを書いてあったので、こいつをdockerマシンにして、コンテナからGPIO制御をできるような実験だけにしようかな。 にしても、最近のコンピュータ雑誌は紙面だけでは説明しきれず、ダウンロードしないとスクリプトや結果表示がわからないっていうのは当たり前なのかな?すごく読みにくいんだけど。

2025年1月29日水曜日

pipicoで可変抵抗器

ロータリーエンコーダじゃなくて、1周しない普通のボリュームの可変抵抗器を使ってみた。
raspberry pi picoにはアナログ入力があるので、可変抵抗器の3本の足を、GND(3番ピン),3.3V(36番ピン),ADC0(31番ピン)につないで、
ネットに転がっているコードを参考に以下のコードにしてみた。

from board import *
import time
from analogio import AnalogIn

potentiometer=AnalogIn(A0)
while True:
    print(potentiometer.value)
    time.sleep(0.1)


読み取りはできてそうだけど、HIDの入力でよさそうなものは見つからない。

2025年1月26日日曜日

USBでHIDでロータリーエンコーダ

左手デバイスって言って、少しのボタンやスライドつまみや回転つまみなどがあるUSBデバイスっていうものがある。
これを試作してみた。

昔はアルドゥイーノのUSBHID対応機種(レオナルドとかマイクロ)を使うのが最有力候補だったけど、
今だとラズベリーパイピコ2の方が安くて普通にUSBHID対応しているので今回はこちらで作ってみた。

まずは、配線はこんな感じ。

スイッチ8個の片側をGPIO~GPIO7に、もう一方をGNDに接続。 ロータリーエンコーダ1の1,GND,2をGPIO14, GND, GPIO15に接続。 ロータリーエンコーダ2の1,GND,2をGPIO12, GND, GPIO13に接続。 ラズベリーパイピコ2の方は、ボタンを押しながらusbに接続し、 共有ドライブ直下に、circuitpythonのページでダウンロードした.uf2ファイルを格納してcircuitpythonを使えるようにして、 https://circuitpython.org/libraries から対応するadafruit-circuitpyhton-bundleをダウンロード/展開し、その中の"adafruit_hid"ディレクトリを circuitpythonの共有ドライブのlibフォルダにコピーしてadafruit_hidを使えるようにして、 以下の内容を共有フォルダ上のcode.pyファイルを上書きした後、一旦PCから外してもう一度つなげて入力ができることを確認。 import digitalio from board import * import time import usb_hid from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard import Keycode from adafruit_hid.consumer_control import ConsumerControl from adafruit_hid.consumer_control_code import ConsumerControlCode s1 = digitalio.DigitalInOut(GP14) s1.direction = digitalio.Direction.INPUT s1.pull = digitalio.Pull.UP s2 = digitalio.DigitalInOut(GP15) s2.direction = digitalio.Direction.INPUT s2.pull = digitalio.Pull.UP n_s1=o_s1=s1.value n_s2=o_s2=s2.value s3 = digitalio.DigitalInOut(GP12) s3.direction = digitalio.Direction.INPUT s3.pull = digitalio.Pull.UP s4 = digitalio.DigitalInOut(GP13) s4.direction = digitalio.Direction.INPUT s4.pull = digitalio.Pull.UP n_s3=o_s3=s3.value n_s4=o_s4=s4.value sw=[] n_sws=[True,True,True,True,True,True,True,True] o_sws=[True,True,True,True,True,True,True,True] vol1map=[ConsumerControlCode.VOLUME_DECREMENT, ConsumerControlCode.VOLUME_INCREMENT] vol2map=[ConsumerControlCode.BRIGHTNESS_DECREMENT, ConsumerControlCode.BRIGHTNESS_INCREMENT] keymap=[Keycode.ONE, Keycode.TWO, Keycode.THREE, Keycode.FOUR, Keycode.FIVE, Keycode.SIX, Keycode.SEVEN, Keycode.EIGHT] for _gpio in GP0,GP1,GP2,GP3,GP4,GP5,GP6,GP7: s = digitalio.DigitalInOut(_gpio) s.direction = digitalio.Direction.INPUT s.pull = digitalio.Pull.UP sw.append(s) cc = ConsumerControl(usb_hid.devices) keyboard = Keyboard(usb_hid.devices) while True: n_s1 , n_s2= s1.value , s2.value if(n_s1 != o_s1 or n_s2 != o_s2) : if n_s1 ^ o_s2 == 0 : cc.send(vol1map[1]) else: cc.send(vol1map[0]) o_s1,o_s2=n_s1,n_s2 n_s3 , n_s4= s3.value , s4.value if(n_s3 != o_s3 or n_s4 != o_s4) : if n_s3 ^ o_s4 == 0 : cc.send(vol2map[1]) else: cc.send(vol2map[0]) o_s3,o_s4=n_s3,n_s4 for i in range(8): n_sws[i] = sw[i].value if ((o_sws[i]==True) and (n_sws[i]==False)): keyboard.send(keymap[i]) o_sws[i]=n_sws[i] time.sleep(0.001) ボタンの方は、多数のボタンの場合、普通はポート数を少なくするため以下のページのように入力と出力をグリッド上にするのですが、 https://www.elec-hobbyist.com/MicomMemo/Pgm_Method/Pgm_method_3.html 手元にダイオードがないため、各ボタン独立でポートを使いました。 ロータリーエンコーダの方は、切り替えのタイミングで短時間でON/OFFを繰り返すため、普通はセラミックコンデンサを入れて高周波成分を取り除くのですが、 https://sheep-me.me/2019/12/05/geidai_21/ 手元にセラミックコンデンサがないため、バタつきが収まるであろう時間を開けてスキャンするだけにしました。

2024年11月3日日曜日

ExcelでPyhton

会社のExcelで、インターネット接続環境ならPythonが使えるようになったみたい。
セルで=py(と打ち込むとpython入力モードとなった。

あらかじめ、pandasなどのライブラリを読み込んであり、excel範囲の取り込みにxl関数があるので、
xl("A1:F200")のExcel範囲指定とかtable定義を読み込みに使えるみたい。
範囲を指定すると、DataFrameが返ってくるよう。
そのセルをExcelで表示させると、そのセルを左上セルとして、Excelに表示できた。

手元に実機がないので以下は試していないけど、

sample_df=xl("A1:F200")
と変数sample_dfにおいて、
sample_df[['名前','年齢']] で表示列を絞ったDataFrameができたり、
sample_df.loc[:2,['名前','年齢']]で、3行2列のDataFrameができたり、
sample_df[sample_df['年齢']>20][['名前','年齢']で、条件で行を絞った、列挙した列分のDataFrameができたり、
sample_df['名前'] でSeriesができたり、
sample_df.plot()で、そのセルにグラフを描いてくれるのかな?

excelでの集計方法が多すぎて(増えすぎて)、どれを使ったらよいか迷いそう。
ざっと挙げても以下の5個。
1.ワークシート関数
 (普通のやつ,xlookupとその亜種,配列式(Control+Shift+Enterのやつ),最近ではスピル(結果の範囲が動的なものも扱える配列式みたいなもの?)も出てきたし、
  この中でも迷いそう)
2.ピボットテーブル
3.table定義フィルタやオートフィルターと組み合わせての表示部分のみで集計するワークシート関数
3.PowerQuery(M言語),PowerPivot(DAX)
 (モダンExcelっていうやつ?ExcelからPowerViewが消えて、この3つがPowerBIに移ったのでExcelでのPowerQuery,PowerPivotはExcelの存在感は薄れたか?)
4.Excelマクロ(マクロ実行で集計させたり、マクロで作成した関数をセルでワークシート関数のように呼び出したり)
5.Python

会社のExcelではまだExcelワークシート関数での正規表現が使えないので、機械的なテキスト編集の場合、私は外部のテキストエディタやPowerShellで正規表現の
置換を使って結果をExcelにペーストしているけど、これをExcel内のPythonで連携できるのかなぁ?
 Excelマクロ関数のセル内実行だと、依存セルの変更時にExcelマクロ関数を使ったセルの結果値の自動反映がうまくいかないことがあるので、Pythonも同じになりそう。