Raspberry Piで困ったことを書いていく

## はじめに
気温とか気圧とか色々記録したいなぁなどと
漠然とした理由から色々な製品を調べていたのですが
自分の用途にあった丁度良い製品が見当たらない。無いなら作ればよい！
ということで今更ですがRaspberry Piをはじめてみました。

本記事ではRaspberry Piを触っていて困ったことを書き溜めていきます。
（困ったことが発生した際に本記事に追加更新していきます。）

## 以下困ったこと集
### OSをBookWormに変えたらカメラ撮影時にERRORが頻発するようになった

#### 環境
|ハード|OS|Python|センサー|
|-----|--|------|-------|
|Raspberry zero 2 WH|Linux raspberrypizero2 6.6.62+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.62-1+rpt1 (2024-11-25) aarch64|Python3|PaspberryPi Camera Module 3 Wide|

#### 事象
以下のエラーが発生する
```python:
dmaHeap allocation failure for rpicam-apps0
ERROR: *** failed to allocate capture buffers for stream ***
```
#### 原因
カメラモジュールの使用するメモリ領域（dmaHeap）が不足している。

#### 対策
ラズパイカメラモジュールはDMA（Direct Memory Access）という方式を用いてCPUを介さず直接物理メモリを使用している。そしてDMAの領域を増やすにはCMA（Contiguous Memory Allocator）という仕組みを使用して物理メモリを予約しておく必要がある。ただ、予約といっても占有してしまうのではなく、使用していない時には解放される。

CMAを変更するにはOSブート時に読み込まれる```cmdline.txt```で変更する。
```bash:bash
$ sudo nano /boot/firmware/cmdline.txt
```
そして最終行に以下を追加して保存する（シンプルに```cma=512MB```だけでも良いかもしれない）
```bash:bash
gpu_mem_1024=256
gpu_mem_256=64
gpu_mem_512=128
start_x=1
camera_auto_detect=1
disable_fw_kms_setup=0
dtoverlay=imx708,cma-512
avoid_warnings=1
disable_splash=0
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=audio=on
enable_uart=0
gpu_mem=128
```
ブート時に読み込まれるため反映するためにリブートする。
```bash:bash
$ sudo reboot
```

## 以下困ったこと集
### ラズパイカメラがエラーで撮影できない

#### 環境
|ハード|OS|Python|センサー|
|-----|--|------|-------|
|Raspberry zero 2 WH|Linux raspberrypizero2 6.6.62+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.62-1+rpt1 (2024-11-25) aarch64|Python3|PaspberryPi Camera Module 3 Wide|

#### 事象
以下のエラーが発生する
```bash:
[0:02:26.202761389] [1045]  WARN V4L2 v4l2_videodevice.cpp:2127 /dev/video0[14:cap]: Dequeue timer of 1000000.00us has expired!
[0:02:26.202916031] [1045] ERROR RPI pipeline_base.cpp:1366 Camera frontend has timed out!
[0:02:26.202955564] [1045] ERROR RPI pipeline_base.cpp:1367 Please check that your camera sensor connector is attached securely.
[0:02:26.202990774] [1045] ERROR RPI pipeline_base.cpp:1368 Alternatively, try another cable and/or sensor.
ERROR: Device timeout detected, attempting a restart!!!
```
#### 原因
ラズパイ本体とカメラの接触不良。

#### 対策
ケーブルをきちんと挿す、掃除してみる　等

### Barometer BMP180のサンプルプログラム(31_barometer.py)がエラーで実行できない1
#### 環境
|ハード|OS|Python|センサー|
|-----|--|------|-------|
|Raspberry Pi 4 MODEL B||Python3|SUNFOUNDER Sensor Kit V2.0 for Raspberry Pi|

#### 事象
以下のエラーが発生する

```
$ sudo python3 31_barometer.py

 Barometer begins...
Traceback (most recent call last):
  File "31_barometer.py", line 42, in <module>
    loop()
  File "31_barometer.py", line 26, in loop
    sensor = BMP085.BMP085()
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_BMP-1.5.0-py3.7.egg/Adafruit_BMP/BMP085.py", line 66, in __init__
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO-1.0.4-py3.7.egg/Adafruit_GPIO/I2C.py", line 66, in get_i2c_device
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO-1.0.4-py3.7.egg/Adafruit_GPIO/I2C.py", line 99, in __init__
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO-1.1.8-py3.7.egg/Adafruit_PureIO/smbus.py", line 125, in __init__
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO-1.1.8-py3.7.egg/Adafruit_PureIO/smbus.py", line 150, in open
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'
```

