8ビットI/Oエクスパンダ(MCP23008/MCP23S08)を用いたLEDアレイの点灯プログラム例

シリアルインターフェイス(I2C又はSPI)の8ビットI/OエクスパンダIC(MCP23008/MCP23S08:Microchip製)を用いて、LEDアレイ(OSX10201-R)を点灯させるプログラムを紹介する。
●使用したIC部品

MCP23008(I2C接続)

MCP23S08(SPI接続)
シリアルインターフェイス8ビットI/OエクスパンダICは、I2Cインターフェイス(MCP23008)はmarutsuオンラインで1個\458、SPIインターフェイス(MCP23S08)は秋月電子通商で1個\200で入手した。
■主な仕様
・ポート数:8
・インターフェイス:I2CまたはSPI
・電源電圧min.:1.8V
・電源電圧max.:5.5V
・クロック周波数max.:10MHz
・出力電流max.:25mA
●LEDアレイ点灯回路図

・I2CによるLEDアレイ点灯回路

・SPIによるLEDアレイ点灯回路
●LEDアレイ点灯のプログラム例
サンプルプログラムは、10LEDアレイの内8個を使って、指定した番号のLEDを点灯/消灯させる事例。
<プログラム事例>
・I2CによるLEDアレイ点灯モジュール(I2C_EXPANDA.py)
import RPi.GPIO as GPIO import smbus import time # ピンの名前を変数として定義 DEV_RESET = 5 REG_IODIR = 0x00 # I/O方向レジスタ REG_GPIO = 0x09 # PORT レジスタ(入出力) REG_IOCON = 0x05 # 設定レジスタ DEV_ADR = 0x20 # Device Address=0b010 0000(A2=0, A1=0, A0=0) #================================================================= class MCP23008: def __init__(self): # I2Cの初期化とMC23008デバイス設定 self.I2C = smbus.SMBus(1) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(DEV_RESET, GPIO.OUT, initial=GPIO.HIGH) # Device Reset = 0 # デバイスのリセット GPIO.output(DEV_RESET, GPIO.LOW) # Device Reset = 0 time.sleep(0.01) GPIO.output(DEV_RESET, GPIO.HIGH) # デバイスの初期設定 self.I2C.write_byte_data(DEV_ADR, REG_IODIR, 0x00) # IODIRレジスタ:データI/Oを出力に設定 self.I2C.write_byte_data(DEV_ADR, REG_IOCON, 0x38) # IOCONレジスタ(シーケンシャル禁止、アドレスピン許可)に設定 # 全ビット消去 self.bitStat = 0x00 self.ALLOFF() def ON(self, no): if type(no) != list: no = [no] for bit in no: self.bitStat = self.bitStat | (0x01 << bit) self.I2C.write_byte_data(DEV_ADR, REG_GPIO, ~self.bitStat) def OFF(self, no): if type(no) != list: no = [no] for bit in no: self.bitStat = self.bitStat & ~(0x01 << bit) self.I2C.write_byte_data(DEV_ADR, REG_GPIO, ~self.bitStat) def ALLOFF(self): self.bitStat = 0x00 self.I2C.write_byte_data(DEV_ADR, REG_GPIO, ~self.bitStat) def close(self): self.ALLOFF() GPIO.cleanup() def readDeviceStat(self): # データRead byteData = self.I2C.read_byte_data(DEV_ADR, REG_GPIO) return byteData #///////////////////////////////////////////////////////// if __name__ == '__main__': i2cExpanda = MCP23008() for ot in range(8): i2cExpanda.ON(ot) print(hex(i2cExpanda.readDeviceStat()).upper()) time.sleep(2) i2cExpanda.OFF(ot) i2cExpanda.ON([0,1,2,3,4,5,6,7]) time.sleep(2) i2cExpanda.OFF([1,3,5,7]) time.sleep(2) i2cExpanda.ALLOFF() i2cExpanda.ON([0,1,2,3]) time.sleep(2) i2cExpanda.ALLOFF() i2cExpanda.ON([4,5,6,7]) time.sleep(2) i2cExpanda.close()
・SPIによるLEDアレイ点灯モジュール(SPI_EXPANDA.py)
import RPi.GPIO as GPIO import time # ピンの名前を変数として定義 SPICLK = 11 SPIMOSI = 10 SPIMISO = 9 SPICS = 8 DEV_RESET = 5 REG_IODIR = 0x00 # I/O方向レジスタ REG_GPIO = 0x09 # PORT レジスタ(入出力) REG_IOCON = 0x05 # 設定レジスタ DEV_ADR = 0x00 # Device Address(A1=0, A0=0) #================================================================= class MCP23S08: def __init__(self): # SPIの初期化とMC23S08デバイス設定 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(SPICLK, GPIO.OUT) GPIO.setup(SPIMOSI, GPIO.OUT) GPIO.setup(SPIMISO, GPIO.IN) GPIO.setup(SPICS, GPIO.OUT, initial=GPIO.HIGH) #CS Not Select GPIO.setup(DEV_RESET, GPIO.OUT, initial=GPIO.HIGH) # Device Reset = 0 # デバイスのリセット GPIO.output(DEV_RESET, GPIO.LOW) # Device Reset = 0 time.sleep(0.01) GPIO.output(DEV_RESET, GPIO.HIGH) # デバイスの初期設定 self.writeDevice(REG_IODIR, 0x00) # IODIRレジスタ:データI/Oを出力に設定 self.writeDevice(REG_IOCON, 0x38) # IOCONレジスタ(シーケンシャル禁止、アドレスピン許可)に設定 # 全ビット消去 self.bitStat = 0x00 self.ALLOFF() def ON(self, no): if type(no) != list: no = [no] for bit in no: self.bitStat = self.bitStat | (0x01 << bit) self.writeDevice(REG_GPIO, ~self.bitStat) def OFF(self, no): if type(no) != list: no = [no] for bit in no: self.bitStat = self.bitStat & ~(0x01 << bit) self.writeDevice(REG_GPIO, ~self.bitStat) def ALLOFF(self): self.bitStat = 0x00 self.writeDevice(REG_GPIO, ~self.bitStat) def close(self): self.ALLOFF() GPIO.cleanup() #====== Read/Write I/O Data======== def readDeviceStat(self): # Read Mode 設定 readRegister = [0x41 | (DEV_ADR << 1), REG_GPIO] # Read Mode & Register GPIO.output(SPICS, GPIO.LOW) # CS Active self.sendData(readRegister) # データRead bitData = 0 for bt in range(8): # MSBから8ビット受信 GPIO.output(SPICLK, GPIO.HIGH) bitData <<= 1 bitData |= GPIO.input(SPIMISO) GPIO.output(SPICLK, GPIO.LOW) GPIO.output(SPICS, GPIO.HIGH) #CS Stand-By return bitData #====== Write I/O Data ======== def writeDevice(self, regNo, byteData): # Write Mode & Register & Data 設定 writeRegData = [0x40 | (DEV_ADR << 1), regNo, byteData] GPIO.output(SPICS, GPIO.LOW) # CS Active self.sendData(writeRegData) GPIO.output(SPICS, GPIO.HIGH) #CS Stand-By return #====== Send Data To Device======== def sendData(self, byteData): for outBit in byteData: for bt in range(8): # MSBから8ビット送信 GPIO.output(SPICLK, GPIO.LOW) GPIO.output(SPIMOSI,(outBit >> (7 - bt)) & 0x01) GPIO.output(SPICLK, GPIO.HIGH) #///////////////////////////////////////////////////////// if __name__ == '__main__': spiExpanda = MCP23S08() for ot in range(8): spiExpanda.ON(ot) print(hex(spiExpanda.readDeviceStat().upper()) time.sleep(2) spiExpanda.OFF(ot) spiExpanda.ON([0,1,2,3,4,5,6,7]) time.sleep(2) spiExpanda.OFF([1,3,5,7]) time.sleep(2) spiExpanda.ALLOFF() spiExpanda.ON([0,1,2,3]) time.sleep(2) spiExpanda.ALLOFF() spiExpanda.ON([4,5,6,7]) time.sleep(2) spiExpanda.ALLOFF() spiExpanda.close()
●プログラム実行結果

I2C-8ビットI/Oエクスパンダを利用したLEDアレイ点灯

I2C-8ビットI/Oエクスパンダを利用したLEDアレイ点灯