Метеостанция для записи температуры, атмосферного давления и влажности

Тема в разделе "Arduino & Shields", создана пользователем Lerych, 20 авг 2019.

  1. Lerych

    Lerych Нерд

    Добрый вечер!
    Собрал проект из темы http://wiki.amperka.ru/arduino-projects:weather-station, однако странно себя ведет метеосенсор.
    Выдает такую инфу: Screen_2019.08.19_10h47m03s_001_COM3.png
    Первые две колонки данные от метеосенсора (температура и влажность) никак не вяжутся с реальными данными.
    Использовал библиотеку https://github.com/amperka/TroykaMeteoSensor
    Кто подскажет как привести эти данные в порядок?
    СПАСИБО!
     
  2. NikitOS

    NikitOS Public enemy Администратор

    Hi!
    Собрано из тех же компонентов, что и в статье?
    А если точнее, используется ли модуль подтяжки для DS18B20? Если нет, в схеме есть резистор подтяжки для него?
     
  3. Lerych

    Lerych Нерд

    Собрано точно из тех же компонентов, что и в проекте. Метеосенсор через Troyka Slot Shield v2, Барометр тоже, датчик температуры выносной DS18B20 через модуль подтяжки. Причём барометр и DS18B20 выдаю правильно всё.
     
  4. Lerych

    Lerych Нерд

    В библиотеке от Амперки для Метеосенсора https://github.com/amperka/TroykaMeteoSensor/blob/master/src/TroykaMeteoSensor.cpp есть строки (номер 73-76):
    _temperatureC = ((((data[0] * 256.0) + data[1]) * 175.0) / 65535.0) - 45.0;
    _temperatureF = (_temperatureC * 9.0 / 5.0) + 32.0;
    _temperatureK = _temperatureC + SHT_CELSIUS_TO_KELVIN;
    _humidity = ((((data[3] * 256.0) + data[4]) * 100.0) / 65535.0);
    От куда они эти преобразования взяли не понятно? Думаю дело в них, но что там должно быть?
     
  5. Lerych

    Lerych Нерд

    Вот полный скетч:
    Код (C++):
    // библиотека для работы I²C
    #include <Wire.h>
    // библиотека для работы с метеосенсором
    #include <TroykaMeteoSensor.h>
    // Подключаем библиотеку для работы с дисплеем
    #include <QuadDisplay2.h>
    // библиотека для работы с модулями IMU
    #include <TroykaIMU.h>
    // библиотека для работы с протоколом 1-Wire
    #include <OneWire.h>
    // библиотека для работы с датчиком DS18B20
    #include <DallasTemperature.h>
    // библиотека для работы с SPI
    #include <SPI.h>
    // библиотека для работы с SD-картами
    #include <SD.h>

    // сигнальный пин датчика DS18B20
    #define ONE_WIRE_BUS 5
    // даём разумное имя для CS пина microSD-карты
    #define SD_CS_PIN  8

    // создаём объект для работы с метеосенсором
    TroykaMeteoSensor meteoSensor;//(JUMPER_OFF);
    // создаём объект класса QuadDisplay, передаём номер пина CS, включаем режим работы с SPI
    QuadDisplay qd(10, true);
    // создаём объект для работы с барометром
    Barometer barometer;
    // создаём объект для работы с библиотекой OneWire
    OneWire oneWire(ONE_WIRE_BUS);
    // создадим объект для работы с библиотекой DallasTemperature
    DallasTemperature sensor(&oneWire);

    // перечисляем имена операций, которые мы будем выводить на дисплей
    enum {
      IN,         // имя для операции, которая выводит на дисплей надпись "In"
      TEMP_IN,    // имя для операции, которая выводит на дисплей температуру с метеосенсора
      CEL,        // имя для операции, которая выводит на дисплей символ °C
      HUM_IN,     // имя для операции, которая выводит на дисплей влажность с метеосенсора
      PPM,        // имя для операции, которая выводит на дисплей символ %
      BAR_IN,     // имя для операции, которая выводит на дисплей давление с барометра в миллиметрах ртутного столба
      MER,        // имя для операции, которая выводит на дисплей надпись "Hg"
      EMPTY,      // имя для операции, которая очищает дисплей
      OUT,        // имя для операции, которая выводит на дисплей надпись "Out"
      TEMP_OUT,    // имя для операции, которая выводит на дисплей температуру с датчика DS18B20
      SAVE_SD    // имя для операции, которая записывает на SD данные
    };
    // создаем массив, в котором будем хранить последовательность операций
    int chain[] = {
      IN,
      TEMP_IN,
      CEL,
      HUM_IN,
      PPM,
      BAR_IN,
      MER,
      EMPTY,
      OUT,
      TEMP_OUT,
      CEL,
      EMPTY,
      SAVE_SD
    };

    // создаем объект класса long для хранения счетчика
    unsigned long respite_Time = 0;

    // создаем объект для регулировки времени показа значений на экране
    int slowdown_qd = 1000;
    // создаем объект для хранения номера выполняемой операции
    int number_qd = 0;

    // создаем объект для записи данных на SD строкой
    String  dataString = "";

    void setup() {
      // инициализация дисплея
      qd.begin();
      // инициализируем метеосенсора
      meteoSensor.begin();
      // инициализация барометра
      barometer.begin();
      // инициализируем работу с датчиком DS18B20
      sensor.begin();
      // устанавливаем разрешение датчика от 9 до 12 бит
      sensor.setResolution(12);
      // инициализируем карту памяти
      SD.begin(SD_CS_PIN);
      // инициализируем порт
      Serial.begin(115200);
      // ждём открытия порта
      while(!Serial) {
      }
      // печатаем сообщение об успешной инициализации Serial-порта
      Serial.println("Serial init OK");
      // собираем верхнюю строчку с наименованием данных
      dataString = "TEMP_IN (ºC)\tHUM_IN (%)\tBAR_IN (mmHg)\tTEMP_OUT (ºC)";
      // выводим в порт верхнюю строчку с наименованием данных
      Serial.println(dataString);
      // вызываем функцию сохранения данных на SD
      saveSD(dataString);
    }

    void loop() {
      // запускаем бесконечный счетчик. Его содержимое будет обрабатываться с периодом равным slowdown_qd
      if (millis() - respite_Time > slowdown_qd) {
        // запускаем процесс, который будет выполнять операции согласно последовательности в chain
        switch (chain[number_qd]) {
          case IN:
            qd.displayDigits(QD_I, QD_n, QD_NONE, QD_NONE);
            break;
          case TEMP_IN:
            showData(meteoSensor.getTemperatureC());
            break;
          case CEL:
            qd.displayDigits(QD_NONE, QD_NONE, QD_DEGREE, QD_C);
            break;
          case HUM_IN:
            showData(meteoSensor.getHumidity());
            break;
          case PPM:
            qd.displayDigits(QD_NONE, QD_NONE, QD_DEGREE, QD_UNDER_DEGREE);
            break;
          case BAR_IN:
            qd.displayInt(barometer.readPressureMillimetersHg());
            break;
          case MER:
            qd.displayDigits(QD_NONE, QD_NONE, QD_H, QD_9);
            break;
          case EMPTY:
            qd.displayClear();
            break;
          case OUT:
            qd.displayDigits(QD_O, QD_u, QD_t, QD_NONE);
            break;
          case TEMP_OUT:
            // переменная для хранения температуры
            float temperature;
            // отправляем запрос на измерение температуры
            sensor.requestTemperatures();
            // выводим значение с датчика DS18B20 на экран
            qd.displayFloat(sensor.getTempCByIndex(0), 1);
            break;
          case SAVE_SD:
            // собираем в строку сначала температура с метеосенсора
            dataString = String(meteoSensor.getTemperatureC()) + "\t";
            // потом влажность
            dataString += String(meteoSensor.getHumidity()) + "\t";
            // давление
            dataString += String(barometer.readPressureMillimetersHg()) + "\t";
            // и температура с датчика DS18B20
            dataString += String(sensor.getTempCByIndex(0)) + "\t";
            // вызываем функцию сохранения данных на SD
            //saveSD(dataString);
            Serial.println(dataString);
            break;
        }
        number_qd++;
        // проверяем не превысил ли номер операции количество операций
        if (number_qd > sizeof(chain) / sizeof(int) - 1)
          number_qd = 0;
        respite_Time = millis();
      }
    }

    // функция работы датчика температуры и влажности
    void showData(float data) {
      // считываем данные с датчика
      int stateSensor = meteoSensor.read();
      switch (stateSensor) {
        // выводим показания на дисплей
        case SHT_OK:
          qd.displayFloat(data, 1);
           // выводим показания влажности и температуры
          /*
          Serial.println("Data MeteoSensor is OK");
          Serial.print("Temperature = ");
          Serial.print(meteoSensor.getTemperatureC());
          Serial.println(" C \t");
          Serial.print("Temperature = ");
          Serial.print(meteoSensor.getTemperatureK());
          Serial.println(" K \t");
          Serial.print("Temperature = ");
          Serial.print(meteoSensor.getTemperatureF());
          Serial.println(" F \t");
          Serial.print("Humidity = ");
          Serial.print(meteoSensor.getHumidity());
          Serial.println(" %\r\n");
          */

          break;
        // выводим сообщение "Errd", если ошибка данных или сенсор не подключён
        case SHT_ERROR_DATA:
          qd.displayDigits(QD_E, QD_r, QD_r, QD_d);
          Serial.println("Data error or sensor not connected");
        // выводим сообщение "ErrC", если ошибка контрольной суммы
        case SHT_ERROR_CHECKSUM:
          qd.displayDigits(QD_E, QD_r, QD_r, QD_C);
          Serial.println("Checksum error");
          break;
      }
    }

    // функция сохранения данных на карту памяти
    void saveSD(String data) {
      // создаем файл для записи данных
      File dataFile = SD.open("datalog.txt", FILE_WRITE);
      // если файл существует и открылся
      if (dataFile) {
        // сохраняем данные
        dataFile.println(data);
        // закрываем файл
        dataFile.close();
      } else {
        // если файл не доступен выводим ошибку на дисплей
        qd.displayDigits(QD_E, QD_r, QD_r, QD_S);
      }
    }
     
  6. noevile

    noevile Гик

    если глянуть видео этого проекта, то в конце видео отображаются данные с датчиков. и как-то так получилось, что данные из видео уж очень похожи на те, что получили вы повторяя этот проект. хммм. магия какая-то однако.
     
  7. Lerych

    Lerych Нерд

    Я сперва вообще подумал, что первый столбец это Влажность (в моем случае 60%), я второй столбец Температура (15С), но оказалось всё ещё хуже.
     
  8. noevile

    noevile Гик

    что может быть хуже влажности 60% при температуре 15С ? :)
     
  9. Lerych

    Lerych Нерд

  10. noevile

    noevile Гик

    формулы как формулы. ничего мистического или фантастического. а вот почему вы, прежде чем кричать "шеф всё пропала", не загрузили стандартный скетч с примером для библиотеки метеосенсора вот это действительно фантастика.
     
  11. Lerych

    Lerych Нерд

    От чего же не загрузил, загрузил. Результат такой же:

    Serial init OK
    Meteo Sensor init OK
    Data sensor is OK
    Temperature = 59.01 C
    Temperature = 332.16 K
    Temperature = 138.22 F
    Humidity = 16.09 %
     
  12. noevile

    noevile Гик

    ну тут целых два варианта на ум приходит. или в хате жара такая что аж мозги кипят. или всё-таки имеется ошибка в амперковской библиотеке. :)

    как вариант можно попробовать другую библиотеку, к примеру от адафруита.
     
  13. Lerych

    Lerych Нерд

    Попробовал библиотеку от Адафруита. Результат тот же: температура 59, влажность 16
    К этой же Ардуино подключен герметичный DS18B20 через модуль подтяжки: выдает температуру 20.
    Может цифровой тройка-метео-сенсор сбоить?
     
  14. Lerych

    Lerych Нерд

    В общем, методом тыка, поменял местами метео-сенсор и барометр на Troyka Slot Shield и всё стало в норме.
    Чудеса может кто объяснить?
     
  15. parovoZZ

    parovoZZ Гуру

    чудес в электронике не бывает. Всё объясняется банальными ошибками.
     
    noevile нравится это.
  16. Lerych

    Lerych Нерд

    Вот и хочется понять чья ошибка.
    weatherstation4.png
    Эта картинка весит на всеобщее обозрение на оф.сайте Амперки, люди повторяют проекты, а они глючат.
    Задача выявить и исправить.
     
  17. parovoZZ

    parovoZZ Гуру

    @BAR__MEN, надо техподдержку подтянуть
     
  18. noevile

    noevile Гик

    было бы чего обсуждать. рукожопы были во все времена. в том числе и в амперке таковые имеются.
    вы же методом перебора обнаружили рукожопость амперкиного примера. нууу. если соотнести амперкин пример и полученные ими значения в видео (примерно с 7 минуты 20 секунды где-то внизу видео. они там ещё зажигалкой подпаливают датчик температуры). так что вам прямая дорога в их службу поддержки с гневным письмом покарать наглеца допустившего ошибку и выноса вам благодарности за труды в перестановке модулей на шилде местами. :)
     
  19. NikitOS

    NikitOS Public enemy Администратор

    Понял, принял
     
  20. Lerych

    Lerych Нерд

    Всем спасибо! Тема закрыта.
    Было бы обидно, если бы на кружке с детьми мы этот проект собрали бы, а он не заработал. Хорошо, что проблема решилась.