#### 原因
I2Cが有効化されていない
#### 対応
##### I2Cを有効化してOSを再起動する
1. Raspberry Piのコンフィグを開く
`$ sudo raspi-config`

1. `3 Interface Options`　>　`P5 I2C`を選択する。[^1]
1. Would you like the ARM I2C interface to be enabled?　で`<はい>`を選択する。
1. The ARM I2C interface is enabled　で`<了解>`を選択する。
1. `<Finish>`で閉じる。
1. Raspberry Piを再起動する。
`$ sudo reboot`

### Barometer BMP180のサンプルプログラム(31_barometer.py)がエラーで実行できない2
#### 環境
|ハード|OS|Python|センサー|
|-----|--|------|-------|
|Raspberry Pi 4 MODEL B||Python3|SUNFOUNDER Sensor Kit V2.0 for Raspberry Pi|
#### 事象
以下のエラーが発生する

```
$ sudo python3 31_barometer.py

 Barometer begins...
Traceback (most recent call last):
  File "31_barometer.py", line 42, in <module>
    loop()
  File "31_barometer.py", line 27, in loop
    temp = sensor.read_temperature()	# Read temperature to veriable temp
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_BMP-1.5.0-py3.7.egg/Adafruit_BMP/BMP085.py", line 144, in read_temperature
TypeError: unsupported operand type(s) for >>: 'float' and 'int'
```

#### 原因
BMP085.pyで式の要素の型が合っていない

#### 対応
##### BMP085.pyを修正（式の要素に型を指定）する
エラーの内容より実行しているファイルが
`/usr/local/lib/python3.7/dist-packages/Adafruit_BMP-1.5.0-py3.7.egg/Adafruit_BMP/BMP085.py`であることがわかります。
こちらはeggファイルなので、このままですと修正するのが面倒くさいため
`Adafruit_BMP-1.5.0-py3.7.egg`を展開し配下の`Adafruit_BMP`フォルダを
以下のようにサンプルプログラムと同じフォルダにコピーします。
こうすることでPythonは親スクリプト（サンプルプログラム）の実行パスと同一パスのファイルから
優先して読み込まれるためコピー後のBMP085.pyが読み込まれます。

```
[/home/pi/SunFounder_SensorKit_for_RPi2/Python]
　├31_barometer.py
　└[Adafruit_BMP]
　　├__init__.py
　　└BMP085.py
```

つぎにコピーしたBMP085.pyを修正します。
エラーの内容では144行目がエラーであるとなっていますがこれはあくまでも
一番はじめにヒットしたエラー箇所であり
実は同種のエラー箇所が複数あります。
そのため以下のように複数行修正する必要があります。
いずれも明示的に変数をint型にするよう修正しています。

|行数|修正前|修正後|
|:----|:----|:----|
|144|temp = ((B5 + 8) >> 4) / 10.0|temp = (int(B5 + 8) >> 4) / 10.0|
|164|X1 = (self.cal_B2 * (B6 * B6) >> 12) >> 11|X1 = (self.cal_B2 * int(B6 * B6) >> 12) >> 11|
|165|X2 = (self.cal_AC2 * B6) >> 11|X2 = (self.cal_AC2 * int(B6)) >> 11|
|169|X1 = (self.cal_AC3 * B6) >> 13|X1 = (self.cal_AC3 * int(B6)) >> 13|
|170|X2 = (self.cal_B1 * ((B6 * B6) >> 12)) >> 16|X2 = (self.cal_B1 * (int(B6 * B6) >> 12)) >> 16|
|180|X1 = (p >> 8) * p >> 8)|X1 = (int(p) >> 8) * (int(p) >> 8)|
|182|X2 = (-7357 * p) >> 16|X2 = (-7357 * int(p)) >> 16|

自分はPythonを少しかじっていたのでわかりましたが初心者殺しだよなぁと＾＾；

### libcamera-helloでプレビューが真っ暗になってしまう
#### 原因
グラフィックアクセラレーションが有効化されていない
#### 対応
次の手順でグラフィックアクセラレーションを有効化する。
1. raspi-configを起動する
1. Advanced Option > Glamerを選択する
1. Glamer AccelerrationをEnable（有効化）する
1. OSを再起動する

## それではよきラズパイライフを！

[^1]: Raspberry Piのバージョンによりコンフィグのメニューが微妙に違います。