pigpio on Raspberry pi

# はじめに

- かなり前に、**pigpio**について調べた備忘録です。

# 公式サイト

- [pigpio](http://abyz.me.uk/rpi/pigpio/)

# インストール

```py:
$ sudo apt install pigpio python-pigpio python3-pigpio
```

# pigpiod起動

```py:
$ sudo pigpiod
```
# pigpioの自動起動

```py:
$ sudo systemctl enable pigpiod.service
$ sudo shutdown -r now

# リブート後の確認
$ sudo systemctl status pigpiod.service
```

### まずはLチカ

```py:led_pigpio.py
from time import sleep
import pigpio

pig = pigpio.pi()
pig.set_mode(21, pigpio.OUTPUT)

try:
    while True:
        sleep(1)
        pig.write(21, 1)
        sleep(1)
        pig.write(21, 0)
except KeyboardInterrupt:
    pig.stop()
```

### イベント処理

```py:sw_pd_event.py
from time import sleep
import pigpio

pig = pigpio.pi()
pig.set_mode(4, pigpio.INPUT)
pig.set_pull_up_down(4, pigpio.PUD_DOWN)

def cbf(gpio, level, tick):
    print(gpio, level, tick)

cb = pig.callback(4, pigpio.RISING_EDGE, cbf)

try:
    while True:
        sleep(0.01)
except KeyboardInterrupt:
    pig.stop()
```

### LCD表示

```py:lcd_pigpio.y
from time import sleep

import pigpio
from RPLCD.pigpio import CharLCD

pi = pigpio.pi()

lcd = CharLCD(pi, cols=16, rows=2, pin_rs=37, pin_e=35, pins_data=[33, 31, 29, 23], pin_contrast=9)
lcd.write_string('Hello RasPi')
sleep(3)
lcd.clear()
lcd.write_string('Test LCD pigpio')
sleep(3)
lcd.close(clear=True)
pi.stop()
```

# i2c: 9軸センサモジュール(BMX055)

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

import pigpio
from BMX055 import bmx055

bmx = bmx055()
bmx.setup()

try:
    while True:
        ax, ay, az = bmx.read_accel()
#        print("accel: ax={0}, ay={1}, az={2}".format(ax, ay, az))

        gx, gy, gz = bmx.read_gyro()
#        print("gyro: gx={0}, gy={1}, gz={2}".format(gx, gy, gz))

        cx, cy, cz = bmx.read_compass()
#        print("comp: cx={0}, cy={1}, cz={2}".format(cx, cy, cz))

        msg = "|       |  x  |  y  |  z  |\n"
        msg += "| accel | "+str(ax)+" | "+str(ay)+" | "+str(az)+" |\n"
        msg += "| gyro  | "+str(gx)+" | "+str(gy)+" | "+str(gz)+" |\n"
        msg += "| comp  | "+str(cx)+" | "+str(cy)+" | "+str(cz)+" |\n"
        print(msg)
        sleep(0.5)
except KeyboardInterrupt:
    bmx.stop()
```

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

import pigpio

class bmx055:
    def __init__(self):
        self.pi = pigpio.pi() 
        self.i2c_bus = 1 
        self.accel_addr = 0x19 
        self.accel = None 
        self.comp_addr = 0x13
        self.comp = None 
        self.gyro_addr = 0x69
        self.gyro = None 
        
    def open(self, i2c_addr):    
        return self.pi.i2c_open(self.i2c_bus, i2c_addr)

    def close(self, handle):
        self.pi.i2c_close(handle)

    def stop(self):
        self.close(self.accel)
        self.close(self.comp)
        self.close(self.gyro)
        self.pi.stop()

    def setup(self):
        self.accel = self.open(self.accel_addr) 
        self.pi.i2c_write_byte_data(self.accel, 0x0f, 0x03)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.accel, 0x10, 0x08)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.accel, 0x11, 0x00)
        sleep(0.1)
        
        self.gyro = self.open(self.gyro_addr) 
        self.pi.i2c_write_byte_data(self.gyro, 0x0f, 0x04)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.gyro, 0x10, 0x07)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.gyro, 0x11, 0x00)
        sleep(0.1)

        self.comp = self.open(self.comp_addr) 
        self.pi.i2c_write_byte_data(self.comp, 0x4b, 0x83)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.comp, 0x4b, 0x01)
        sleep(0.1)
        self.pi.i2c_write_byte_data(self.comp, 0x4c, 0x00)
        self.pi.i2c_write_byte_data(self.comp, 0x4e, 0x84)
        self.pi.i2c_write_byte_data(self.comp, 0x51, 0x04)
        self.pi.i2c_write_byte_data(self.comp, 0x52, 0x16)

        sleep(0.3)

    def read_accel(self):
        x_l = self.pi.i2c_read_byte_data(self.accel, 0x02)
        x_m = self.pi.i2c_read_byte_data(self.accel, 0x03)
        y_l = self.pi.i2c_read_byte_data(self.accel, 0x04)
        y_m = self.pi.i2c_read_byte_data(self.accel, 0x05)
        z_l = self.pi.i2c_read_byte_data(self.accel, 0x06)
        z_m = self.pi.i2c_read_byte_data(self.accel, 0x07)

        x = ((x_m*256) + (x_l&0xf0))/16
        if (x > 2047):
            x -= 4096
        y = ((y_m*256) + (y_l&0xf0))/16
        if (y > 2047):
            y -= 4096
        z = ((x_m*256) + (z_l&0xf0))/16
        if (z > 2047):
            z -= 4096

        return (x, y, z)


    def read_compass(self):
        x_l = self.pi.i2c_read_byte_data(self.comp, 0x42)
        x_m = self.pi.i2c_read_byte_data(self.comp, 0x43)
        y_l = self.pi.i2c_read_byte_data(self.comp, 0x44)
        y_m = self.pi.i2c_read_byte_data(self.comp, 0x45)
        z_l = self.pi.i2c_read_byte_data(self.comp, 0x46)
        z_m = self.pi.i2c_read_byte_data(self.comp, 0x47)
        t_l = self.pi.i2c_read_byte_data(self.comp, 0x48)
        t_m = self.pi.i2c_read_byte_data(self.comp, 0x49)

        x = (x_m << 8) + (x_l >> 3)
        if (x > 4095):
            x -= 8192
        y = (y_m << 8) + (y_l >> 3)
        if (y > 4095):
            y -= 8192
        z = (x_m << 8) + (z_l >> 3)
        if (z > 16383):
            z -= 32768

        return (x, y, z)

    def read_gyro(self):
        x_l = self.pi.i2c_read_byte_data(self.gyro, 0x02)
        x_m = self.pi.i2c_read_byte_data(self.gyro, 0x03)
        y_l = self.pi.i2c_read_byte_data(self.gyro, 0x04)
        y_m = self.pi.i2c_read_byte_data(self.gyro, 0x05)
        z_l = self.pi.i2c_read_byte_data(self.gyro, 0x06)
        z_m = self.pi.i2c_read_byte_data(self.gyro, 0x07)

        x = (x_m*256) + x_l
        if (x > 32767):
            x -= 65536
        y = (y_m*256) + y_l
        if (y > 32767):
            y -= 65536
        z = (x_m*256) + z_l
        if (z > 32767):
            z -= 65536

        return (x, y, z)
```

# PWMにてサーボモータ(SG92)を制御

### サーボモータ(SG92)仕様表
|項目|値|備考|
|:-:|:-:|:-:|
|可動角|180度|   |
|速度|0.1s / 60度|   |
|電圧|4.8 ～ 5.0V|   |
|パルス周期|10,000 - 20,000μs|   |
|パルス幅|500 - 2,400μs|※データシート:1,000 - 2,000μs|

```py:SG90.py
import pigpio

class SG90:
    """SG90_Spec:
    # 可動角: 180度
    # スピード: 0.1s / 60度
    # 電圧: 4.8 ～ 5V
    # パルス周期: 10,000 - 20,000μs
    # パルス幅: 500 - 2,400μs ※データシート:1,000 - 2,000μs
    """
    def __init__(self, pin=None):
        self.range_of_motion = 180
        self.min_pulse_width = 500
        self.max_pulse_width = 2400
        self.pig = pigpio.pi()
        self.pin = pin
    
    def move(self, rad):
        if self.pin == None:
            pass
        else:
            spw = (rad/self.range_of_motion) * (self.max_pulse_width-self.min_pulse_width) + self.min_pulse_width
            self.pig.set_servo_pulsewidth(self.pin, spw)

    def stop(self):
        self.pig.set_servo_pulsewidth(self.pin, 0)
```

# おわりに

- 人感センサ、赤外線センサ、温湿度センサ、照度センサの使い方を調べる。
- RaspberryPi 4 欲しいな。