Интерференция I2C устройств
В настоящее время я пытаюсь подключить 3 устройства I2C к Arduino Mega, как описано в скетче fritzing. Это датчики: Датчик Max86150 PPG на пробивной плате (5 В), ИК-датчик температуры MLX90614 (3,3 В) и Датчик давления SM9336(3,3 В). По сути, я могу подключить все устройства и считывать датчики с помощью отдельных скетчей, но когда я объединяю скетчи, значения не совпадают, а затем скетч выходит из строя всего через несколько секунд.
Как ни странно, когда я объединяю скетч либо с датчиком температуры и датчиком давления, либо с датчиком температуры и датчиком PPG, он будет работать. Но Давление и PPG не работают вместе.
Кто-нибудь знает, что могло случиться? У меня он работал некоторое время с некоторыми другими проводами, может ли это иметь какое-то отношение к этому? Но даже при этом некоторые результаты, которые я считывал с датчика, были значениями ошибок (например, значение, которое вы получаете, когда ничего не подключено, но это не сбой). Для справки я использую провода 30 AWG и полосовую плату вместо макета во фриттинге.
//PPG
#include "max86150.h"
MAX86150 max86150Sensor;
uint16_t ppgunsigned16;
uint16_t irdata;
// Pressure Sensor
#include <Wire.h>
#define PressureSensor_Data 0x30 // Pressure Register address
#define TemperatureSensor_Data 0x2E // Pressure Temp Sensor Address
int P0,T0,P1,T1;
int SMD993Address = 0x6C; // Device Address
//Timing
#define INTERVAL 10 //10 milliseconds per sample for 100 Hz, change this for different sampling rates.
uint32_t lastMicros = 0;
// Temp
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
void ppgsetup()
{
max86150Sensor.setup();
}
void PPG() {
while (1){
if(max86150Sensor.check()>0)
{
ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);
Serial.println(ppgunsigned16);
//ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);
//Serial.println(ppgunsigned16);
if (ppgunsigned16 > 7000){
for (int z = 0; z <= 500; z++){//This takes a reading every 10 milliseconds for 5000 milli seconds which is 5 seconds, 500 readings
digitalWrite(ledPin,HIGH);//turning LED on
//if (micros() - lastMicros > INTERVAL) { //This takes a reading every 100th of a second
//lastMicros = micros(); // do this first or your interval is too long!
if(max86150Sensor.check()>0)
{
ppgunsigned16 = (uint16_t) (max86150Sensor.getFIFORed()>>2);
irdata = (uint16_t) (max86150Sensor.getFIFOIR()>>2);
Serial.print(ppgunsigned16);
Serial.print(",");
Serial.println(irdata);
//Serial.print("Check PPG");Serial.println(y);
//mySerial.write(84);mySerial.print(ppgunsigned16);mySerial.print("/");
//mySerial.write(83);mySerial.print(irdata);mySerial.print("/");
}
}
digitalWrite(ledPin,LOW);//turning LED off
break;
}
}
}
}
void spirometry() {
for (int x = 0; x <= 500; x++){
Wire.beginTransmission(SMD993Address);
Wire.write(PressureSensor_Data);
Wire.write(TemperatureSensor_Data);
Wire.endTransmission();
Wire.requestFrom(SMD993Address,2);//This takes a reading every 100 milliseconds for 10000 milli seconds which is 10 seconds
//if (micros() - lastMicros > INTERVAL) { //This takes a reading every 1000th of a second
//lastMicros = micros(); // do this first or your interval is too long!
if(Wire.available()<= 2) {
P0 = Wire.read();
P1 = Wire.read();
}
int Ptotal = P0 + (P1<<8); //The high byte is transmitted second so that
Serial.println(Ptotal); // Print Ptotal to the serial monitor
//mySerial.write(81);mySerial.print(Ptotal);mySerial.print("/");// Send PTotal over BLE with flag 81, this will change as sending via bytes is more efficient
}
}
void temperature() {
for (int y = 0; y <= 10; y++){
mlx.begin();
Serial.println(mlx.readObjectTempC());
mySerial.write(82);mySerial.print(mlx.readObjectTempC());mySerial.print("/");
delay(10);
}
}
void setup() {
// BT
mySerial.begin(9600);
Serial.begin(9600);//Sets BT Serial Comms to 115200, ensure that BT is allowing for this
//LED
pinMode(ledPin, OUTPUT);
// PPG
// Initialize sensor
if (max86150Sensor.begin(Wire, I2C_SPEED_FAST) == false)
{
Serial.println("MAX86150 was not found. Please check wiring/power. ");
while (1);
}
Serial.println(max86150Sensor.readPartID());
ppgsetup();
//Pressure Sensor
//Temp
//Sleep
sleep();
}
void loop()
{
// put your main code here, to run repeatedly
PPG();
delay(10000);
spirometry();
delay(1000);
temperature();
}
@Tee Gallagher, 👍1
Обсуждение2 ответа
Некоторое время назад у меня была похожая проблема, когда я подключил к Raspberry Pi 2 платы сервопривода и батарейную шляпу (которая использовала I2C для считывания уровней мощности). Батарейная плата работала одна, и сервоплата работала одна, но когда присутствовали все три, батарейная плата перестала работать. И все они имели уникальные адреса. После нескольких часов безумия я понял, что на ПИ есть подтягивающие резисторы и все три платы подключены. Общее сопротивление всех 4 параллельных подтягивающих резисторов не соответствовало спецификации для I2C. Я снял резисторы с сервоплат, и все начало работать вместе. Так что, может быть, вы могли бы отключить подтягивания на всех баордах, кроме Ардуино, и посмотреть, есть ли в этом проблема.
Спасибо за ответ, похоже, что я неосознанно установил интерфейс провода I2C на высокую скорость и что это было по существу сбой датчика давления и скетча, насколько я могу судить в любом случае., @Tee Gallagher
@TeeGallagher, я проголосовал за это, потому что это был хороший ответ в любом случае. Если у вас есть некоторая уверенность в том, что ваша высокая скорость была проблемой, вы должны сделать отдельный ответ и позже принять его., @timemage
Как указал @peterpaulkeifer; Здесь
// Инициализация датчика
if (max86150Sensor.begin(Wire, I2C_SPEED_FAST) == false)
{
Serial.println("MAX86150 не найден. Пожалуйста, проверьте проводку/питание".);
while (1);
}
Я устанавливал скорость I2C интерфейсной шины I2C на быструю, и мне показалось, что датчик давления не смог справиться с этим и поэтому давал ответы об ошибках, а затем выходил из строя.
- Лазерный датчик ToF (VL53L0X) не работает
- Могу ли я соединить вместе несколько плат Arduino Nano ?
- Параллельная связь между несколькими Ардуино
- Multiple Wire.write() не работает для Arduino Nano I2C
- Как использовать I2C от Arduino Uno, когда у меня установлен GSM-shield?
- Главный считыватель/ведомый передатчик с датчиком расстояния
- Отправка 4 аналоговых значений от одного arduino к другому с помощью I2C
- Увеличение скорости датчиков Vl6180x
Вы пробовали добавлять подтягивающие резисторы к линиям? По мере того как вы подключаете к шине все больше устройств, емкость увеличивается. Подтягивания (возможно, 4,7 Ком, которые я в основном использую для I2C) могут помочь в этом. И еще: Какой длины ваши провода? I2C предназначен для довольно коротких соединений в однозначной области cm. Длинные провода могут сделать его ненадежным., @chrisl
Возможно, не стоит полностью спамить шину своими сообщениями (например, вы очень быстро снимаете показания в " спирометрии ()`). Пожалуйста, попробуйте ввести небольшую задержку или что-то подобное там. И почему вы вызываете "mlx.begin ()" 11 раз для чтения температуры? Не будет ли достаточно одного начала в настройке?, @chrisl
@chrisl Я запускал устройства I2C по кабелю 10 м, только с случайными ошибками чтения, так что это вряд ли проблема здесь. Являются ли адреса устройств уникальными?, @PMF
@chrisl AFAIK есть внутренние резисторы pullup в Arduino, но я дам им попробовать и посмотреть, работает ли он лучше. Кабели, вероятно, 10 см максимум, большинство из них будет в одном диапазоне см. Я пробовал играть с задержками, но это, кажется, ничего не меняет, я пытаюсь достичь частоты дискретизации 100 Гц, которая, как я прочитал, должна быть достижима на Arduino Mega. Mlx.begin() находится в неправильном месте, хорошее место, которое я перемещу., @Tee Gallagher
@PMF Да, все адреса уникальны, какой калибр провода вы используете для 10 м?, @Tee Gallagher
@TeeGallagher Это был кабель для передачи данных 8x 0.25mm2. Я использовал 2 провода для заземления, 1x 5V, 1x 3.3 V, 2x для I2C. Пульт имеет 4x20LCD, датчик температуры, расширитель GPIO с несколькими кнопками и светодиодами. Основная проблема на самом деле заключается в том, что 3,3 В не очень стабильны на дальней стороне., @PMF
Вы запускаете провод в высокоскоростном режиме для ppg. Вы не установили это обратно, когда выполняли доступ к проводу для давления. Может ли датчик давления работать в высокоскоростном режиме? Ваш код тихонько нечитаем для меня, так что, возможно, я что-то подслушал., @Peter Paul Kiefer
@PeterPaulKiefer Похоже, это могло бы сработать, мне пришлось заменить провод, потому что он сломался, но это, похоже, решило проблему. Так здорово, спасибо, я вытащил эту строку кода из примера и подумал, что она принадлежит библиотеке. Так мне и надо., @Tee Gallagher