初版作成 2023.5.7
最終更新 2024.09.13
Raspberry Pi Imager というアプリを使う。 https://www.raspberrypi.com/software/ からダウンロードし、exe ファイルをダブルクリックすると インストールされる。 起動して「インストールする OS」「インストール先ドライブ」を 選択する。 ラズパイ 2B に 32 bit 版を入れてみたが、死ぬほど重い。 32 bit レガシー版はサクサク動くので、古いラズパイ にはレガシー版を入れた方が良い。 インストール時に以下のものを設定する。 ・ユーザー名とパスワード(過去との互換性をとるなら pi) インストールできるラズパイ ・ラズパイ 2 以降でないと Chrome が起動しないので 初期バージョンの無印の B は実用的ではない
GUI で操作できる。 ネットワークを固定 IP に設定する(実験室は DHCP で固定 IP を設定) サブネットマスクを設定する項目はない。 default router と name server は 192.168.xx.1 に設定する。 まずやること ネットワークに接続する 次にやること # apt update # apt upgrade (かなり時間がかかる) 以下のアプリをインストールする emacs (めちゃくちゃ時間がかかる) telnet telnetd ftp ftpd telnetd を使えるようにする(レガシーでない raspbian の場合) /etc/inetd.conf を編集してコメントを外す # service inetutils-inetd restart あるいは # kill -HUP PID_of_inetd ○ 日本語を使えるようにする # apt install ibus-mozc (再起動必要) 左上ラズベリーマーク --- preferences --- rasupberry pi config. --- locale: JP (再起動必要) 右上のアイコンをクリックし以下の順に選択する。 日本語 - Japanese 日本語 - Mozc ○ ある程度インストールが終わった後にすること 起動時に CLI で起動するようにする ○ ftpd が動作しないことがあった。インストールしているにも かかわらず、/usr/sbin/in.ftpd が存在しない。 何が効いたかわからないが、 # apt uninstall ftpd # apt upgrade # apt install ftpd で解決した。 ○ ラズパイ4 で HDMI に 1024x768 の信号を出力する /etc/firmware/config.txt に以下を書き込む どれが効いているのかわからない。 ChatGPT4o に聞いた hdmi_group=1 hdmi_mode=16 hdmi_force_hotplug=1 hdmi_drive=2 hdmi_save=0
キーの入れ替えは wayland の場合は後述 setxkbmap -option ctrl:swapcaps xmodmap key-file ---- key-file の中身 ---- keycode 49 = Escape keycode 9 = Zenkaku_Hankaku ------------------------- export TERM=vt100 alias rm='rm -i' alias cp='cp -p' alias ls='ls -F --color=never' alias ne='emacs -nw' alias sc='. ~/.bashrc' export PATH=$PATH:. export CDPATH=~:/home/pi/public_html:/home/pi/public_html/cgi-bin --- wayland の場合 --- ./config/wayfare.ini [input] xkb_options=ctrl:swapcaps xkb_model=pc105 xkb_layout=jp xkb_variant=OADG109A xkb_symbolds="keycode(9)=Zenkaku_Hankaku+keycode(49)=Escape"
# apt install apache2 (1) ユーザーディレクトリを使えるようにする # a2enmod userdir (2) cgi を使えるようにする # cd /etc/apache2/mods-enabled # ln -s ../mods-available/cgi.load . (3) ユーザーディレクトリを html としているとき html ----> public_html のシンボリックリンクを張る $ cd $ ln -s public_html html (4) 設定ファイルの変更点 ------------- /etc/apache2/apache2.conf ------------ ServerRoot "/etc/apache2" #<Directory /home/user-name/public_html/> # AllowOverride Limit Options FileInfo AuthConfig # Options FollowSymLinks # Require all granted #</Directory> #<FilesMatch "~$"> # Require all denied #</FilesMatch> ---------- /etc/apache2/sites-available/000-default.conf -------- ServerName xxx.yyy.nara-edu.ac.jp ServerAdmin zzz@nara.edu.ac.jp を設定(省略可) Include conf-available/serve-cgi-bin.conf を確認 ---------- /etc/apache2/conf-available/serve-cgi-bin.conf -------- <IfDefine ENABLE_USR_LIB_CGI_BIN> ScriptAlias /cgi-bin/ /home/pi/public_html/cgi-bin/ <Directory "/home/pi/public_html/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all granted AddHandler cgi-script .py <---- ここに必要! なぜか mime.conf に書いても効かない </Directory> </IfDefine> ---------- /etc/apache2/mods-available/mime.conf ---- AddHandler cgi-script .py なぜか効かない。 (5) /var/www/html/index.html の変更 以下のように書き換える。 <html> <head> <meta http-equiv="Refresh" content="0;URL=/~pi/"> <title>top page</title> </head> <body> </body> </html> (6) apache2 の自動起動の on/off # update-rc.d -f apache2 remove 自動起動停止 /etc/rc2.d/... が削除 # update-rc.d apache2 defaults 自動起動復活 apache2 の起動 # apachectl start # apachectl stop # apachectl restart (7) ファイルのパーミッション ~/public_html/ 755 ~/public_html/index.html 644 ~/public_html/cgi-bin/ 755 ~/public_html/cgi-bin/*.py 755 (8) CGI を実行可能にする # visudo 最後に以下を付加 www-data ALL=(ALL) NOPASSWD: ALL apache2 用 nobody ALL=(ALL) NOPASSWD: ALL python http.server 用
ラズパイのバージョンによってデバイス名が変わる pi2 まで /dev/ttyAMA0 pi3 以降 /dev/serial0 # raspi-config シリアルコンソールとシリアル通信は別らしい。 シリアルコンソールを off にしないと、 シリアル通信の受信文字が化ける Interface options --- Serial port would you like a login shell to be accessible over serial: no would you like the serial port hardware to be enabled: yes serial port hardware to be enabled:yes の 指示は以下のファイルに書き込まれる /boot/config.txt 2023.5.7 のバージョン レガシーバージョン /boot/firmware/config.txt 2024.7.22 のバージョン enable_uart=1 login shell ....over serial: no の結果が どこに書き込まれるかは不明
python2: python -m CGIHTTPServer 80 ファイル閲覧, CGI 実行 OK python3: python -m http.server 80 ファイル閲覧のみ python3 で CGI を使う方法は以下の通り # python start_cgi_server.py start_cgi_server.py の中身 (ChatGPT4o が作った) ------------------ #!/usr/bin/python import os from http.server import HTTPServer, CGIHTTPRequestHandler class CustomHTTPServer(HTTPServer): def server_bind(self): HTTPServer.server_bind(self) self.server_name = "localhost" self.server_port = self.server_address[1] PORT = 80 DIRECTORY = "/home/pi/public_html" os.chdir(DIRECTORY) server = CustomHTTPServer(("", PORT), CGIHTTPRequestHandler) print(f"Serving at port {PORT}") server.serve_forever() ------------------ 自動起動したいときは rc.local に以下のように書き込む (cd /home/pi/public_html; python start_cgi_server.py >> /var/tmp/web.log 2>&1 &)
参考 http://sooch.hatenablog.com/entry/2017/03/26/061032 1. デバイス名の確認 # blkid 2. フォーマット # fdisk /dev/sda Command (m for help): d パーティション削除 Selected partition 1 Command (m for help): p 確認 Command (m for help): n パーティション作成 enter を押すとデフォルト値が入る Command (m for help): p 確認 Command (m for help): w 書き出して終了 # mkfs.ext4 /dev/sda1 enter を押すとデフォルト値が入る 3. マウント # mount /dev/sda1 /mnt /etc/rc.local に書き込む リブートした時に自動的に接続されてしまう /etc/fstab に書くより、 mount コマンドを /etc/rc.local に書く方が 良いと思う。
$ sudo apt install nfs-common <-- client $ sudo apt install nfs-kernel-server <-- server $ sudo apt install rpcbind <-- server ・クライアント ----- /etc/rc.local ----- mount -t nfs machine-name:/home/user-name/dir /home/user-name/dir -------------------------- ・サーバー ----- /etc/exports ---- /home/user-name/html macine-name(rw,sync,no_subtree_check) machine-name2(rw,sync,no_subtree_check) /etc/apache2 machine-name(rw,sync,no_subtree_check) /var/log/apache2 machine-name(rw,sync,no_subtree_check) -------- /etc/rc.local -------------- service rpcbind start service nfs-kernel-server restart # nfs-kernel-server start ではダメ。restart # 下記の設定でも同じ # systemctl start rpcbind.service # systemctl restart nfs-kernel-server.service -------------------------------------- サーバーを動かすのに色々と苦労した。 # service nfs-kernel-server start ではダメ。restart が必要。 export 状況の確認は # exportfs サービスの状況は # service nfs-kernel-server status で確認する。しかし、rpcbind, nfs-kernel-server ともに active であるにもかかわらず、接続できなかった。 restart に気がつくのに時間がかかった。 参考サイト https://hermemo.com/archives/1312 このサイトがなかったら、解決できなかった。
linux2.txt を参照 ユーザー名を指定しての接続は \\192.168.xx.yy\user-name としてわざとエラーを出し、 「その他」をクリックして 「別のアカウントを使用する」を選ぶ。 windows と samba のパスワードが同一の場合は、 いきなりログイン出来てしまう。 smbpasswd でパスワードを変更すると、 linux のログインパスワードと samba のパスワードの 両方が変わる。 passwd でパスワードを変更すると、linux のパスワード だけが変わる。 いろいろといじっているうちに、telnet でログインすると 途中で止まるようになってしまった。止まっても ^C でログイン出来る。 リブートしたらなおった。謎。
pi.txt を参照 ファイル名は ○○.php パーミッションを 666 にすることを忘れないように!!!
○ 接続 DHT11 の詳しい説明はデータシートを参照 http://akizukidenshi.com/download/ds/aosong/DHT11_20180119.pdf DHT11 は 4 個端子がある。使うのは 3 個 1 Vcc 2 Data 3 NC 4 Gnd 電源 DC 3.3V ~ 5.5 V 3.3 V で運用するときはケーブルの長さは可能な限り短くする。 Data ピンは 4.7k でプルアップ Data 端子は入出力兼用という不思議な接続法である。 Data 端子の波形をオシロで見ると、 0 V と Vcc の 2 値をとるパルスである。 Vcc = 5 V に設定すると、パルス波形の立ち上がりがなまる。 ネットを見ると、Vcc = 5 V のサイトと Vcc = 3.3 V の サイトの 2 つの接続法がある。 実験してみると、どちらでも動作するが、ラズパイの 入力端子に 5 V をかけるのは良くないと思われるので、 私は 3.3 V で運用する。 ○ ライブラリのインストール # apt-get install git # git clone https://github.com/szazo/DHT11_Python.git これ以外にもライブラリがあるようだ。 https://se-lina.hatenablog.com/entry/2022/03/07/182723 によると、以下のライブラリがあるらしい。 git clone https://github.com/adafruit/Adafruit_Python_DHT.git ○ サンプルプログラム DHT11_Python のフォルダで実行する。 import dht11 を実行すると dht11/__init__.py を見に行く。 その他のフォルダで実行するときは、__init__.py を当該フォルダ にコピーし、ファイル名を dht11.py にリネームする。 以下のプログラムは Data は GPIO14 (8番端子) に 接続する場合である。 #!/usr/bin/python # -*- coding: utf-8 -*- import RPi.GPIO as GPIO import time, datetime import dht11 GPIO.setwarnings(True) GPIO.setmode(GPIO.BCM) instance = dht11.DHT11(pin=14) while True: result = instance.read() if result.is_valid(): temp = result.temperature humid = result.humidity print(temp, humid) time.sleep(1)
DHT20 の方が精度が良いらしい。 温度 ±0.5 ℃ 湿度 ±3 % DHT11 は 温度 ±2 ℃ 湿度 ±5 % 接続は I2C なので、ラズパイの設定で I2C を on に しておく。 # raspi-config Pi DHT20 1 (3.3V) --- 1 3 (SDA)----- 2 5 (SCL)----- 3 9 (Gnd)----- 4 穴が空いている面を上に、下向きに端子が伸びるように 配置して左から順番に 1-4 サンプルプログラム 参照:https://s-design-tokyo.com/use-dht20-raspberrypi/ import smbus, time send = [0xac, 0x33, 0x00] i2c = smbus.SMBus(1) address = 0x38 time.sleep(0.2) ret = i2c.read_byte_data(address, 0x71) while True: time.sleep(0.01) i2c.write_i2c_block_data(address, 0x00, send) time.sleep(0.08) data = i2c.read_i2c_block_data(address, 0x00, 0x07) humid = data[1] <<12 | data[2] << 4 | (( data[3] & 0xf0 ) >> 4 ) temp = ((data[3] & 0x0f) << 16 ) | data[4] << 8 | data[5] humid2 = humid / 2**20 * 100 temp2 = temp / 2**20 * 200 - 50 print("湿度 = {:3.0f} % 温度 = {:4.1f} 度".format(humid2, temp2)) time.sleep(1)
ホームディレクトリで実行される。 ファイルを扱うときに、スクリプトのあるフォルダを読み書きしたい時は、 スクリプトの存在するフォルダを script_path = os.path.abspath(os.path.dirname(__file__)) のように取得してスクリプト内で処理するか、 cron 内で (cd /home/pi/xxx/script-path ; ./script-fname ) のように cd してから実行する。
# apt install libopencv-dev # apt install python3-opencv 以下の pip3 を使う方法は エラーが出てインストールできない (1) pip をアップグレードする python3 -m pip install --upgrade pip (2) インストール元を指定する pip3 install opencv-python -i https://pypi.doubanio.com/simple/ 常にミラーサーバを使う場合は .config/pip/pip.conf の中を以下のように書く [global] index-url = https://pypi.doubanio.com/simple/ (3) sudo を付ける sudo pip3 install opencv-python
ラズパイA の再インストールを Rapberry Pi Imager v1.8.5 を 使って行う。 これまで使っていた SD カードに Raspberry Pi Imager で書き込もうと すると、パーティションを変えることができないというエラーがでる。 SD Card Formatter でクイックフォーマットすると、 書き込めるようになる。 Raspbian のレガシー版をインストールする。 X が起動した状態では、非常に重く、実用的な速度では動かない。 ドロップダウンメニューの項目を 1 個選ぶだけで、そのメニューが 表示されるまでに 10 分程度かかる。 レガシー Lite 版をインストールするとよさそうに見えるが、 なぜかキーボードが使えない。 レガシー版をインストールし、Wifi に接続することに成功したなら、 ターミナル内で raspi-config を起動し、 System Options で Boot/Auto Login で Console Autologin を選択 してリブートする。 これまで使っていた Wifi アダプタ IO Data WN-G150UM(2016 年購入)は使えない。 lsusb では認識するが、iwlist wlan0 scan を実行すると 周辺の Wifi ルータを認識しない。 2015 年頃の NOOBS_1_3_4 をインストールすると、 その Wifi アダプタを認識する。 しかし apt update でエラーが出る。 /etc/apt/sources.list の 1 行目に以下を 加えると apt update のエラーは回避できる。 deb http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi bullseye のところは Debian のバージョンによって変更する。 deb7:wheezy deb10:buster deb11:bullseye しかし、telnetd, telnet がエラーで入らない。 結論として、古い NOOBS は使えない。 ゆえに IO Data WN-G150UM(2016 年購入)は使えない(認識しない)。 ---------- Wifi アダプタは Elecom WDC-150SU2M (2020 年頃購入)を試したところ 繋がった。しかし、SD card が数日後に壊れて 再度インストールすると認識はするが、接続できない。 Planex GW-USNano2 を使う。 以下の 2 個のファイルを編集する。 ・/etc/wpa_supplicant/wpa_supplicant.conf 以下を追加 network={ ssid="rx....." psk="passwd" } ・/etc/dhcpcd.conf 以下を追加 interface wlan0 static ip_address=192.168.0.201/24 static routers=192.168.0.1 static domain_name_servers=192.168.0.1 8.8.8.8 8.8.4.4 # systemctl restart wpa_supplicant # systemctl restart dhcpcd # ifconfig ネットワークの設定をするときに使ったコマンドを以下に記す。 どれが役に立ったのかよく分からない。 # iwlist wlan0 scan # ip link set wlan0 down # ip link set wlan0 up # ip addr add 192.168.0.201/24 dev wlan0 # dhclient wlan0 # wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -i wlan0 # iwconfig wlan0 essid "ssd-id" key s:password # journalctl -u dhcpcd # journalctl -u wpa_supplicant Web サーバは python の HTTPServer CGIHTTPRequestHandler モジュールを使う方法と apache2 を使う方法がある。 python のモジュールは非常に反応が遅かったり、 ハングアップしたり、安定性が悪い。 apache2 の方が圧倒的に安定している。 ---------- ネットワークに繋がって CLI で再起動したら、 # apt update # apt install telnetd あとはリモートから接続して telnet, ftpd, ftp, emacs を インストールし、設定を行う。 apache2 のインストールはその後で行う。 シリアルを使うには raspi-config --- Interface Options --- Serial Port で シリアルコンソール no シリアルポート yes に設定する。
起動して Wifi の国を JP にセットする 再起動する <---- これが重要 こうしないとネットに接続するメニューが出てこない # apt update # apt upgrade (非常に時間がかかる)
addr を GND に接続すると 0x23 3.3 V に接続すると 0x5c ・raspi-config で I2C を有効にしておく 2 つ方法がある (1) adafruit-circuitpython-bh1750 を使う (2) 使わない (1) のときモジュールのインストールが必要。以下のように --break-system-packages をつけないとエラーがでる。 $ pip install adafruit-circuitpython-bh1750 --break-system-packages import board, adafruit_bh1750 i2c = board.I2C() bh1750 = adafruit_bh150.BH1750(i2c) value = bh1750.lux (2) のとき import time, smbus i2c = smbus.SMBus(1) bh1750_address = 0x23 # addr = GND のとき i2c.write_byte(bh1750_address, 0x01) # power on time.sleep(0.2) i2c.write_byte(bh1750_address, 0x07) # register reset time.sleep(0.2) i2c.write_byte(bh1750_address, 0x10) # high reso mode time.sleep(0.2) data = i2c.read_i2c_block_data(bh1750_address, 0x10) lux = ( data[0] << 8 | data[1] ) / 1.2 print(f"Light level: {lux:.0f} lux")
(1) adafruit_bh1750 使用 import time import board import adafruit_bh1750 import smbus # I2C for BH1750 (light sensor) i2c_bus = board.I2C() # SDA and SCL are automatically detected bh1750 = adafruit_bh1750.BH1750(i2c_bus) # I2C for DHT20 (temperature and humidity sensor) i2c = smbus.SMBus(1) dht20_address = 0x38 send = [0xac, 0x33, 0x00] # Initialize DHT20 sensor time.sleep(0.2) i2c.read_byte_data(dht20_address, 0x71) # Initialize DHT20 while True: # Read BH1750 lux value lux = bh1750.lux print(f"Light level: {lux} lux") # Read DHT20 temperature and humidity values time.sleep(0.01) i2c.write_i2c_block_data(dht20_address, 0x00, send) time.sleep(0.08) data = i2c.read_i2c_block_data(dht20_address, 0x00, 7) # Calculate humidity and temperature humid = data[1] << 12 | data[2] << 4 | ((data[3] & 0xf0) >> 4) temp = ((data[3] & 0x0f) << 16) | data[4] << 8 | data[5] humid2 = humid / 2**20 * 100 temp2 = temp / 2**20 * 200 - 50 print(f"Humidity: {humid2:.2f}%") print(f"Temperature: {temp2:.2f}°C") # Wait before next reading time.sleep(1) (2) adafruit のライブラリ不使用 #!/usr/bin/python import time import smbus # init_bh1750() の 6 行は全て必要 # 怠ると adafruit ライブラリ使用のプログラムの終了直後に実行すると # 1 個目のデータがおかしくなる。 def init_bh1750(): i2c.write_byte(bh1750_address, 0x01) # power on time.sleep(0.2) i2c.write_byte(bh1750_address, 0x07) # register reset time.sleep(0.2) i2c.write_byte(bh1750_address, 0x10) # high reso mode time.sleep(0.2) def read_bh1750(): data = i2c.read_i2c_block_data(bh1750_address, 0x10) lux = ( data[0] << 8 | data[1] ) / 1.2 return lux def init_dht20(): time.sleep(0.2) i2c.read_byte_data(dht20_address, 0x71) def read_dht20(): time.sleep(0.01) i2c.write_i2c_block_data(dht20_address, 0x00, \ [0xac, 0x33, 0x00]) time.sleep(0.08) data = i2c.read_i2c_block_data(dht20_address, 0x00, 7) humid = data[1] << 12 | data[2] << 4 | \ ((data[3] & 0xf0) >> 4) temp = ((data[3] & 0x0f) << 16) | data[4] << 8 | data[5] humid2 = humid / 2**20 * 100 temp2 = temp / 2**20 * 200 - 50 return(humid2, temp2) # global variable i2c = smbus.SMBus(1) dht20_address = 0x38 bh1750_address = 0x23 # addr = GND のとき init_dht20() init_bh1750() while True: (humid, temp) = read_dht20() lux = read_bh1750() print(f"Light level: {lux:.0f} lux") print(f"Humidity: {humid:.1f} %") print(f"Temperature: {temp:.1f} °C") # Wait before next reading print("") time.sleep(1)