Можно ли заменить delay на millis() в библиотеке
- Войдите на сайт для отправки комментариев
Вс, 08/12/2019 - 11:41
Привет всем форумчанам!
При использовании единственной доступной в интернете(родной китайской) библиотеки для датчика влажности и прочего AHT10, возникли проблемы с изменением и выведением на LCD1602 требуемой влажности воздуха, изменяемой посредством энкодера, а именно, сильно тупит изменение значений, как с выводом на LCD1602, так и в Serial.print. Но при отключении библиотеки AHT10 все работает отлично. При изучении библиотеки были обнаружены задержки в коде(delay), отсюда возник вопрос: "Можно ли поменять в коде библиотеки delay на millis(), и как это правильно сделать (как в основном коде, или как-то по другому это описывается)?
Заранее спасибо откликнувшимся!!!
Заменить можно.
Правильно это сделать так: проанализировать секретную библиотеку, разработать алгоритм замены, произвести работы по замене, протестировать изменённую функцию.
#include <stdint.h> #include <math.h> #include <Arduino.h> #include <Wire.h> #include "Thinary_AHT10.h" // Specify the constants for water vapor and barometric pressure. #define WATER_VAPOR 17.62f #define BAROMETRIC_PRESSURE 243.5f Sensor_CMD eSensorCalibrateCmd[3] = {0xE1, 0x08, 0x00}; Sensor_CMD eSensorNormalCmd[3] = {0xA8, 0x00, 0x00}; Sensor_CMD eSensorMeasureCmd[3] = {0xAC, 0x33, 0x00}; Sensor_CMD eSensorResetCmd = 0xBA; boolean GetRHumidityCmd = true; boolean GetTempCmd = false; /****************************************************************************** * Global Functions ******************************************************************************/ AHT10Class::AHT10Class() { } boolean AHT10Class::begin(unsigned char _AHT10_address) { AHT10_address = _AHT10_address; Serial.begin(9600); Serial.println("\x54\x68\x69\x6E\x61\x72\x79\x20\x45\x6C\x65\x74\x72\x6F\x6E\x69\x63\x20\x41\x48\x54\x31\x30\x20\x4D\x6F\x64\x75\x6C\x65\x2E"); Wire.begin(AHT10_address); Wire.beginTransmission(AHT10_address); Wire.write(eSensorCalibrateCmd, 3); Wire.endTransmission(); Serial.println("https://thinaryelectronic.aliexpress.com"); delay(500); if((readStatus()&0x68) == 0x08) return true; else { return false; } } /********************************************************** * GetHumidity * Gets the current humidity from the sensor. * * @return float - The relative humidity in %RH **********************************************************/ float AHT10Class::GetHumidity(void) { float value = readSensor(GetRHumidityCmd); if (value == 0) { return 0; // Some unrealistic value } return value * 100 / 1048576; } /********************************************************** * GetTemperature * Gets the current temperature from the sensor. * * @return float - The temperature in Deg C **********************************************************/ float AHT10Class::GetTemperature(void) { float value = readSensor(GetTempCmd); return ((200 * value) / 1048576) - 50; } /********************************************************** * GetDewPoint * Gets the current dew point based on the current humidity and temperature * * @return float - The dew point in Deg C **********************************************************/ float AHT10Class::GetDewPoint(void) { float humidity = GetHumidity(); float temperature = GetTemperature(); // Calculate the intermediate value 'gamma' float gamma = log(humidity / 100) + WATER_VAPOR * temperature / (BAROMETRIC_PRESSURE + temperature); // Calculate dew point in Celsius float dewPoint = BAROMETRIC_PRESSURE * gamma / (WATER_VAPOR - gamma); return dewPoint; } /****************************************************************************** * Private Functions ******************************************************************************/ unsigned long AHT10Class::readSensor(boolean GetDataCmd) { unsigned long result, temp[6]; Wire.beginTransmission(AHT10_address); Wire.write(eSensorMeasureCmd, 3); Wire.endTransmission(); delay(100); Wire.requestFrom(AHT10_address, 6); for(unsigned char i = 0; Wire.available() > 0; i++) { temp[i] = Wire.read(); } if(GetDataCmd) { result = ((temp[1] << 16) | (temp[2] << 8) | temp[3]) >> 4; } else { result = ((temp[3] & 0x0F) << 16) | (temp[4] << 8) | temp[5]; } return result; } unsigned char AHT10Class::readStatus(void) { unsigned char result = 0; Wire.requestFrom(AHT10_address, 1); result = Wire.read(); return result; } void AHT10Class::Reset(void) { Wire.beginTransmission(AHT10_address); Wire.write(eSensorResetCmd); Wire.endTransmission(); delay(20); }Собственно сама библиотека...
Температура и влажность параметры которые быстро невозможно изменить, если конечно зажигалкой не греть датчик. Вызывайте получение данных раз в минуту, а не как сейчас на каждом круге лупа. И перерисовывать температуру и влажность нужно только когда изменились показания датчика. Посмотрите тему блинк без делей. Вместо блинк вызывайте получение данных.
P.S. Посмотрел библиотеку. Делеев при получении данных не нашёл.
unsigned long AHT10Class::readSensor(boolean GetDataCmd) { unsigned long result, temp[6]; Wire.beginTransmission(AHT10_address); Wire.write(eSensorMeasureCmd, 3); Wire.endTransmission(); delay(100); Wire.requestFrom(AHT10_address, 6); for(unsigned char i = 0; Wire.available() > 0; i++) { temp[i] = Wire.read(); }unsigned long AHT10Class::readSensor(boolean GetDataCmd) { unsigned long result, temp[6], timer; if ((millis() -timer) > 100) { Wire.beginTransmission(AHT10_address); Wire.write(eSensorMeasureCmd, 3); Wire.endTransmission(); timer = millis(); } Wire.requestFrom(AHT10_address, 6); for(unsigned char i = 0; Wire.available() > 0; i++) { temp[i] = Wire.read(); }Это будет идентичный вариант для логики библиотеки?
Спасибо за отклик огромное!!!
Перед редактированием библиотек научитесь пастить код по правилам форума.
Спасибо еще раз! Буду искать проблему в своей голове, по итогам профилактических работ отпишусь!)
Negotiator, пожалуйста откройте для себя http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii , я предыдущие Ваши посты поправил, дальше буду неправильно вставленный код удалять.
Обязательно учту! Прошу прощения...
Ваше предложение на замену принципиально неправильно. Тут делей нужен для разделения по времени команд датчику по I2C. В рамках одной функции с однократным вызовом смысла менять делей на миллис нет.
unsigned long AHT10Class::readSensor(boolean GetDataCmd) { unsigned long result, temp[6], timer; if ((millis() -timer) > 100) { Wire.beginTransmission(AHT10_address); Wire.write(eSensorMeasureCmd, 3); Wire.endTransmission(); timer = millis(); } Wire.requestFrom(AHT10_address, 6); for(unsigned char i = 0; Wire.available() > 0; i++) { temp[i] = Wire.read(); }Это будет идентичный вариант для логики библиотеки?
Конечно, нет. Раньше строки №№6-8 однократно вызывались, а теперь Вы им в цикле постоянно долбите.
Вы, прежде, чем спрашивать, хоть бы пробовали, что ли.
Благодарю за помощь. Буду строить логику скетча по-другому.