Arduino I2C设备地址扫描和主从通讯实验例程
📌主要是用于扫描挂载在外部的I2C设备地址。
- 🔖Arduino UNO板,I2C0引脚:A4(SDA),A5(SCL)
📝示例程序
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(115200);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);//从指定的地址开始向I2C从设备进行传输
error = Wire.endTransmission();//停止与从机的数据传输
/*
* error返回结果:
* 0: 成功
1: 数据量超过传送缓存容纳限制
2: 传送地址时收到 NACK
3: 传送数据时收到 NACK
4: 其它错误
*/
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
- 🌿串口打印扫描到的I2C地址
📍这里扫描到的
AT24C02
的I2C
地址是0X50
。
📝扫描程序二
#include "Wire.h"
extern "C" {
#include "utility/twi.h" // from Wire library, so we can do bus scanning
}
// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
void(*callback)(byte address, byte result) )
{
byte rc;
byte data = 0; // not used, just an address to feed to twi_writeTo()
for( byte addr = from_addr; addr <= to_addr; addr++ ) {
rc = twi_writeTo(addr, &data, 0, 1, 0);
callback( addr, rc );
}
}
// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
Serial.print("addr: ");
Serial.print(addr,DEC);
Serial.print( (result==0) ? " found!":" ");
Serial.print( (addr%4) ? "\t":"\n");
}
byte start_address = 8; // lower addresses are reserved to prevent conflicts with other protocols
byte end_address = 119; // higher addresses unlock other modes, like 10-bit addressing
// standard Arduino setup()
void setup()
{
Wire.begin();
Serial.begin(9600); // Changed from 19200 to 9600 which seems to be default for Arduino serial monitor
Serial.println("\nI2CScanner ready!");
Serial.print("starting scanning of I2C bus from ");
Serial.print(start_address,DEC);
Serial.print(" to ");
Serial.print(end_address,DEC);
Serial.println("...");
// start the scan, will call "scanFunc()" on result from each address
scanI2CBus( start_address, end_address, scanFunc );
Serial.println("\ndone");
// Set pin mode so the loop code works ( Not required for the functionality)
pinMode(13, OUTPUT);
}
// standard Arduino loop()
void loop()
{
// Nothing to do here, so we'll just blink the built-in LED
digitalWrite(13,HIGH);
delay(300);
digitalWrite(13,LOW);
delay(300);
}
- 🌿串口监视器打印扫描I2C地址信息
📗主发从收通讯实验例程
- 🌿Slave Receiver从设备接收
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(8); // join I2C bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
- 🌿主设备发送数据端
// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(); // join I2C bus (address optional for master)
}
byte x = 0;
void loop() {
Wire.beginTransmission(8); // transmit to device #8
Wire.write("x is "); // sends five bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting
x++;
delay(500);
}
📗主收从发通讯实验例程
- 主设备接收端
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(); // join I2C bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(8, 6); // request 6 bytes from slave device #8
while (Wire.available()) { // slave may send less than requested
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
- 从设备发送数据端
// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(8); // join I2C bus with address #8
Wire.onRequest(requestEvent); // register event
}
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write("hello "); // respond with message of 6 bytes
// as expected by master
}