●移行対象デバイス
以下のGPIOデバイスがライブラリィ変更対象
- LED
- タクト・スィッチ
- I2C 温湿度センサー(BME280)
- I2C LCDディスプレイ
pigpioに変更した結果、大きな変化は無かったが、LEDを徐々に消灯させる動作がスムーズになったように感じる。
以下は'smbus'と'RPi.GPIO'から'pigpio'への変更点で、それ程難しくは無く意外とあっさり変更できた。
●pigpioを使う準備
●pigpioのサービスを有効化して開始する
$ sudo systemctl enable pigpiod
$ sudo systemctl start pigpiod
※起動時のオプションを変更する場合は下記をファイル内を変更
/lib/systemd/system/pigpiod.service
●ライブラリィとインスタンス
●ライブラリィとインスタンス
import smbus
import RPi.GPIO as GPIO
↓
import pigpio
###
I2C_CH = 1
i2c_bus = smbus.SMBus( I2C_CH )
↓
pi = pigpio.pi() # create instance
pi2c_lcd = pi.i2c_open(I2C_CH, LCD_ADDR) # handle for LCD
pi2c_bme280 = pi.i2c_open(I2C_CH, BME280_ADDR) # handle for BME280
● 終了処理
LEDblue.stop()
↓
pi.set_PWM_dutycycle(LED_BLUE, 0) # blue off
GPIO.cleanup()
↓
cb1.cancel()
pi.i2c_close(pi2c_bme280)
pi.i2c_close(pi2c_lcd)
pi.stop()
●スィッチとLED
※スィッチのインタラプト処理ではチャタリングを考慮して押されている時間範囲を調整した
●GPIOタクトスィッチとLED関係
● スィッチインタラプト処理関数
def reqvoice(channel):
st = 0
cnt = 0
while st == 0:
st = GPIO.input(channel)
if st == 0:
cnt = cnt + 1
time.sleep(0.2)
print('status:{}, count:{}'.format(GPIO.input(channel), cnt))
if cnt in range(1,3):
elif cnt > 10:
if IoTCAP: disp(1)
cmd = "sudo shutdown -h now"
proc.run(cmd.split(' '))
else: pass
↓
def reqvoice(gpio, level, tick):
for i in range(30): # limit 0.2sec x 30 = 6sec
if pi.read(gpio) == 1:
end_tick = pi.get_current_tick()
else:
time.sleep(0.2)
duration = pigpio.tickDiff(tick, end_tick)
print('status:{}, duration:{}'.format(pi.read(gpio), duration))
if duration > 400000 and duration < 2000000: # over 400msec and under 2sec
:
:音声処理
:
elif duration > 2000000 and duration < 5000000: # over 2sec and under 5sec
if IoTCAP: disp(1)
cmd = "sudo shutdown -h now"
proc.run(cmd.split(' '))
else: pass
●GPIO タクトスィッチ、LEDの初期化
GPIO.setwarnings(False)
GPIO.setmode( GPIO.BCM )
GPIO.setup( CDS_PIN, GPIO.IN )
GPIO.setup( SW_GREEN, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.add_event_detect(SW_GREEN, GPIO.FALLING, callback = reqvoice, bouncetime = 1000) # 立下りイベントを記録
# LEDをアナログ周波数50Hzに設定
GPIO.setup( LED_BLUE, GPIO.OUT )
LEDblue = GPIO.PWM(LED_BLUE, 50) # LED青
LEDblue.start(0) # LEDをオフにする
↓
pi.set_mode(SW_GREEN, pigpio.INPUT)
pi.set_pull_up_down(SW_GREEN, pigpio.PUD_UP)
cb1 = pi.callback(SW_GREEN, pigpio.FALLING_EDGE, reqvoice)
# LEDをアナログ周波数50Hzに設定
pi.set_mode(LED_BLUE, pigpio.OUTPUT)
pi.set_PWM_frequency(LED_BLUE, 50) # FREQ = 50
pi.set_PWM_range(LED_BLUE, 25) # RANGE = 25
# LED off
LEDblue.ChangeDutyCycle(0) # blue off
↓
pi.set_PWM_dutycycle(LED_BLUE, 0) # blue off
# LED fade on/off
# IoTCAP 青LED on
for dc in range(0,11,1):
LEDblue.ChangeDutyCycle(dc) # blue fade-on
↓
pi.set_PWM_dutycycle(LED_BLUE, dc) # blue fade-on
time.sleep(0.04)
# IoTCAP 青LED off
for dc in range(10,-1,-1):
LEDblue.ChangeDutyCycle(dc) # blue fade-off
↓
pi.set_PWM_dutycycle(LED_BLUE, dc) # blue fade-off
time.sleep(0.04)
●BME280
※下記と共にBME280用モジュールも'pigpio'ライブラリィに変更している
● BME280用インスタンス
i2c = smbus.SMBus( I2C_CH )
bme280 = bme280( i2c_bus, BME280_ADDR )
bme280.setup()
↓
bme280 = bme280( pi, pi2c_bme280)
bme280.setup()
●LCD
※初期化、アドレスセット、書込み
● LCD用
# LCD初期化
bus=smbus.SMBus(I2C_CH)
time.sleep(0.1)
i2c_bus.write_i2c_block_data(LCD_ADDR, LCD_CMD, [0x38, 0x39, 0x14, 0x70, 0x56, 0x6c])
time.sleep(0.3)
i2c_bus.write_i2c_block_data(LCD_ADDR, LCD_CMD, [0x38, 0x0c, 0x01])
i2c_bus.write_i2c_block_data(LCD_ADDR, LCD_CMD, [0x05, 0x01])
↓
time.sleep(0.1)
pi.i2c_write_block_data(pi2c_lcd, LCD_CMD, [0x38, 0x39, 0x14, 0x70, 0x56, 0x6c])
time.sleep(0.3)
pi.i2c_write_block_data(pi2c_lcd, LCD_CMD, [0x38, 0x0c, 0x01])
# LCDアドレスセット
z=0x80+y*0x40+x
i2c_bus.write_i2c_block_data(LCD_ADDR, LCD_CMD, [z])
↓
pi.i2c_write_byte_data(pi2c_lcd, LCD_CMD, z)
# LCD書込み
for c in data:
i2c_bus.write_i2c_block_data(LCD_ADDR, LCD_DAT, [ord(c)])
↓
pi.i2c_write_byte_data(pi2c_lcd, LCD_DAT, ord(c))