如何在Raspberry Pi中使用MCP23017 I2C端口扩展器– Part 1

27

对于我的所有项目,我都使用标准的GPIO接头引脚作为输入和输出。这使您总共可以使用17个引脚,但是如果您需要更多引脚该怎么办?

获得更多输入和输出的最简单方法是使用“i/o port expander”。这是一种设备,您可以使用发送到该设备的数据来控制多个端口。

MCP23017电路示例其他人在使用I2C设备方面取得了很多成功,因此我决定尝试一下。 I2C是一种串行通信协议,它允许芯片在同一芯片上交换数据“bus”。端口扩展器获取数据并控制适当的引脚。这样一来,仅使用少数Pi即可控制许多传感器和设备’s 通用输入输出 pins.

硬件设置

MCP23017 16位端口扩展器我选择的设备是MCP23017 I2C端口扩展器,共有16个端口。要驱动它,您可以使用Pi上的两个I2C引脚’s 通用输入输出头(引脚3和5)。这将使我们可以玩31(15 + 16)个输入或输出!

It’实际上,可以驱动多个端口扩展器,从而大大提高了可用输入或输出的数量。添加另一个MCP23017将使GPIO数量从31增加到47(15 + 16 + 16)。全部花了几英镑。

这些设备的优点在于它们很便宜(几英镑/ $)并且需要很少的外部组件。

在这个例子中’我们有3个LED和一个按钮开关连接到设备,该设备由Pi上的两个I2C引脚驱动。一世’我们使用了330欧姆电阻来限制流过LED的电流。您可以使用其他合适的值,但我倾向于使用330(因为我’由于我的BerryClip股票,有很多可用的!):

MCP23017 IO扩展器示例开关电阻为10Kohm,并将输入接地。这样可以确保输入一直为低电平,直到按下开关为止。按下开关可在输入上施加3.3V电压,使其变为高电平。电阻会阻止这种情况,从而导致两个电源轨之间短路。

  • 引脚9(VDD)连接到3.3V
  • 引脚10(VSS)接地
  • Pin 12 (SCL) is connected to Pin 5 上 的Pi 通用输入输出
  • Pin 13 (SDA) is connected to Pin 3 上 的Pi 通用输入输出
  • 正常工作时,引脚18(复位)应设为高电平,因此我们将其连接至3.3V
  • 15、16针&17(A0-A2)确定分配给该设备的编号。我们仅使用一个设备,因此我们将所有这三个引脚都设置为0(接地),将其设为二进制零。

这是我的测试电路在小面包板上构建的照片:

MCP23017电路示例

系统设置

要在Pi上使用I2C,您需要在Raspbian中启用一些功能,因为默认情况下未启用它。这是一个相当简单的过程,我对此进行了描述 在Raspberry Pi上启用I2C接口 教程。

测试硬件

一旦您’已启用i2c接口并连接硬件,请仔细检查接线。确保3.3V输入正确的引脚’没有短路。给树莓派上电,等待它启动。

如果你’已获得Rev 2 Pi或更高版本,然后键入以下命令:

sudo i2cdetect -y 1

如果你’具有原始的Rev 1 Pi,然后键入以下命令:

sudo i2cdetect -y 0

为什么会有所不同?在Pi的Rev 1和Rev 2版本之间,他们更改了到达GPIO接头连接器上的Pin 3和Pin 5的信号。这将需要与I2C一起使用的设备号从0更改为1。

我使用了Rev 1 Pi,我的输出看起来像这样:

[email protected] ~ $ sudo i2cdetect -y 0
     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: -- -- -- -- -- -- -- --

这表明我’连接了一个设备,其地址为0x20(十进制为32)。这是因为三个地址引脚设置为低电平。如果将A0设置为高,则地址将变为0x21(十进制为33)。如何设置A0,A1和A2取决于您,但是所有I2C设备都必须具有唯一的地址。

命令行测试

为了进行快速测试,我们可以使用命令行启用GPA0上的LED:

首先我们配置Port A引脚GPA0-6作为输出,GPA7作为输入。 (二进制为10000000,十六进制为0x80):

sudo i2cset -y 1 0x20 0x00 0x80 

Then we set GPA0 to logic high which will enable 的LED :

须藤i2cset -y 1 0x20 0x14 0x01

To turn off 的LED we use :

sudo i2cset -y 1 0x20 0x14 0x00

如果使用的是Rev 1板,请记住将1替换为0。

It’是时候开始使用这些额外的GPIO…

查看 如何在Raspberry Pi中使用MCP23017 I2C端口扩展器–第2部分 有关如何使用Python脚本控制输出的说明。

查看 如何在Raspberry Pi上使用MCP23017 I2C端口扩展器–第3部分 有关如何使用Python脚本控制输入的说明。

这是我的测试电路的一些照片供参考:

分享。

