Связь I2C с ICM-20789

i2c pressure

Я пытаюсь подключиться к ICM-20789 через I2C. Технические данные

Мне удалось получить все три показания гироскопа и все три показания акселерометра. Сейчас я пытаюсь получить показания давления с устройства, так как оно имеет встроенный датчик давления, но не могу заставить его работать.

В техническом описании указано включить режим обхода.

Режим обхода: установите регистр INT_PIN_CFG (адрес: 55 (десятичный); 37 (шестнадцатеричный)) бит 1 на значение 1 и бит I2C_MST_EN на «0» (Адрес: 106 (десятичный); 6A (шестнадцатеричный). Доступ к данным датчика давления можно получить с помощью процедуры, описанной в разделе 10

В настройке я использую этот код:

  Wire.beginTransmission(gyro_address);                                  
  Wire.write(0x37);      //INT_PIN_CFG                                                    
  Wire.write(0x02);      //00000010                                                    
  Wire.endTransmission(); 

У меня также возникли проблемы с поиском I2C_MST_EN в таблице данных, так как я не могу найти его в адресе 6A.

После того как бит обхода включен, я пытаюсь запросить данные о давлении и температуре с датчика, используя этот код:

Wire.beginTransmission(0x63);      
Wire.write(0x7866);     
Wire.endTransmission();
Wire.requestFrom(0x63, 16);

while (Wire.available() < 16);
pressure = Wire.read() << 16 | Wire.read() << 8 | Wire.read();
temp_2   = Wire.read() << 16 | Wire.read() << 8 | Wire.read();

К сожалению, устройство зависает, когда я пытаюсь запустить этот код. Я знаю, что явно делаю что-то не так, просто пока не знаю, что именно.

, 👍0

Обсуждение

Wire.write(0x7866); урежет ваше значение до 0x66. Вы можете «записывать» только 8 бит за раз., @Majenko


1 ответ


Лучший ответ:

1

В вашем коде есть четыре ошибки.

  1. Вы неправильно отправляете команду "начать измерение". Функция Wire.write() может отправлять только 8 бит, но вы передаете ей 16-битное значение. Вместо этого вы должны разбить его на 2 отдельных 8-битных значения:

    Wire.beginTransmission(0x63);
    Wire.write(0x78);
    Wire.write(0x66);
    Wire.endTransmission();

  2. Возвращенные данные распределяются по 9 байтам, а не по 16. Согласно техническому описанию:

Данные о температуре передаются двумя 8-битными словами, а данные о давлении передается четырьмя 8-битными словами.

и:

За двумя байтами данных всегда следует один байт контрольной суммы CRC

Это 2 + 4 = 6 + (6/2) = 9

  1. Вы не ждете завершения преобразования. Согласно техническому описанию, в режиме «сверхмалого шума» (0x7866) для выполнения измерения требуется до 94,5 мс. Поэтому вам следует добавить немного большую задержку, чтобы позволить ему делать то, что нужно.

  2. Команда, которую вы отправляете, сначала отвечает температурой, а не давлением, но вы сначала читаете давление (и все равно читаете неправильные байты).

В целом ваш код должен выглядеть примерно так:

Wire.beginTransmission(0x63);      
Wire.write(0x78);     
Wire.write(0x66);     
Wire.endTransmission();

delay(100);

Wire.requestFrom(0x63, 9);
uint8_t tmsb = Wire.read(); // старший байт температуры
uint8_t tlsb = Wire.read(); // Младший байт температуры
Wire.read();

uint8_t pmmsb = Wire.read(); // Самый высокий байт давления
uint8_t pmlsb = Wire.read(); // Следующий старший байт давления
Wire.read(); // Отбросить контрольную сумму
uint8_t plmsb = Wire.read(); // Следующий младший байт давления
uint8_t pllsb = Wire.read(); // Самый низкий байт давления
Wire.read(); // Отбросить контрольную сумму

pressure = (pmmsb << 24) | (pmlsb << 16) | (plmsb << 8) | pllsb;
temp_2   = (tmsb << 8) | (plsb << 8);
,

Спасибо Маженко! Это имеет больше смысла. Я добавил этот код в свой цикл. Мой код все еще зависает. Это происходит, когда я добавляю этот код в настройку для входа в режим обхода: Wire.beginTransmission(0x63); Wire.write(0x78); Wire.write(0x66); Wire.endTransmission();, @M.Schindler

Это не код для входа в режим байпаса, это код для запуска преобразования давления., @Majenko

Прошу прощения, я скопировал неправильный код. Когда у меня есть эти строки кода в моей установке, код зависает. Wire.beginTransmission(gyro_address); Wire.write(0x37); //INT_PIN_CFG Wire.write(0x02); //00000010 Wire.endTransmission();, @M.Schindler