Как соединить два устройства через i2c?

Я работаю с 2 Pololu Altimu-10 V6, подключенными к одной и той же плате ESP32. Оба они подключены по протоколу i2c и имеют разные адреса. Адреса — 0x1C и 0x1E.

У меня есть этот код для калибровки магнитометра одного из них. Как мне изменить его, чтобы измерять оба?

Я не знаю, как указать адрес каждого из них.

#include <Wire.h>
#include <LIS3MDL.h>

LIS3MDL mag;
LIS3MDL::vector<int16_t> running_min = {32767, 32767, 32767}, running_max = {-32768, -32768, -32768};

char report[80];

void setup() {
  Serial.begin(9600);
  Wire.begin();

  if (!mag.init()) {
    Serial.println("Failed to detect and initialize magnetometer!");
    while (1);
  }

  mag.enableDefault();
}

void loop() {
  mag.read();

  running_min.x = min(running_min.x, mag.m.x);
  running_min.y = min(running_min.y, mag.m.y);
  running_min.z = min(running_min.z, mag.m.z);

  running_max.x = max(running_max.x, mag.m.x);
  running_max.y = max(running_max.y, mag.m.y);
  running_max.z = max(running_max.z, mag.m.z);

  snprintf(report, sizeof(report), "min: {%+6d, %+6d, %+6d}   max: {%+6d, %+6d, %+6d}",
    running_min.x, running_min.y, running_min.z,
    running_max.x, running_max.y, running_max.z);
  Serial.println(report);

  delay(100);
}

, 👍0


1 ответ


0

Я полагаю, вы используете эту библиотеку от pololu. В файле Readme в разделе «Справочник по библиотеке» вы можете найти следующую запись:

`bool init(deviceType device, sa0State sa0) Инициализирует библиотеку с используемым устройством (device_LIS3MDL или device_auto) и состоянием вывода SA1 (sa1_low, sa1_high или sa1_auto), который определяет второй по значимости бит адреса подчиненного устройства I²C. Константы для этих аргументов определены в LIS3MDL.h. Оба эти аргумента являются необязательными; если они не указаны, библиотека попытается автоматически определить адрес устройства. Возвращается логическое значение, указывающее, был ли успешно определен тип устройства (если необходимо).

Я интерпретирую это следующим образом: вы можете создать 2 объекта LIS3MDL следующим образом:

LIS3MDL mag1;
LIS3MDL mag2;

Затем в setup() вы инициализируете их оба, но указываете необязательные параметры функции init:

if(!mag1.init(LIS3MDL::device_LIS3MDL, LIS3MDL::sa1_low)){
  Serial.println("Failed to detect and initialize magnetometer 1!");
  while (1);
}
if(!mag2.init(LIS3MDL::device_LIS3MDL, LIS3MDL::sa1_high)){
  Serial.println("Failed to detect and initialize magnetometer 2!");
  while (1);
}

Первый параметр — это тип устройства. Вероятно, он также будет работать со значением LIS3MDL::device_auto, хотя просто его установка делает его более явным. Второй параметр представляет состояние адресного контакта (SA1) на соответствующем модуле. В приведенном выше коде модуль, у которого контакт SA1 находится в состоянии LOW, будет mag1; модуль с контактом SA1 в состоянии HIGH будет mag2. Обратите внимание, что вам, конечно, нужно фактически подключить контакты SA1 модулей к заземлению/Vcc соответственно, чтобы это работало.

Затем все, что вы ранее делали только с одним объектом LIS3MDL, вы можете делать с каждым из этих двух объектов LIS3MDL последовательно.

,

Я попробовал, но получил следующую ошибку: «device_LIS3MDL» не был объявлен в этой области., @sonlas10

@hcheung Если я использую mag1.init(0x1C), у меня возникает эта ошибка: ошибка: недопустимое преобразование из 'int' в 'LIS3MDL::deviceType'. Также я пробовал в двоичном формате (как в документации) mag1.init(0b0011110) , и ошибка была той же., @sonlas10

@sonlas10 Извините, не видел, как именно это определяется. На самом деле это перечисление внутри класса. В документации об этом не упоминается. Я мог бы скомпилировать, добавив LIS3MDL:: перед именами device_LIS3MDL и sa1_high/sa1_low. Это говорит компилятору, что это член класса LIS3MDL, @chrisl

@sonlas10, мои извинения, я перечитал исходный код более подробно, я был неправ. Может быть, вам стоит подумать о том, чтобы поднять [проблему](https://github.com/pololu/lis3mdl-arduino/issues) в библиотеке GitHub., @hcheung