27条留言

    • I’ve更新了文本。它们是330欧姆。我用它们是因为我’它们中有很多可用,但是如果需要,您可以使用其他值。

      • 马特

        感谢您的快速响应,开关和地之间的另一个电阻又如何(这是做什么用的?)对我来说,这很多是新来的,请原谅我的问题,
        我使用RPI搭建了象棋计算机&一个Arduino,(www.chess.fortheray.co.uk)因为PI上没有引脚,所以我需要Arduino,但是使用端口扩展器应该可以使我在RPI上完成所有操作。

        谢谢,

        最高

        • 开关电阻为10Kohm。一世’ve更新了文本,以对其目的进行更多解释。当不按下开关时,它将输入接地(低)。按下开关时,输入为3.3V(高)。电流流经电阻,但仅为3.3 / 10 mA,因此没有明显的影响。

          • 马特

            我已经完成了您所有出色的教程,现在我想我拥有了项目所需的一切。我正在构建一个木制国际象棋计算机,该计算机使用64个磁簧开关感应运动,并通过64个LED发出信号。即使使用多路复用,我也需要24个输入。看到 http://www.chess.fortherapy.co.uk .
            在我最初的项目中,我使用Arduino提供输入,并与RPI进行串行通信,但是现在我应该能够在Pi上进行所有操作。再次感谢,马克斯

  1. 蒂姆贝格特

    非常感谢Matt提供的这个清晰的教程。它使我有信心将我的互联网广播项目发展到现在包括许多预设的广播电台。一个忧虑是轮询所有切换的输入将花费时间,但是我只能尝试。
    干杯,蒂姆伯格。

    • 那’故意的。面包板上的电源导轨上有空隙,因此我不得不画水平连接才能将电线连接到孔上。我不’像对角线ðŸ™,

  2. 你好一世’m试图使用MCP23017为简单的段显示供电(每个段的onme引脚)。问题是,该网段使用一个共享的3.3V连接,然后通过连接接地来控制每个网段。

    为了我的一生,我可以’t找出如何使用该芯片打开/关闭GND连接–它似乎仅支持通过每个引脚输出功率。有任何想法吗?

  3. 很棒的教程!一世’我将尝试使用它来创建烤箱测绘设备(9个温度探头–每个角加一个中心)。在AtoD转换中,我需要很多针脚用于分辨率。我收集了在软件代码中依次激活每个MCP23017的信息,然后将依次从每个探头中读取一个样本温度读数(尽管只有八个地址可用,所以八个MCP芯片/探针?)。一世’我仍然处于早期阶段。

    • MCP23017是端口扩展器,因此它为您提供8个输入和输出。这些只是逻辑级别。它为N’t an ADC so can’t读取模拟输入。这取决于探针,但您应该查看我的MCP3008帖子。那是一个具有8个输入的ADC。您可以使用两个设备以10位精度读取16个模拟通道。

      • 你好,谢谢你的回复。一世’我非常热衷于获得我所能获得的最大精度(如果我’m lucky). I’由于其14位分辨率和冷端补偿,我们一直在检查Maxim31855(每个探头可能一个芯片)。输出是一个串行输出,我想我可能必须使用一个多路复用器,但是如果我可以避免它,并且在所有9个点上采样温度,那么效果会更好吗?

  4. 你好

    I’m trying to understand 的i2cset commands better ðŸ™,

    须藤i2cset -y 1 0x20 0x14 0x01

    完美运作– 的LED goes 上 ðŸ™,

    的“1” I understand – reference to 的总线 上 的Raspberry Pi.
    0x20 is 的address of 的chip
    0x14-这是哪里来的? man i2cset说这是数据地址–但是,如果我看一下mcp23017数据表,这似乎是INTCONB的地址。显然我不’当LED点亮ðŸ™,时,您将无法理解
    0x01– set pin 0 high

    很想了解我在哪里’m读取数据表错误ðŸ™,

  5. 首先,请允许我感谢您的出色文章。

    I’我曾经使用过Arduino,通常我必须在SDA和SCL上将4.7K电阻器放置到5V。为什么不’您在Raspberry Pi上执行此操作吗? SDA和SCL引脚上是否具有内部上拉电阻?

  6. 嘿,谢谢您的精彩教程! ðŸ™,

    是否可以在Pi上添加一个I / O扩展器(如MCP23017)并连接一个广告转换器(如MCP3008)并在该传感器上附加一些传感器?

    不知道那是否可能。
    如果是这样,您是否偶然知道在这种情况下如何进行接线?
    ðŸ™,

  7. 基思·克鲁克斯

    嗨,我认为我的厚度非常大,在本示例中,我已经看到如何使用须藤i2cset -y 1 0x20 0x14 0x01来使LED灯发光,但是我如何修改代码以使连接到GPA1的第二盏LED灯欢呼起来

    • 三个LED连接到GPA1,2&3.要点亮它们,您需要考虑一个3位的二进制序列,但是将其转换为十六进制代码。

      雷格
      —–
      001– 绿色 ON
      010– 黄色 ON
      100– 红 ON
      101– 红 and 绿色 ON

      So …

      绿色
      须藤i2cset -y 1 0x20 0x14 0x01

      黄色
      sudo i2cset -y 1 0x20 0x14 0x02


      sudo i2cset -y 1 0x20 0x14 0x04

      要点亮绿色和红色,您需要1 + 4:
      sudo i2cset -y 1 0x20 0x14 0x04

      黄色和红色为2 + 4:
      sudo i2cset -y 1 0x20 0x14 0x06

  8. 戴夫·克莱伯特

    为什么该电路的A0,A1和A2有3个接地?
    为什么RESET上有电压?

    为了简单起见,仅输出这些是完全必要的吗?

    • A0,A1和A2接地,以确保它们设置为低电平。如果不是’连接到他们的逻辑水平可能“float”并给出不可预测的结果。根据数据手册中的定义,正常工作时,复位引脚设置为高电平。连接到高电平或低电平时,您会知道它们处于什么状态。’将它们连接起来,其状态是未知且不可预测的。

发表评论

该网站使用Akismet减少垃圾邮件。 了解如何处理您的评论数据.