以下是针对不同通信方式的 针脚级连接示例 和 关键元件接线图,包含详细步骤和注意事项,帮助您快速实现多 Arduino 互联:
一、I²C 通信(1主多从)
场景:1个主控Arduino + 2个从机Arduino(最多可扩展至112个设备)
所需元件:
元件 | 数量 | 作用 |
---|---|---|
4.7kΩ 上拉电阻 | 2个 | 稳定 I²C 总线电平 |
杜邦线 | 若干 | 连接 SDA/SCL/GND |
接线图:
plaintext
主控 Arduino (Master) 从机1 (Slave1) 从机2 (Slave2) A4 (SDA) —————————— A4 (SDA) ———————— A4 (SDA) A5 (SCL) —————————— A5 (SCL) ———————— A5 (SCL) GND —————————— GND ———————— GND │ │ │ ├─4.7kΩ─VCC ├─4.7kΩ─VCC ├─4.7kΩ─VCC (接5V)
代码示例:
主控端 (Master):
cpp
#include <Wire.h> void setup() { Wire.begin(); // 作为主设备启动 Serial.begin(9600); } void loop() { // 向从机1(地址8)请求数据 Wire.requestFrom(8, 1); while (Wire.available()) { int data = Wire.read(); Serial.print("From Slave1: "); Serial.println(data); } // 向从机2(地址9)发送命令 Wire.beginTransmission(9); Wire.write('A'); // 发送字符'A' Wire.endTransmission(); delay(500); }
从机1 (Slave1 - 地址8):
cpp
#include <Wire.h> void setup() { Wire.begin(8); // 设置从机地址为8 Wire.onRequest(requestEvent); // 注册主设备请求回调 } void loop() {} void requestEvent() { Wire.write(analogRead(A0) / 4); // 发送A0模拟值 }
从机2 (Slave2 - 地址9):
cpp
#include <Wire.h> void setup() { Wire.begin(9); Wire.onReceive(receiveEvent); // 注册主设备发送回调 pinMode(LED_BUILTIN, OUTPUT); } void receiveEvent(int bytes) { char c = Wire.read(); if (c == 'A') digitalWrite(LED_BUILTIN, HIGH); // 收到'A'点亮LED }
二、RS-485 通信(长距离抗干扰)
场景:多个Arduino通过RS-485总线通信(工业环境)
所需元件:
元件 | 数量 | 作用 |
---|---|---|
MAX485 模块 | 每设备1个 | TTL转RS-485电平 |
120Ω 终端电阻 | 2个 | 消除总线信号反射 |
双绞线 | 若干 | 连接A/B线 |
接线图:
plaintext
Arduino1 MAX485模块1 双绞线总线 MAX485模块2 Arduino2 TX0 ——— RO RX0 ——— DI │ D2 ——— DE/RE(控制收发) ├— A —————— A —————— A 5V ——— VCC │ GND ——— GND ├— B —————— B —————— B │ ├─── 120Ω电阻(总线两端各1个)
关键跳线设置:
-
DE/RE引脚:短接后通过Arduino的任意GPIO控制(高电平=发送,低电平=接收)
代码逻辑:
cpp
// 所有设备共用此发送函数 void rs485Send(String msg) { digitalWrite(DE_PIN, HIGH); // 进入发送模式 Serial.write(msg.c_str()); Serial.flush(); digitalWrite(DE_PIN, LOW); // 切回接收模式 } // 接收数据(在loop中轮询) if (Serial.available()) { String data = Serial.readString(); // 解析数据... }
三、无线通信(NRF24L01 组网)
场景:3个Arduino通过2.4GHz无线通信
所需元件:
元件 | 数量 | 注意事项 |
---|---|---|
NRF24L01+ 模块 | 每设备1个 | 需3.3V供电 |
10μF 电容 | 每模块1个 | 并联在模块电源脚防干扰 |
接线图:
plaintext
Arduino NRF24L01+ 模块 3.3V ———— VCC GND ———— GND D7 ———— CE (通信使能) D8 ———— CSN (片选) D13 ———— SCK (SPI时钟) D11 ———— MOSI (主机输出) D12 ———— MISO (主机输入) (在VCC-GND间并联10μF电解电容)
网络拓扑示例:
plaintext
[中心节点] (PAN Coordinator) │ ├─── [节点1] (Router) │ └─── [节点2] (End Device)
中心节点代码片段:
cpp
#include <RF24Network.h> RF24 radio(7, 8); // CE=7, CSN=8 RF24Network network(radio); void setup() { radio.begin(); network.begin(90, 00); // 信道90, 中心节点地址00 } void loop() { network.update(); // 接收数据 while (network.available()) { RF24NetworkHeader header; int sensorData; network.read(header, &sensorData, sizeof(sensorData)); } }
四、关键问题解决方案
-
I²C地址冲突:
-
解决方法:使用
PCA9548A
I²C多路复用器(可扩展8路独立I²C总线)
plaintext
-
-
Arduino — I²C — PCA9548A ├— CH0 — 设备1 ├— CH1 — 设备2 └— ...
-
长距离通信干扰:
-
RS-485:双绞线 + 终端电阻 + 屏蔽层接地
-
无线:LoRa模块(SX1276)传输距离可达10km
-
-
实时性保障:
-
硬件方案:改用 CAN 总线(仲裁机制保证高优先级数据优先传输)
-
软件方案:为消息添加优先级字段,接收方按优先级处理
-
调试技巧
-
I²C总线扫描工具:
cpp
-
#include <Wire.h> void setup(){ Wire.begin(); Serial.begin(9600); while (!Serial); Serial.println("\nI2C Scanner"); } void loop(){ byte error, address; for(address=1; address<127; address++){ Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) Serial.printf("设备发现: 0x%02X\n", address); } delay(5000); }
-
RS-485信号测量:
-
用示波器检查A-B线差分电压(典型值:±1.5V~±5V)
-
空闲状态:B线电压 > A线电压
-
重要提醒:所有通信系统必须 共地(GND)!长距离通信建议使用 磁耦隔离模块 (如ADuM1201) 防止地环路损坏设备。