我正在尝试通过I2C总线将两个Sparkfun VL6180 TOF传感器连接到Arduino板。我能够分别从两个传感器读取数据,但是如果两个传感器都连接到I2C总线,则无法从两个传感器读取数据。
当两个传感器都连接时,我可以从单个传感器读取该值。当我尝试使用I2C扫描仪查找两个传感器的地址时,只能找到一个传感器的地址,即默认的0x29。我可以单独读取传感器的地址,但是两者都有相同的地址。有人知道如何解决该问题吗?
I2C扫描器代码:
#include <Wire.h>
#include <Arduino.h>
// scans devices from 50 to 800KHz I2C speeds.
// lower than 50 is not possible
// DS3231 RTC works on 800 KHz. TWBR = 2; (?)
long speed[] = {
50, 100, 200, 250, 400, 500, 800
};
const int speeds = sizeof(speed) / sizeof(speed[0]);
// DELAY BETWEEN TESTS
#define RESTORE_LATENCY 5 // for delay between tests of found devices.
bool delayFlag = false;
// MINIMIZE OUTPUT
bool printAll = true;
bool header = true;
// STATE MACHINE
enum states {
STOP, ONCE, CONT, HELP
};
states state = STOP;
uint32_t startScan;
uint32_t stopScan;
void setup() {
Serial.begin(115200);
Wire.begin();
displayHelp();
}
void loop() {
switch (getCommand()) {
case 's':
state = ONCE;
break;
case 'c':
state = CONT;
break;
case 'd':
delayFlag = !delayFlag;
Serial.print(F("<delay="));
Serial.println(delayFlag ? F("5>") : F("0>"));
break;
case 'e':
// eeprom test TODO
break;
case 'h':
header = !header;
Serial.print(F("<header="));
Serial.println(header ? F("yes>") : F("no>"));
break;
case '?':
state = HELP;
break;
case 'p':
printAll = !printAll;
Serial.print(F("<print="));
Serial.println(printAll ? F("all>") : F("found>"));
break;
case 'q':
state = HELP;
break;
default:
break;
}
switch (state) {
case ONCE:
I2Cscan();
state = HELP;
break;
case CONT:
I2Cscan();
delay(1000);
break;
case HELP:
displayHelp();
state = STOP;
break;
case STOP:
break;
default: // ignore all non commands
break;
}
}
char getCommand() {
char c = '\0';
if (Serial.available()) {
c = Serial.read();
}
return c;
}
void displayHelp() {
Serial.println(F("\nArduino I2C Scanner - 0.1.03\n"));
Serial.println(F("\ts = single scan"));
Serial.println(F("\tc = continuous scan - 1 second delay"));
Serial.println(F("\tq = quit continuous scan"));
Serial.println(F("\td = toggle latency delay between successful tests."));
Serial.println(F("\tp = toggle printAll - printFound."));
Serial.println(F("\th = toggle header - noHeader."));
Serial.println(F("\t? = help - this page"));
Serial.println();
}
void I2Cscan() {
startScan = millis();
uint8_t count = 0;
if (header) {
Serial.print(F("TIME\tDEC\tHEX\t"));
for (uint8_t s = 0; s < speeds; s++) {
Serial.print(F("\t"));
Serial.print(speed[s]);
}
Serial.println(F("\t[KHz]"));
for (uint8_t s = 0; s < speeds + 5; s++) {
Serial.print(F("--------"));
}
Serial.println();
}
// TEST
// 0.1.04: tests only address range 8..120
// --------------------------------------------
// Address R/W Bit Description
// 0000 000 0 General call address
// 0000 000 1 START byte
// 0000 001 X CBUS address
// 0000 010 X reserved - different bus format
// 0000 011 X reserved - future purposes
// 0000 1XX X High Speed master code
// 1111 1XX X reserved - future purposes
// 1111 0XX X 10-bit slave addressing
for (uint8_t address = 8; address < 120; address++) {
bool printLine = printAll;
bool found[speeds];
bool fnd = false;
for (uint8_t s = 0; s < speeds ; s++) {
TWBR = (F_CPU / (speed[s] * 1000) - 16) / 2;
Wire.beginTransmission (address);
found[s] = (Wire.endTransmission () == 0);
fnd |= found[s];
// give device 5 millis
if (fnd && delayFlag) delay(RESTORE_LATENCY);
}
if (fnd) count++;
printLine |= fnd;
if (printLine) {
Serial.print(millis());
Serial.print(F("\t"));
Serial.print(address, DEC);
Serial.print(F("\t0x"));
Serial.print(address, HEX);
Serial.print(F("\t"));
for (uint8_t s = 0; s < speeds ; s++) {
Serial.print(F("\t"));
Serial.print(found[s] ? F("V") : F("."));
}
Serial.println();
}
}
stopScan = millis();
if (header) {
Serial.println();
Serial.print(count);
Serial.print(F(" devices found in "));
Serial.print(stopScan - startScan);
Serial.println(F(" milliseconds."));
}
}
从两个传感器读取数据的代码:
#include <Wire.h>
#include <SparkFun_VL6180X.h>
#define VL6180X_ADDRESS1 0x29
#define VL6180X_ADDRESS2 0x30
VL6180xIdentification identification1;
VL6180xIdentification identification2;
VL6180x sensor1(VL6180X_ADDRESS1);
VL6180x sensor2(VL6180X_ADDRESS2);
void setup() {
Serial.begin(115200);
Wire.begin();
delay(100);
sensor1.getIdentification(&identification1); // Retrieve manufacturer info from device memory
printIdentification(&identification1);
sensor2.getIdentification(&identification2); // Retrieve manufacturerinfo from device memory
printIdentification(&identification2);
if (sensor1.VL6180xInit() != 0) {
Serial.println("S1FAILED TO INITALIZE");
};
if (sensor2.VL6180xInit() != 0) {
Serial.println("S2FAILED TO INITALIZE");
};
sensor1.VL6180xDefautSettings();
sensor2.VL6180xDefautSettings();//Load default settings to get started.
delay(1000); // delay 1s
}
void loop() {
Serial.print(" S1 :Distance measured (mm) = ");
Serial.println( sensor1.getDistance() );
Serial.print(" S2 :Distance measured (mm) = ");
Serial.println( sensor2.getDistance() );
delay(500);
};
void printIdentification(struct VL6180xIdentification *temp) {
Serial.print("Model ID = ");
Serial.println(temp->idModel);
Serial.print("Model Rev = ");
Serial.print(temp->idModelRevMajor);
Serial.print(".");
Serial.println(temp->idModelRevMinor);
Serial.print("Module Rev = ");
Serial.print(temp->idModuleRevMajor);
Serial.print(".");
Serial.println(temp->idModuleRevMinor);
Serial.print("Manufacture Date = ");
Serial.print((temp->idDate >> 3) & 0x001F);
Serial.print("/");
Serial.print((temp->idDate >> 8) & 0x000F);
Serial.print("/1");
Serial.print((temp->idDate >> 12) & 0x000F);
Serial.print(" Phase: ");
Serial.println(temp->idDate & 0x0007);
Serial.print("Manufacture Time (s)= ");
Serial.println(temp->idTime * 2);
Serial.println();
Serial.println();
}
答案 0 :(得分:0)
如果传感器具有相同的I2C地址,并且无法配置该地址,则可能会出现问题,因为无法同时读取这两个地址。
首先研究配置I2C地址的可能性。许多I2C设备都有此选项。
如果这不可用,您可以做的就是将传感器的Vcc引脚连接到Arduino的数字引脚。当您要从传感器读取数据时,可以通过将另一个传感器的Vcc数字引脚设置为LOW来关闭另一个传感器,并通过将其Vcc数字引脚设置为HIGH来打开要读取的传感器。
但是,根据传感器的类型,您可能必须等待直到传感器准备就绪。某些传感器在打开时会花费一些时间才能提供准确的读数。