Упражнение: чтение датчиков I²C
В этом упражнении вы научитесь считывать показания датчиков на шине I²C.
На Rust ESP Board есть два датчика, которые можно считывать по шине I²C:
| Периферия | Модель | Документация | Крейт | Адрес |
|---|---|---|---|---|
| IMU | ICM-42670-P | Даташит | Ссылка | 0x68 |
| Температура и влажность | SHTC3 | Даташит | Ссылка | 0x70 |
Задача — использовать готовый драйвер из crates.io, чтобы считать показания датчика температуры и влажности по I²C. После этого второй датчик будет считываться по той же шине I²C с помощью shared-bus.
Часть 1: чтение температуры и влажности
Создайте экземпляр датчика влажности SHTC3 и каждые 600 мс считывайте и выводите значения влажности и температуры.
i2c-sensor-reading/examples/part_1.rs содержит рабочее решение части 1. Чтобы запустить решение части 1:
cargo run --example part_1
i2c-sensor-reading/src/main.rs содержит заготовку кода, в которой уже есть импорты, нужные для этой части.
Шаги:
✅ Перейдите в папку i2c-sensor-reading/ и откройте соответствующую документацию командой:
cargo doc --open
✅ Определите два вывода: один как SDA, другой как SCL.
| Сигнал | GPIO |
|---|---|
| SDA | GPIO10 |
| SCL | GPIO8 |
✅ Создайте экземпляр периферии I²C с помощью сгенерированной документации. Используйте частоту 400 кГц.
✅ Используя крейт драйвера shtcx, создайте экземпляр датчика SHTC3, передав в него экземпляр I²C. За подробностями обращайтесь к документации.
✅ Чтобы проверить, что к датчику обращаются правильно, считайте его идентификатор устройства и выведите значение.
Ожидаемый вывод:
Device ID SHTC3: 71
✅ Выполните измерение, считайте значения датчика и выведите их. Методы датчика описаны в документации.
Ожидаемый вывод:
TEMP: [локальная температура] °C
HUM: [локальная влажность] %
❗ Некоторым датчикам нужно время между измерением и чтением значения. ❗ Следите за единицами измерения!
💡 Есть методы, которые переводят значения датчика в нужные единицы.
Часть 2: чтение данных акселерометра
С помощью менеджера шины реализуйте второй датчик. Считайте его значения и выведите значения обоих датчиков.
Продолжайте со своим решением части 1. Или можно начать с готового частичного решения части 1: i2c-sensor-reading/examples/part_1.rs.
i2c-sensor-reading/examples/part_2.rs содержит рабочее решение части 2. Если нужна помощь, можно посмотреть его, запустив:
cargo run --example part_2
Шаги
✅ Импортируйте крейт драйвера для ICM42670p.
#![allow(unused)]
fn main() {
use icm42670::{Address, Icm42670, PowerMode as imuPowerMode};
}
✅ Создайте экземпляр датчика.
✅ Почему передача одного и того же экземпляра I²C двум датчикам не работает, хотя оба находятся на одной шине I²C?
Ответ
Это вопрос владения. Каждое место в памяти должно кому-то принадлежать. Если мы передадим шину I²C в SHTC3, датчик станет её владельцем, и ею не сможет владеть другой датчик. Заимствовать её тоже нельзя, потому что шина I²C должна быть изменяемой: оба датчика должны иметь возможность её менять. Мы решаем эту проблему, вводя менеджер шины, который создаёт несколько прокси шины I²C. Эти прокси затем могут принадлежать соответствующим датчикам.
✅ Импортируйте крейт менеджера шины.
#![allow(unused)]
fn main() {
use shared_bus::BusManagerSimple;
}
✅ Создайте экземпляр простого менеджера шины. Создайте два прокси и передавайте их датчикам вместо исходного экземпляра I²C.
✅ Считайте и выведите идентификатор устройства с обоих датчиков.
Ожидаемый вывод:
Device ID SHTC3: 71
Device ID ICM42670p: 96
✅ Запустите ICM42670p в режиме низкого шума (low noise mode).
✅ Считайте значения гироскопа и выведите их с двумя знаками после запятой вместе со значениями температуры и влажности.
Ожидаемый вывод:
GYRO: X: 0.00 Y: 0.00 Z: 0:00
TEMP: [локальная температура] °C
HUM: [локальная влажность] %