Собрал домашнюю метеостанцию из следующего железа: 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 напрямую. Датчик опрашивается раз в минуту. Показания с него скачут как показанно на скриншоте: Это нормально для такого датчика или же я в чем-то ошибся? Код (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; }
Перемудрил на счет вычисления более точного значения опорного напряжения? Возможно... Думал, что дело в нем. Даже пробовал запитать Arduino только от поверенного лабораторного источника питания. В итоге все тоже самое...
Датчик выдает напряжение, которое измеряется и, с учетом температуры, пересчитывается во влажность по определенной формуле. Чтобы его нормализовать, пользуйтесь или кольцевым фильтром, или фильтром Калмана. Здесь оно есть на форуме.
Нет. Я четко написал, вроде бы. Датчик сразу выдает относительную влажность. Всё. Городить из говна и палок компенсацию на пол-процента погрешности бесполезно. Вы только внесете еще больше погрешности.
Код (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 - уточняйте для своего, после чего сюда.
Провод длинный? Наводка наверное. Попробуйте конденсатор параллельно на десяток uF. Даташит на датчик почитайте, а потом четко пишите. А до этого четко почитайте.