HTU21 на GY-21 breakout board I2C проблема
Я соединяю датчик HTU21D с моим NodeMCU v3. Все хорошо! Мне удалось получить кое-какие показания и так далее. Но когда я повторно загружаю свой код, устройство не отвечает. Если я выну блок питания из контакта и сброшу его, он снова заработает. У меня точно такая же проблема с использованием библиотеки Sparkfun, так что это скорее аппаратная проблема. У кого-нибудь еще была такая же проблема? ссылка на библиотеку sparkfun https://github.com/sparkfun/SparkFun_HTU21D_Breakout_Arduino_Library для справки, вот мой код
This program interfaces the HTU21 temp/humidity sensor via I2C
*/
#include <Wire.h>
#include <Math.h>
const int HTU21_ADDR = 0x40;
const int Trigger_Temp_Measurement = 0xE3;// hold master
const int Trigger_Hum_Measurement = 0xE5; // hold master
const int Trigger_Temp = 0xF3; //No Hold Master
const int Trigger_Hum = 0xF5; //No Hold Master
int16_t Temp, Hum;//переменные для хранения температуры и влажности
int8_t TmpCrc, HumCrC;
void setup() {// поместите свой установочный код здесь, чтобы запустить один раз:
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(HTU21_ADDR);
Wire.write(0xFE);
Wire.endTransmission(true);
}
void loop() {// поместите свой основной код здесь, чтобы запускать его повторно:
TempReading();
HumReading();
}
void TempReading() {
Wire.beginTransmission(HTU21_ADDR);
Wire.write(Trigger_Temp_Measurement);
Wire.endTransmission();
Wire.requestFrom(HTU21_ADDR, 3, true);
if (Wire.available() <= 3) {
Temp = (Wire.read() << 8) | (Wire.read() );
TmpCrc = Wire.read();
}
float TempCalc = -46.85 + (175.72 * ((float)Temp / (pow(2, 16))));
Serial.print("Temperature \t");
Serial.print(TempCalc);
//Serial.println(TmpCrc, HEX);
}
void HumReading() {
Wire.beginTransmission(HTU21_ADDR);
Wire.write(Trigger_Hum_Measurement);
Wire.endTransmission();
Wire.requestFrom(HTU21_ADDR, 3, true);
if (Wire.available() <= 3) {
Hum = (Wire.read() << 8) | (Wire.read());
HumCrC = Wire.read();
}
float HumCalc = -6 + 125 * (Hum / (pow(2, 16)));
Serial.print("\t Humidity \t");
Serial.println(HumCalc);
//Serial.println(HumCrC, HEX);
}```
@sanrays10, 👍1
Обсуждение1 ответ
Да, установка выполняется полностью. Я обнаружил, что шина зависает, если я прекращаю связь, загружая новый код на плату. Я нашел фрагмент кода, который освобождает шину, которая работает. См. ниже:
#if defined(TWCR) && defined(TWEN)
TWCR &= ~(_BV(TWEN)); //Отключите 2-проводной интерфейс Atmel, чтобы мы могли напрямую управлять контактами SDA и SCL
#endif
pinMode(SDA, INPUT_PULLUP); // Сделайте входы контактов SDA (data) и SCL (clock) с помощью pullup.
pinMode(SCL, INPUT_PULLUP);
boolean SCL_LOW = (digitalRead(SCL) == LOW); // Проверьте, что SCL низкий.
if (SCL_LOW) { //Если он удерживается на низком уровне, Arduno не может стать мастером I2C.
return 1; //Ошибка шины I2C. Не удалось очистить линию часов SCL, удерживаемую на низком уровне
}
boolean SDA_LOW = (digitalRead(SDA) == LOW); // vi. Проверьте вход SDA.
int clockCount = 20; // > 2x9 часов
while (SDA_LOW && (clockCount > 0)) { // vii. Если SDA низкий,
clockCount--;
// Примечание: шина I2C является открытым коллектором, поэтому НЕ приводите SCL или SDA высоко.
pinMode(SCL, INPUT); // отпустите подтягивание SCL так, чтобы при выводе оно было НИЗКИМ
pinMode(SCL, OUTPUT); // затем clock SCL Low
delayMicroseconds(10); // для >5uS
pinMode(SCL, INPUT); // release SCL LOW
pinMode(SCL, INPUT_PULLUP); // снова включите подтягивающие резисторы
// не форсируйте высоко, так как ведомый может удерживать его низко для растягивания часов.
delayMicroseconds(10); // для >5uS
// >5uS предназначен для обработки даже самых медленных устройств I2C.
SCL_LOW = (digitalRead(SCL) == LOW); // Проверьте, является ли SCL низким.
int counter = 20;
while (SCL_LOW && (counter > 0)) { // цикл, ожидающий, пока SCL станет высоким, ждет только 2 секунды.
counter--;
delay(100);
SCL_LOW = (digitalRead(SCL) == LOW);
}
if (SCL_LOW) { // все еще низкий уровень после ошибки 2 сек
return 2; // Ошибка шины I2C. Не мог очистить. Линия часов SCL удерживается низко подчиненными часами stretch for >2sec
}
SDA_LOW = (digitalRead(SDA) == LOW); // и снова проверьте вход SDA и цикл
}
if (SDA_LOW) { // все еще низкий
return 3; // Ошибка шины I2C. Не мог очистить. Линия передачи данных SDA удерживается на низком уровне
}
// else pull SDA line low for Start or Repeated Start
pinMode(SDA, INPUT); // удалить подтягивание.
pinMode(SDA, OUTPUT); // а затем сделайте его НИЗКИМ, т. е. отправьте I2C Start или повторное управление запуском.
// Когда есть только один мастер I2C, запуск или повторный запуск имеет ту же функцию, что и Остановка, и очищает шину.
/// Повторный старт-это Старт, происходящий после Старта без промежуточной Остановки.
delayMicroseconds(10); // wait >5uS
pinMode(SDA, INPUT); // удалить выходной низкий
pinMode(SDA, INPUT_PULLUP); // и сделать SDA высоким, т. е. отправить I2C STOP control.
delayMicroseconds(10); // x. wait >5uS
pinMode(SDA, INPUT); // и сбросить контакты в качестве трехфазных входов, что является состоянием по умолчанию при сбросе
pinMode(SCL, INPUT);
return 0; // все ок
}
Спасибо, что указали мне правильное направление!
- Разница между этими двумя платами NodeMCU?
- NodeMCU с RFID RC522 и LCD-модулем интерфейса I2C вместе
- Проблемы с подключением I2C на ESP8266 — 12F, какие контакты использовать?
- Как подключить MPU9250 к NodeMCU с помощью SPI или I2C Slave?
- Ведомое устройство Arduino с двумя мастерами, использующими одну и ту же шину I2C?
- D1 Mini; есть ли предохранитель?
- Датчик помех I2C (SCL+SDA) и связь MasterSlave
- как увеличить коэффициент задержки DHT11?
Вы также сбрасываете ведомое устройство вместе с NodeMCU? Когда вы нарушаете связь I2C в неподходящее время, ведомое устройство может находиться в плохом состоянии, блокируя шину. Кроме того, вы можете не захотеть спамить I2C и последовательную шину (потому что у вас нет никакой задержки или чего-то подобного в вашем " loop ()")., @chrisl
Ну, если я нажму reset, он пройдет через цикл настройки, который сбросит устройство. Это действительно НЕ сработает, если шина I2C находится в плохом состоянии. Каким может быть решение для сброса шины?, @sanrays10
Действительно ли установка работает полностью? Откуда ты это знаешь? Под сбросом я подразумеваю настоящий жесткий сброс, а не сброс команды. Только жесткий сброс приведет к сбросу шины I2C, @chrisl
Да, установка выполняется полностью. Я обнаружил, что шина зависает, если я прекращаю связь, загружая новый код на плату. Я нашел фрагмент кода, который освобождает шину, которая работает., @sanrays10