Raspberry Pi (3 Model B+) > GPIO > GPIOをGNDにショートするとRPiがハングする > Raspbianの振舞い > スライドスイッチの入力取得はGPIO.PUD_DOWNを使う (Python実装例 x 2+1)

```txt:動作環境
Raspberry Pi 3 Model B (以下RPi)
Raspbian Stretch
- python 2.7.13
- python 3.5.3
- bash v4.4.12
- Geany v1.29
- GNU Make 4.1
- gcc (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516
```

### はまり

- GPIOを使ったスイッチを作成
- スライドスイッチ
- VCC接続とGND接続をスライドスイッチで切替え
- GND接続時にssh接続したRPiの接続が切れる

### 注意

以下を見つけた。

https://www.raspberrypi.org/forums/viewtopic.php?t=42839

>  Connecting any GPIO to ground stops the processor.

...

> There seems to be a problem in bcm2835_gpio_len() in the bcm2835 library such that low detect enable checking hangs while the GPIO is brought low.

...

> as this is a known issue, and I quote:
...
> ***CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len() are used and the pin is pulled LOW it can cause temporary hangs on 2012-07-15-wheezy-raspbian and Occidentalisv01.***


Raspbian Stretchでもどうかの情報は未確認であるが、実際に発生している。

## スライドスイッチの入力取得 (Python)

スライドスイッチでの入力をするには

### 接続

[スライドスイッチ](https://www.monotaro.com/g/00027814/?t.q=%83X%83%89%83C%83h%83X%83C%83b%83%60%20on%20on)

- 中央: Pin# 11 GPIO17 (GPIO_GEN0)
- 端: Pin#01 3.3v DC Power

### 実装1 > スイッチ入力 (簡易チャタリング防止)

```python
#!/usr/bin/env python

import RPi.GPIO as GPIO
import time
import os

swio=11 # Pin# 11 (GPI_GEN0)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(swio, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

chk1=GPIO.HIGH
chk2=GPIO.HIGH
chk3=GPIO.HIGH
while True:
    chk1=chk2
    chk2=chk3
    chk3=GPIO.input(swio)
    #print GPIO.input(swio)
    if chk1==GPIO.LOW and chk2==GPIO.HIGH and chk3==GPIO.HIGH:
		print('VCC')

    time.sleep(0.3)
    
```

```
$ sudo python gpio_sw_in_190221.py 
VCC
VCC
VCC
VCC
```

スイッチをVCC側にした時に「VCC」が表示されることを確認できた。

### 実装2 > スイッチのHigh/Lowロガー

スイッチのHigh/Lowを1秒ごとに確認する。

```gpio_SW_in_190221.py
#!/usr/bin/env python

'''
Python 3.5.3 on Raspberry Pi 3 Model B+
'''

import RPi.GPIO as GPIO
import time
import os
from datetime import datetime as dt

swio = 11  # Pin# 11 (GPI_GEN0)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(swio, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
    swin = GPIO.input(swio)
    res = (swin == GPIO.HIGH)
    today = dt.today()
    strdt = today.strftime("%Y/%m/%d,%H:%M:%S")
    print("%s,%d" % (strdt, res))

    time.sleep(1.0)

```

```
$ sudo python3 sw_logger_190221.py 
2019/02/14,12:20:50,0
2019/02/14,12:20:51,0
2019/02/14,12:20:52,0
2019/02/14,12:20:53,0
2019/02/14,12:20:54,0
2019/02/14,12:20:55,1
2019/02/14,12:20:56,1
2019/02/14,12:20:57,1
2019/02/14,12:20:58,0
2019/02/14,12:20:59,0
```

SWをVCC接続にスライドした時に1となる。


### 実装2 v0.2 > flushの追加

実装2の処理では、nohupで使った時に出力が毎秒ファイルに書込まれない。

(注記: 以下はrc.localの例であるが、実行行の前でPythonスクリプトがあるディレクトリにcdをしている: 未記載)

```/etc/rc.local
...
nohup python sw_logger_190221.py >> /home/pi/LOG_190221/sw_log.txt &
```

stdoutのflush処理をすることで、これを回避する。
具体的には`sys.stdout.flush()`を追加する。

- [Python > Link > 出力ファイルへのリダイレクションをすぐに行う > sys.stdout.flush()](https://qiita.com/7of9/items/ebb6e65256db3d9427fa)


```sw_logger_190221.py
#!/usr/bin/env python

import sys

'''
Python 3.5.3 on Raspberry Pi 3 Model B+
'''

'''
v0.2 Feb. 21, 2019
  - flush stdout buffer each time
    + to use with [nohup] 
v0.1 Feb. 21, 2019
  - print GPIO input with timestamp
'''

import RPi.GPIO as GPIO
import time
import os
from datetime import datetime as dt

swio = 11  # Pin# 11 (GPI_GEN0)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(swio, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

while True:
    swin = GPIO.input(swio)
    res = (swin == GPIO.HIGH)
    today = dt.today()
    strdt = today.strftime("%Y/%m/%d,%H:%M:%S")
    print("%s,%d" % (strdt, res))
    sys.stdout.flush()

    time.sleep(1.0)

```