Good to Know Database

Raspbian Jessie: Ein- und Ausgänge des MCP23017 benutzen


Der MCP23017 ist ein 16 Bit I/O Expander welcher auch am I²C-Bus des Raspberry Pi's eingesetzt werden kann. Dadurch kann man den Raspberry Pi um weitere 16 digitale Eingänge beziehungsweise Ausgänge erweitern. Über die Pins A0 - A2 können Sie dem MCP23017 Baustein mit einer individuellen I²C-Adresse von 0x20 bis 0x27 konfigurieren. Das bedeutet Sie können bis zu 8 Bausteine direkt am I²C-Bus des Raspberry Pi's betreiben.

In dieser Anleitung wird anhand eines einfachen Beispiels gezeigt wie Sie die 16 digitalen Ports des MCP23017 in einem Python Skript verwenden können. Dabei werden die ersten 8 Ports (GPA0 - GPA7) als Eingänge und die zweiten 8 Ports (GPB0 - GPB7) als Ausgänge konfiguriert. Sobald sich der Zustand eines Einganges ändert soll der dazugehörige Ausgang ebenfalls seinen Zustand ändern.

I²C-Bus des Raspberry Pi's aktivieren

Bevor Sie den I²C-Bus des Raspberry Pi's unter Raspbian verwenden können, müssen Sie diesen aktivieren. Wie dies durchgeführt wird können Sie in der Anleitung Raspbian Wheezy: I²C-Unterstützung im Device Tree aktivieren nachlesen.

MCP23017 Adresse am I²C-Bus herausfinden

Damit Sie den MCP23017 ansprechen können, benötigen Sie dessen I²C Slave Adresse. Diese können Sie wie bereits in der Anleitung Raspbian Wheezy: Teilnehmer am I²C-Bus identifizieren beschrieben mit dem Befehl i2cdetect herausfinden. Wie Sie der folgenden Ausgabe entnehmen können, besitzt in diesem Fall der MCP23017 die Adresse 0x20. Über die Pins A0 - A2 können Sie eine individuelle I²C Adresse von 0x20 bis 0x27 konfigurieren.

pi@raspberrypi ~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Benötigte Python Module installieren

Als zusätzliches Python Modul wird das Paket python-smbus benötigt. Dieses enthält die Funktionalitäten für den Zugriff auf den System Management Bus (SMBus) und kann wie unter Raspbian Jessie: Python Modul für den SMBus-Zugriff installieren beschrieben installiert werden.

Python Skript erstellen

Für das folgende Python Skript erstellen Sie mit einem Editor die Datei mcp23017_input_output.py.

pi@raspberrypi ~ $ vi mcp23017_input_output.py

Fügen Sie in diese Datei den folgenden Python Code ein und speichern die Datei ab.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Creation:    07.04.2015
# Last Update: 09.04.2015
#
# Copyright (c) 2015 by Georg Kainzbauer <http://www.gtkdb.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#

# import required modules
import smbus
import time

# define I2C bus
# 0: Raspberry Pi Model B Rev 1.0
# 1: Raspberry Pi Model B Rev 2.0, Model A, Model B+, Model A+, Raspberry Pi 2 Model B and  Raspberry Pi 3 Model B
I2C_BUS = 1

# define I2C address of MCP23017 16-Bit I/O expander
# depends on the hardware pins A0 - A2
I2C_ADDR = 0x20

# define I/O direction (IODIR) registers
IODIRA = 0x00
IODIRB = 0x10

# define general purpose I/O (GPIO) registers
GPIOA = 0x12
GPIOB = 0x13

# define output latch (OLAT) registers
OLATA = 0x14
OLATB = 0x15

# main function
def main():
  try:
    # init I2C bus
    i2c = smbus.SMBus(I2C_BUS)

    # configure all GPA pins as inputs
    i2c.write_byte_data(I2C_ADDR, IODIRA, 0xFF)

    # configure all GPB pins as outputs
    i2c.write_byte_data(I2C_ADDR, IODIRB, 0x00)

    # set all output pins to 0
    i2c.write_byte_data(I2C_ADDR, OLATB, 0x00)

    # set start values
    bit0 = 0x00
    bit1 = 0x00
    bit2 = 0x00
    bit3 = 0x00
    bit4 = 0x00
    bit5 = 0x00
    bit6 = 0x00
    bit7 = 0x00
    output = 0x00

    while True:
      # read data from GPA port
      input = i2c.read_byte_data(I2C_ADDR, GPIOA)

      # check if GPA0 has changed and set GPB0 if required
      if bit0 != (input & 0x01)
        bit0 = input & 0x01
        if bit0 == 0x00:
          output = output & 0xFE
        else:
          output = output | 0x01

      # check if GPA1 has changed and set GPB1 if required
      if bit1 != (input & 0x02)
        bit1 = input & 0x02
        if bit1 == 0x00:
          output = output & 0xFD
        else:
          output = output | 0x02

      # check if GPA2 has changed and set GPB2 if required
      if bit2 != (input & 0x04)
        bit2 = input & 0x04
        if bit2 == 0x00:
          output = output & 0xFB
        else:
          output = output | 0x04

      # check if GPA3 has changed and set GPB3 if required
      if bit3 != (input & 0x08)
        bit3 = input & 0x08
        if bit3 == 0x00:
          output = output & 0xF7
        else:
          output = output | 0x08

      # check if GPA4 has changed and set GPB4 if required
      if bit4 != (input & 0x10)
        bit4 = input & 0x10
        if bit4 == 0x00:
          output = output & 0xEF
        else:
          output = output | 0x10

      # check if GPA5 has changed and set GPB5 if required
      if bit5 != (input & 0x20)
        bit5 = input & 0x20
        if bit5 == 0x00:
          output = output & 0xDF
        else:
          output = output | 0x20

      # check if GPA6 has changed and set GPB6 if required
      if bit6 != (input & 0x40)
        bit6 = input & 0x40
        if bit6 == 0x00:
          output = output & 0xBF
        else:
          output = output | 0x40

      # check if GPA7 has changed and set GPB7 if required
      if bit7 != (input & 0x80)
        bit7 = input & 0x80
        if bit7 == 0x00:
          output = output & 0x7F
        else:
          output = output | 0x80

      # output data on GPB port
      i2c.write_byte_data(I2C_ADDR, OLATB, output)

      # wait 100ms
      time.sleep(0.1)

  except KeyboardInterrupt:
    print("Execution stopped by user")

if __name__ == '__main__':
  main()

Nachdem Sie Das Python Skript erstellt haben, sollten Sie die Rechte der Datei anpassen.

pi@raspberrypi ~ $ chmod +x mcp23017_input_output.py

Jetzt können Sie das Python Skript wie folgt ausführen.

pi@raspberrypi ~ $ sudo ./mcp23017_input_output.py


Dieser Eintrag wurde am 19.02.2017 erstellt.

Direkter Link zu dieser Seite: http://www.gtkdb.de/index_36_2916.html

[ Zur Startseite ]   [ Zur Kategorie ]


Valid XHTML 1.0 Transitional Valid CSS Valid Atom 1.0

© 2004-2017 by Georg Kainzbauer