您想利用比板上供应的更多的输入/输出端口。
办理方案

您可以利用外部端口扩展器,例如PCF8574或PCF8574A,它们具有八个输入/输出引脚,可以利用I2C进行掌握。草图创建了一个具有八个LED的条形图。图13-10显示了连接。
上图 PCF8574 / A端口扩展器驱动八个LED。
如果您利用的是3.3V的板子,请将Vcc连接到3.3V而不是5V,以避免破坏您的板子。
这个示例程序利用I2C端口扩展器来驱动LED,因此只须要两个引脚:
/I2C bargraph sketch利用I2C端口驱动条形图通过一个仿照传感器的值打开一系列与之成比例的LED灯。拜会食谱7.6/#include <Wire.h>const int address = 0x20; // PCF8574地址;利用0x38作为PCF8574/A的地址const int NbrLEDs = 8;const int analogInPin = A0; // 连接到可变电阻器的仿照输入引脚int sensorValue = 0; // 传感器读取的值int ledLevel = 0; // 将传感器值转换为LED“条”int ledBits = 0; // 每个LED的位将被设置为1以打开LEDvoid setup(){ Wire.begin(); // 设置Arduino I2C支持}void loop(){ sensorValue = analogRead(analogInPin); // 读取仿照值 ledLevel = map(sensorValue, 0, 1023, 0, NbrLEDs); // 映射到LED的数量 for (int led = 0; led < NbrLEDs; led++) { Wire.beginTransmission(address); if (led < ledLevel) { Wire.write(~(1 << led)); } else { Wire.write(0xFF); // 关闭所有LED } Wire.endTransmission(); // 将值发送到I2C }}
谈论:
电阻该当是220欧姆或更大(有关选择电阻的信息,请拜会第7章)。
该示例从analogRead读取一个值,然后将其映射到0到LED数量之间的值(ledLevel)。然后,该示例进入一个for循环,迭代每个LED。如果LED的编号小于ledLevel,则该示例将照亮该LED。在PCF8574/A上激活引脚的命令是一个位域:0b00000001(1)将引脚0设置为高电平,0b11111111(255)将所有引脚设置为高电平。然而,你不想通过PCF8574/A将引脚设置为高电平来点亮LED!
PCF8574/A的驱动LED的能力比Arduino低。每个引脚只能供应(源)眇小的电流,远远不敷以驱动LED所需的电流。但是,每个引脚可以吸收(汲取)高达25 mA的电流。这意味着你必须利用反向逻辑,类似于INPUT_PULLUP模式(请拜会第2.4节),利用PCF8574/A。这便是为什么每个LED连接到+5V/+3.3V而不是GND的缘故原由:当个中一个引脚变为LOW时,电流从正电源源出,并且引脚汲取该电流。这便是为什么该示例利用布尔Not运算符~来反转值的缘故原由(因此0b00000001,或1十进制,变为0b11111110,或254十进制)。
此外,还有一个额外的限定:PCF8574/A不能同时汲取超过80 mA的电流。因此,如果你要打开所有LED(0b00000000),它可能会事情,但你会超出芯片的限定,从而缩短其寿命。这便是为什么该示例仅利用布尔左移来打算一个位域,个中仅启用该引脚,然后反转该位域。你可以利用0b11111110打开引脚0,利用0b11110111打开引脚3。这发生得足够快,以至于由于视觉勾留,看起来多个灯光同时点亮。虽然在碰着未照亮的LED时发出Wire.write(0xFF)不是严格必要的,但这样做确保示例始终实行相同数量的命令,从而使LED的亮度保持同等,而不管有多少个LED被点亮。
如果您想在仍旧在PCF8574/A的限定范围内最小化闪烁,您可以每次点亮四个LED:
int bitField = 0;for (int led = 0; led < NbrLEDs; led++){ if (led < ledLevel) { bitField |= (1 << led); } if ((led + 1) % 4 == 0) // 每四个引脚发送一次命令 { Wire.beginTransmission(address); Wire.write(~bitField); Wire.endTransmission(); // 发送值到I2C bitField = 0; // 清空位域 }}
您可以通过变动标记为A0、A1和A2的引脚的连接来变动地址,如表13-3所示。如果您利用PCF8574/A分线板,它该当有用于选择地址的跳线或焊盘。
下表列出 PCF8574/A的地址值
要利用端口扩展器作为输入,可以按照以下步骤从扩展器中读取一个字节:
Wire.requestFrom(address, 1);if (Wire.available()){ data = Wire.receive(); Serial.println(data, BIN);}










