Можно ли заменить delay на millis() в библиотеке

Negotiator
Offline
Зарегистрирован: 08.12.2019

Привет всем форумчанам!

При использовании единственной доступной в интернете(родной китайской) библиотеки для датчика влажности и прочего AHT10, возникли проблемы с изменением и выведением на LCD1602 требуемой влажности воздуха, изменяемой посредством энкодера, а именно, сильно тупит изменение значений, как с выводом на LCD1602, так и в Serial.print. Но при отключении библиотеки AHT10 все работает отлично. При изучении библиотеки были обнаружены задержки в коде(delay), отсюда возник вопрос: "Можно ли поменять в коде библиотеки delay  на millis(),  и как это правильно сделать (как в основном коде, или как-то по другому это описывается)?

Заранее спасибо откликнувшимся!!! 

sadman41
Offline
Зарегистрирован: 19.10.2016

Заменить можно. 

Правильно это сделать так: проанализировать секретную библиотеку, разработать алгоритм замены, произвести работы по замене, протестировать изменённую функцию. 

Negotiator
Offline
Зарегистрирован: 08.12.2019
#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);
}

 

 

Negotiator
Offline
Зарегистрирован: 08.12.2019

Собственно сама библиотека...

 

nik182
Offline
Зарегистрирован: 04.05.2015

Температура и влажность параметры которые быстро невозможно изменить, если конечно зажигалкой не греть датчик. Вызывайте получение данных раз в минуту, а не как сейчас на каждом круге лупа. И перерисовывать температуру и влажность нужно только когда изменились показания датчика. Посмотрите тему блинк без делей. Вместо блинк вызывайте получение данных. 

P.S. Посмотрел библиотеку. Делеев при получении данных не нашёл.

Negotiator
Offline
Зарегистрирован: 08.12.2019
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();
    }   

 

 

Это будет идентичный вариант для логики библиотеки? 

Спасибо за отклик огромное!!!

 

 

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Перед редактированием библиотек научитесь пастить код по правилам форума.

Negotiator
Offline
Зарегистрирован: 08.12.2019

Спасибо еще раз! Буду искать проблему в своей голове, по итогам профилактических работ отпишусь!)

 

Araris
Offline
Зарегистрирован: 09.11.2012

Negotiator, пожалуйста откройте для себя http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii , я предыдущие Ваши  посты поправил, дальше буду неправильно вставленный код удалять.

Negotiator
Offline
Зарегистрирован: 08.12.2019

Обязательно учту! Прошу прощения...

nik182
Offline
Зарегистрирован: 04.05.2015

Ваше предложение на замену принципиально неправильно. Тут делей нужен для разделения по времени команд датчику по I2C. В рамках одной функции с однократным вызовом смысла менять делей на миллис нет. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Negotiator пишет:
Если поменяю на это:

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 однократно вызывались, а теперь Вы им в цикле постоянно долбите.

Вы, прежде, чем спрашивать, хоть бы пробовали, что ли.

Negotiator
Offline
Зарегистрирован: 08.12.2019

Благодарю за помощь. Буду строить логику скетча по-другому.