Вопрос или проблема
Я пытаюсь подключиться к датчику влажности и температуры HS3000, используя I2C с Mbed OS на Arduino Nano 33 BLE Sense. Однако я постоянно сталкиваюсь с проблемами связи по I2C при попытке прочитать регистр “Who Am I”. Мой код постоянно выводит:
Ошибка записи I2C на ‘Who Am I’!
Ошибка чтения I2C на ‘Who Am I’!
Получено от датчика: 0x97 0x01
Я считаю, что проблема заключается в связи по I2C, но не знаю, что делать дальше. Я проверил проводку и соединения, но, возможно, упускаю что-то из виду.
Это часть большого лабораторного проекта, и я пытался сократить все детали и код, чтобы соответствовать требованиям stack overflow, но если вы считаете, что необходимо предоставить лабораторную инструкцию и мой полный код, дайте знать, и я прикреплю оба.
#include "mbed.h"
#include "USBSerial.h"
#include "I2C.h"
// Определение регистров GPIO, отображенных в памяти, для управления светодиодами
#define DIRSET (uint32_t*) 0x50000514 // Установить направление GPIO (Вход/Выход)
#define OUTSET (uint32_t*) 0x50000508 // Установить пин LED (включить)
#define OUTCLR (uint32_t*) 0x5000050c // Очистить пин LED (выключить)
#define HUMIDITY_FLAG (1UL << 0)
#define TEMPERATURE_FLAG (1UL << 1)
//Ticker ticker;
EventFlags event_flags;
USBSerial serial;
void set_i2c_pullup(){
*DIRSET |= (1 << 0);
*OUTSET |= (1 << 0);
}
void ISR(){
static bool toggle = true;
if (toggle){
event_flags.set(HUMIDITY_FLAG);
}
else{
event_flags.set(TEMPERATURE_FLAG);
}
toggle = !toggle;
}
Mutex print_mutex;
I2C i2c(I2C_SDA1, I2C_SCL1);
const int HS3000_ADDR = 0x44 << 1; // 0x44 сдвинут для 7-битного адреса I2C
int main(void){
set_i2c_pullup();
char who_am_i_addr[] = {0x1E}; // Регистру для чтения ID
char who_am_i_data[2];
if (i2c.write(HS3000_ADDR, who_am_i_addr, 1) != 0) {
serial.printf("Ошибка записи I2C на 'Who Am I'!\r\n");
}
ThisThread::sleep_for(200ms);
if (i2c.read(HS3000_ADDR, who_am_i_data, 2) != 0) {
serial.printf("Ошибка чтения I2C на 'Who Am I'!\r\n");
}
serial.printf("Получено от датчика: 0x%02X 0x%02X\r\n", who_am_i_data[0], who_am_i_data[1]);
//ticker.attach(&ISR, 1s);
while(true){
// Главный цикл
}
}
Настройка:
Плата: Arduino Nano 33 BLE Sense
Датчик: датчик влажности и температуры HS3000
Информация из технического описания, которую я нашел полезной:
“Датчик серии HS3xxx работает как устройство-ведомое на шине I2C с поддержкой скоростей передачи 100kHz и 400kHz” (стр. 10)
“Стандартный адрес I2C для серии HS3xxx — 44HEX. Устройство будет отвечать только на этот 7-битный адрес.” (стр. 10)
Таблица 2. Регистры энергонезависимой памяти (стр. 14)
Адрес Описание регистра
0x06 Разрешение датчика влажности – читать регистр (биты 11:10).
0x46 Разрешение датчика влажности – записать регистр (биты 11:10).
0x11 Разрешение датчика температуры – читать регистр (биты 11:10).
0x51 Разрешение датчика температуры – записать регистр (биты 11:10).
0x1E Читать ID датчика – верхние 2 байта.
0x1F Читать ID датчика – нижние 2 байта.
Проблемы:
Обратите внимание, что нет ошибок компиляции.
Ошибка записи I2C: возникает при попытке записать в регистр “Who Am I” (0x1E).
Ошибка чтения I2C: возникает при попытке прочитать ответ датчика.
Ожидаемое поведение:
Я ожидаю, что смогу прочитать ID датчика из регистра “Who Am I”, чтобы убедиться, что связь с датчиком работает.
Фактическое поведение:
Вместо этого я получаю ошибки записи и чтения I2C, а датчик выдает 0x97 0x01 при чтении ID, что не соответствует ожидаемым значениям.
Вопросы:
Может ли это быть связано с адресом I2C или конфигурацией связи с датчиком?
Есть ли дополнительные шаги, которые я должен предпринять для устранения неполадок связи I2C с HS3000?
Ответ или решение
Проблемы с I2C-связью с датчиком HS3000 в Mbed OS: Ошибки при записи и чтении
Проблема, с которой вы столкнулись при установлении I2C-соединения с датчиком влажности и температуры HS3000, требует тщательного анализа вашей конфигурации и кода. Давайте рассмотрим основные аспекты, которые могут вызвать ошибки при записи и чтении регистров.
1. Проверка адреса I2C
Вы указали, что для HS3000 адрес равен 0x44 в 7-битном формате, что является правильным значением. Однако вы записываете этот адрес в переменную HS3000_ADDR
с учетом смещения для 8-битного адреса:
const int HS3000_ADDR = 0x44 << 1; // 0x44 для 7-битного адреса
В данном случае, вы должны проверить, правильно ли выставлен адрес. В наилучшей практике стоит использовать 0x44 непосредственно как 7-битный адресе, поэтому следует убрать сдвиг:
const int HS3000_ADDR = 0x44; // Используйте 7-битный адрес напрямую
2. Проверьте подключение и вывод
Убедитесь, что ваш датчик подключен корректно:
- SDA подключен к соответствующему выводу на Arduino Nano 33 BLE Sense.
- SCL подключен тоже правильно.
- Проверьте соединения на предмет плохих контактов или обрывов проводов.
Если вы используете внешние подтягивающие резисторы, убедитесь, что они правильно подключены, или отключите встроенные подтягивающие резисторы, если они имеются.
3. Ожидание перед чтением
После записи в регистр необходимо обеспечить достаточную задержку, чтобы датчик успел обработать запрос. В вашем коде вы уже используете ThisThread::sleep_for(200ms);
, что является хорошей практикой, но если это не помогло, попробуйте увеличить время ожидания до 500 мс или даже 1 секунды.
4. Последовательность операций
Ваши операции записи и чтения должны учитывать, что некоторые устройства I2C могут требовать определения начального состояния слоя (start condition). Убедитесь, что перед вызовом read()
вы корректно записываете адрес устройства.
5. Ошибки I2C
Вы упомянули, что получаете сообщения об ошибках при записи и чтении. Для более детального понимания попробуйте добавить дополнительную отладочную информацию:
if (i2c.write(HS3000_ADDR, who_am_i_addr, 1) != 0) {
serial.printf("I2C write error on 'Who Am I'! Error Code: %d\r\n", i2c.get_last_error());
}
Эта информация может дать более четкое понимание, почему происходит сбой.
6. Проверка на неправильный ответ
Ваш код считывает два байта после записи в регистр 0x1E. Однако, если датчик не отвечает, это может означать, что он недоступен или конфигурация неверна. Ваша функция чтения должна проверять смещение и ожидать ответа в соответствии с документацией.
Заключение
Следуя вышеописанным рекомендациям, вы сможете диагностировать и, возможно, устранить ошибки связи с датчиком HS3000 через I2C. Начните с проверки адреса устройства, затем проверьте подключения и последовательность операций. Как только вы получите успешный ответ от датчика, вы сможете продолжить дальнейшую работу с проектом. Если же все предпринятые меры не дадут результата, рассмотрите возможность использования логического анализатора для наблюдения за линиями I2C. Это может помочь выявить истинную природу проблемы, будь то сбой на уровне данных или неверная интерпретация сигналов.