RaspberryPi3 B+入門 Step2- 入出力制御

# はじめに

- Lチカからカメラ、各種センサの使い方を学習したので備忘録

# RaspberryPi3 B+への入出力制御

- RasPiへの入出力は、[GPIO](https://www.raspberrypi.org/documentation/usage/gpio/README.md) (General-Purpose Input/Output：[多目的入出力](https://ja.wikipedia.org/wiki/GPIO))ポートを介して行う
 - [RPi.GPIO](https://pypi.org/project/RPi.GPIO/)
 - [Gpiozero](https://gpiozero.readthedocs.io/en/stable/index.html)

### [RasPi3 B+ Pin配列](https://pinout.xyz/)

```sh:実機のPin確認
$ pinout
```

<details>
<summary>出力例</summary>
<div>

```sh:
,--------------------------------.
| oooooooooooooooooooo J8     +====
| 1ooooooooooooooooooo      P | USB
|  Wi                     ooo +====
|  Fi  Pi Model 3B+ V1.3  ooE    |
|        ,----.               +====
| |D|    |SoC |               | USB
| |S|    |    |               +====
| |I|    `----'                  |
|                   |C|     +======
|                   |S|     |   Net
| pwr        |HDMI| |I||A|  +======
`-| |--------|    |----|V|-------'

Revision           : a020d3
SoC                : BCM2837
RAM                : 1024Mb
Storage            : MicroSD
USB ports          : 4 (excluding power)
Ethernet ports     : 1
Wi-fi              : True
Bluetooth          : True
Camera ports (CSI) : 1
Display ports (DSI): 1

J8:
   3V3  (1) (2)  5V
 GPIO2  (3) (4)  5V
 GPIO3  (5) (6)  GND
 GPIO4  (7) (8)  GPIO14
   GND  (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
   3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
 GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
   GND (25) (26) GPIO7
 GPIO0 (27) (28) GPIO1
 GPIO5 (29) (30) GND
 GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
   GND (39) (40) GPIO21

For further information, please refer to https://pinout.xyz/
```

</div>
</details>

```sh:ステータス確認
$ gpio readall
```

<details>
<summary>出力例</summary>
<div>

```txt:
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 1 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 1 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 1 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 1 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+
```

</div>
</details>

### サンプルコード (RPi.GPIO)

- Lチカやスイッチ(ON/OFF)など

```py:
import RPi.GPIO as GPIO

GPIO.getmode() # BOARD, BCM, None
GPIO.setmode(BCM)

GPIO.setup(25, GPIO.OUT)
GPIO.setup(24, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.output([11, 12], GPIO.LOW) # all ch: LOW
GPIO.output([11, 12], (GPIO.LOW, GPIO.HIGH)) # ch11: LOW, ch12: HIGH

GPIO.add_event_detect(26, GPIO.FALLING, call_back=my_func, bouncetime=200)

GPIO.output(24, not GPIO.input(24))

GPIO.cleanup()
```

### [RPLCD](https://github.com/dbrgn/RPLCD)

- [1602A LCD](https://www.amazon.co.jp/KKHMF-1602-%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-16%C3%972%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF-LCD%E3%83%96%E3%83%AB%E3%83%BC%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF%E3%83%A9%E3%82%A4%E3%83%88/dp/B0757C4W92/ref=sr_1_6?ie=UTF8&qid=1552403356&sr=8-6&keywords=LCD+1602)
- http://www.circuitbasics.com/raspberry-pi-lcd-set-up-and-programming-in-python/
- [HD44780 DataSheet](http://fab.cba.mit.edu/classes/863.06/11.13/44780.pdf)

```sh:パッケージのインストール
$ pip3 install RPLCD
```

```py:RPLCD_CharLCD.py
from time import sleep

from RPLCD.gpio import CharLCD
import RPi.GPIO as GPIO

lcd = CharLCD(numbering_mode=GPIO.BOARD, cols=16, rows=2, pin_rs=37, pin_e=35, pins_data=[33, 31, 29, 23])
lcd.write_string('Hello World.')
sleep(5)
lcd.close(clear=True)
```

##### SPI (Serial Peripheral Interface：[シリアル・ペリフェラル・インタフェース](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%BB%E3%83%9A%E3%83%AA%E3%83%95%E3%82%A7%E3%83%A9%E3%83%AB%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9))

- AD変換によりアナログ値を利用する

|制御信号|用途|
|:-:|:-:|
|SCK (Serial Clock)|同期クロック|
|MISO (Master In Slave Out)|入力|
|MOSI (Master Out Slave In)|出力|
|SS/CS/CE (Slave Select)|スレーブ識別|

##### I2C (Inter-Integrated Circuit：[アイ・スクエアド・シー](https://ja.wikipedia.org/wiki/I2C))

- デジタル値を直接利用する
- デバイスにはアドレスがある

|制御信号|用途|
|:-:|:-:|
|SDA (Serial Data)|入出力|
|SCL (Serial Clock)|同期クロック|

##### PWM (Pulse Width Modulation：[パルス幅変調](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%AB%E3%82%B9%E5%B9%85%E5%A4%89%E8%AA%BF))

- 高精度のPWM (2つ)： サーボモータの角度制御
- 低精度のPWM (複数)： 疑似的なアナログ制御(LEDの明るさ制御，DCモータの速度制御など)

-----

## [Picamera](https://picamera.readthedocs.io/en/release-1.13/#)

- [ラズパイ用 高画質 カメラモジュール](https://www.amazon.co.jp/%E3%83%A9%E3%82%BA%E3%83%91%E3%82%A4%E7%94%A8-%E9%AB%98%E7%94%BB%E8%B3%AA-%E3%82%AB%E3%83%A1%E3%83%A9%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-Camera-Raspberry/dp/B07GCSC42V/ref=redir_mobile_desktop?_encoding=UTF8&psc=1&ref=ppx_pop_mob_b_pd_title)
- [picamera github](https://github.com/waveform80/picamera)
- [カメラ：チュートリアル](https://projects.raspberrypi.org/en/projects/getting-started-with-picamera)

```sh:画像保存先の作成
$ cd /home/pi/MyProjects/raspi/Camera/
$ mkdir ./pictures/
$ mkdir ./videos/
$ sudo chmod 0755 ./pictures/
$ sudo chmod 0755 ./videos/
```

##### 静止画撮影

```py:02_Picture.py
from picamera import PiCamera
from time import strftime
from time import sleep

PAUSE_TIME = 3
PHOTO_SAVE_DIR = '/home/pi/MyProjects/raspi/Camera/pictures/'
FILE_NAME_FMT = '%Y-%m-%d_%H-%M-%S'

camera = PiCamera()
camera.rotation = 180
camera.resolution = (800, 600)
camera.start_preview(alpha=200)
sleep(PAUSE_TIME)
camera.capture(PHOTO_SAVE_DIR + strftime(FILE_NAME_FMT) + '.jpeg')
camera.stop_preview()
```

##### 動画撮影

```py:03_Video.py
from picamera import PiCamera
from time import strftime
from time import sleep

PAUSE_TIME = 10
VIDEO_SAVE_DIR = '/home/pi/MyProjects/raspi/Camera/videos/'
FILE_NAME_FMT = '%Y-%m-%d_%H-%M-%S'

camera = PiCamera()
camera.resolution = (800, 600)
camera.start_preview(alpha=200)
camera.start_recording(VIDEO_SAVE_DIR + strftime(FILE_NAME_FMT) + '.h264')
sleep(PAUSE_TIME)
camera.stop_recording()
camera.stop_preview()
```

```sh:動画再生
$ omxplayer yyyy-mm-dd_HH-MM-SS.h264
```

## DIY電子工作

- 電子工作については以下のサイトが大変役に立ちました。
ありがとうございます。

 - [Fritzing (配線図作成ソフト)](http://fritzing.org/home/)
 - [Fritzingの使い方](https://www.fabshop.jp/fritzing%E3%81%A7%E5%9B%9E%E8%B7%AF%E5%9B%B3%E3%83%BB%E9%85%8D%E7%B7%9A%E5%9B%B3%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86%EF%BC%81/)
 - [DIY環境 RaspberryPi](https://www.denshi.club/pc/raspi/)
 - [Raspberry Piで学ぶ電子工作 サポートページ](http://bluebacks.kodansha.co.jp/books/9784062579773/appendix/)
 - [Raspberry Piで学ぶ電子工作 補足情報](https://raspibb1.blogspot.com/)

# おわりに

- 基本的な入出力制御は理解出来た。
- この基本を組み合わせていけば、色々なシステム、装置が自作出来そう。
- 3Dプリンタが欲しくなる。