Скачут показания с датчика влажности Honeywell HIH-4000

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Nit99, 8 дек 2017.

  1. Nit99

    Nit99 Нуб

    Собрал домашнюю метеостанцию из следующего железа:
    Arduino Uno R3 (оригинал)
    Датчик влажности Honeywell HIH-4000-001 https://sensing.honeywell.com/index.php?ci_id=49922
    Ну и термистор B57164-K 103-J http://files.amperka.ru/datasheets/B57164.pdf для коррекции показаний влажности

    Датчик влажности подключен к Arduino напрямую. Датчик опрашивается раз в минуту. Показания с него скачут как показанно на скриншоте:
    [​IMG]
    [​IMG]
    Это нормально для такого датчика или же я в чем-то ошибся?

    Код (C++):
    #include <math.h>
    #include <LiquidCrystal.h>
    int minute = 1;

    #define TERMIST_B 4300 // B value determined by resistance measurement at 25 °C and 100 °C (from datasheet: http://files.amperka.ru/datasheets/B57164.pdf)

    LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

    byte degreeChar[8] = {
      0b01100,
      0b10010,
      0b10010,
      0b01100,
      0b00000,
      0b00000,
      0b00000,
      0b00000
    };

    void setup() {
      Serial.begin(9600);
      Serial.println("Minute\tHumidity (%)\tTemperature (°C)");
      lcd.createChar(0, degreeChar);
      lcd.begin(16,2);
    }

    void loop() {
      float voltsOnSensorInput = realVcc();
      float voltsOnA1 = analogRead(A1) * voltsOnSensorInput / 1023.0;
      float r1 = voltsOnA1 / (voltsOnSensorInput - voltsOnA1);
      float temperature = 1.0 / (1.0 / TERMIST_B * log(r1) + 1.0 / (25.0 + 273.0)) - 273.0;

      voltsOnSensorInput = realVcc();
      float voltsOnA0 = analogRead(A0) * voltsOnSensorInput / 1023.0;
      float humidity = ((voltsOnA0 / voltsOnSensorInput - 0.16) / 0.0062) / (1.0546 - 0.00216 * temperature);

      Serial.print(minute);
      Serial.print("\t");
      Serial.print(humidity);
      Serial.print("\t\t");
      Serial.println(temperature);

      lcd.setCursor(0, 0);
      lcd.print("Hum: ");
      lcd.print(humidity, 0);
      lcd.print(" %RH");
      lcd.setCursor(0, 1);
      lcd.print("Temp: ");
      lcd.print(temperature, 1);
      lcd.print(" ");
      lcd.write(byte(0));
      lcd.print("C");

      delay(60000);
      ++minute;
    }

    float realVcc() {
      // https://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
      #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
         ADMUX = _BV(MUX5) | _BV(MUX0) ;
      #else
        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      #endif

      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA, ADSC)); // measuring

      uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
      uint8_t high = ADCH; // unlocks both

      float result = (high<<8) | low;

      result = (1.1 * 1023.0) / result; // Real Vcc in volts
      return result;
    }
     
    Последнее редактирование: 8 дек 2017
  2. rkit

    rkit Гуру

    Что-то вы перемудрили очень и очень. Датчик сразу выдает относительную влажность.
     
  3. Nit99

    Nit99 Нуб

    Перемудрил на счет вычисления более точного значения опорного напряжения?
    Возможно... Думал, что дело в нем. Даже пробовал запитать Arduino только от поверенного лабораторного источника питания. В итоге все тоже самое...
     
  4. ИгорьК

    ИгорьК Гуру

    Датчик выдает напряжение, которое измеряется и, с учетом температуры, пересчитывается во влажность по определенной формуле.
    Чтобы его нормализовать, пользуйтесь или кольцевым фильтром, или фильтром Калмана. Здесь оно есть на форуме.
     
  5. ИгорьК

    ИгорьК Гуру

    Эм... Тут Вы меня научили читать по слогам, за что великий поклон... :
    upload_2017-12-8_14-24-52.png
     
  6. rkit

    rkit Гуру

    Нет. Я четко написал, вроде бы. Датчик сразу выдает относительную влажность. Всё.
    Городить из говна и палок компенсацию на пол-процента погрешности бесполезно. Вы только внесете еще больше погрешности.
     
  7. ИгорьК

    ИгорьК Гуру

    Код (Javascript):
     var GetHue = function (pin, temp) {
            // Accordiong HIH-5030 datasheet:
            var RH =  (analogRead(pin) - 0.1515)/ 0.00636;
            var TrueRH = (RH)/(1.0546 - 0.00216 * temp);
            console.log("Hum is " + TrueRH.toFixed(1)+" %");
            return parseFloat(TrueRH.toFixed(1));
        };
    Это HIH-5030 - уточняйте для своего, после чего сюда.
     
  8. Onkel

    Onkel Гуру

    Провод длинный? Наводка наверное. Попробуйте конденсатор параллельно на десяток uF.

    Даташит на датчик почитайте, а потом четко пишите. А до этого четко почитайте.