Чтение из люкса висит при ярком свете
Я использую датчики VMEL6040, и иногда при ярком свете чтение может висеть, вместо того, чтобы использовать wdt для восстановления, я хотел бы задать некоторые вопросы о библиотеке.
что касается отладки датчиков, они работают стабли (несколько дней при считывании каждые 250 мс) в условиях низкой освещенности, но более 6k люкс они могут разбиться.
Я использую проволоку.к здесь
в заголовке
TwoWire *_i2cPort;
значение read вызывает функцию ReadRegister:
uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
{
uint16_t _regValue;
_i2cPort->beginTransmission(_address);
_i2cPort->write(_reg); // Moves pointer to register.
_i2cPort->endTransmission(false); // 'False' here sends a restart message so that bus is not released
_i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
_regValue = _i2cPort->read(); // LSB
_regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
return(_regValue);
}
есть ли причина, по которой они не проверяют возврат _i2cPort->endTransmission(false);>
call? Мне интересно, должен ли я проверить это и не вызывать requestFrom
, если это так, т. Е.:
uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
{
uint16_t _regValue;
_i2cPort->beginTransmission(_address);
_i2cPort->write(_reg); // Moves pointer to register.
if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released
_i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
_regValue = _i2cPort->read(); // LSB
_regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
return(_regValue);
}
else
return 0;
}
Или моя ошибка может быть от статического кастинга do int?
@levi Clouser, 👍0
Обсуждение1 ответ
Лучший ответ:
итак, я думаю, что понял, проблема заключалась в том, что на fail wire.read() возвращает int -1 , когда он преобразуется в unint16-это большое число, а затем оно сдвигается влево и переполняется
решение было таково:
uint16_t SparkFun_Ambient_Light::_readRegisterLight(uint8_t _reg)
{
int lsb;
int msb;
_i2cPort->beginTransmission(_address);
_i2cPort->write(_reg); // Moves pointer to register.
if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released
unsigned long tstamp = millis();
while ((_i2cPort->available() < 2) && ((millis() - tstamp) < 10));
if ((_i2cPort->available() < 2)) {
_i2cPort->requestFrom(_address, 2); // Two reads for 16 bit registers
lsb = _i2cPort->read(); // LSB
msb = _i2cPort->read(); //MSB
if ((lsb >= 0) && (lsb <= 256) && (msb >= 0) && (msb <= 256)) {
_regValue = lsb + msb * 256;
}
}
return(_regValue);
}
else
return _regValue;//last read
}
Это содержит некоторую дополнительную обработку ошибок, которую я добавил, но оставит, например:
- время ожидания ответа
- проверка правильности закрытия шины в конечной передаче
- проверка ошибок при чтении
Я не занимался обработкой ошибок, так как мне нужно было бы переписать всю библиотеку, и для моего приложения достаточно повторить последнее чтение.
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Как отправить строку на мастер с помощью i2c
- Как выбрать альтернативные контакты I2C на ESP32?
- Что означает в I2C «NACK получен»?
- NodeMCU с RFID RC522 и LCD-модулем интерфейса I2C вместе
- Несколько датчиков I2C с одинаковым адресом
Я думал, что "static_cast" - это просто приведение во время компиляции; Я не вижу, как приведение " 2 " к байту вызовет ошибку, если это то, что ожидает вызов (а это IIRC)., @Dave Newton
1) ' static_cast<uint8_t>(2)
не является необходимым, если вы читаете [Wire](https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/Wire/src/Wire.cpp#L169-L186) источник, вы увидите несколько функций перегрузки для обработки приведения типа. 2) чтобы привести
uint8_t1 кuint16_t
, это(uint16_t) _i2cPort->read()
, а не uint16_t(_i2cPort->>read() . 3) не должно лиuint16_t _regValue;
быть объявлено на уровне вашего класса? теперь ваш код объявил его как локальную переменную, и вы возвращаете значение локальной переменной, которое может больше не существовать (вне области действия), когда программа возвращается из функции., @hcheung@hcheung: Возврат _address_ локальной переменной будет ошибкой. Вернуть его _value_-это совершенно нормально., @Edgar Bonet
полную библиотеку, которую я использую, можно найти здесь: https://github.com/sparkfun/SparkFun_Ambient_Light_Sensor_Arduino_Library, @levi Clouser
Я думаю, что только что понял это _i2cPort->read(); возвращает -1 при ошибке duh, @levi Clouser