Фиксация min. и max. уличной температуры за сутки

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Уважаемые форумчане, прошу помощи в написание части скетча для домашней метеостанции. Задача состоит в том чтобы фиксировать с последующем отображением на lcd дисплее минимальную и максимальную, дневную и ночную уличную температуру. 

Просмотор форума и поиск в интернете пока не дал результатов. Только начал осваивать ардуино и пока самому трудно понять с чего начинать. Для своей метеостанции использую ардуино про мини,  датчик температуры  и влажности DHT 22 , датчик давления BMP085.

Дисплей lcd 20x4, также модуль часов DS1307. Так же есть задача отбражения тренда повышения и понижения атмосферного давления.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Надо кроме переменной "текущая температура" ввести еще две переменных: "минимальная температура" и "максимальная температура". После этого при каждом измерении сравниваем измеренное термометром значение с минимумом и максимумом. Если текущая температура выше максимума - то обновляем максимум присвоением ему текущего значения, с минимумом - поступаем соответственно.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Andrey_Y_  спасибо за совет. Я в программировании полный ноль, если можно напишите примерно часть кода как это реализовать. Со всем не давно начал осваивать язык ардуино и еще далек до самостоятельного написания программ. Пока пытаюсь брать уже готовые скетчи или часть из них.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
#include "DHT.h"
#define DHTPIN 2 
#define DHTTYPE DHT22   

DHT dht(DHTPIN, DHTTYPE);

float currentHumi = 0; 
float currentTemp = 0;
float maxTemp = 0;
float minTemp = 0;

void setup() { 
  Serial.begin(9600); 
  Serial.println("DHTxx test!");

  dht.begin(); 
}

void loop() {

  float currentHumi = dht.readHumidity(); 
  float currentTemp = dht.readTemperature();

  if (isnan(t) || isnan(h)) { 
    Serial.println("Failed to read from DHT"); 
  } 
  else { 
    if (currentTemp > maxTemp) maxTemp = currentTemp;
    if (currentTemp < minTemp) minTemp = currentTemp;
    Serial.print("Humidity: "); Serial.print(currentHumi); Serial.print(" %\t"); 
    Serial.print("Temperature: ");  Serial.print(currentTemp);  Serial.print(" *C\t"); 
    Serial.print("Max: "); Serial.print(maxTemp); Serial.print(" *C\t"); 
    Serial.print("Min: "); Serial.print(minTemp); Serial.println(" *C"); 
  } 
}

Но это будет абсолютный минимум и максимум (за все время измерений).

А для расчета за сутки, надо определиться что под этим понимается: сутки с 00 до 23, или сутки - это текущее время и предыдущие 23:59 часа?

Соответственно, надо либо раз в сутки сбрасывать максимум и минимум, либо каждый час смещать показания назад.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Tomasina.

Благодарю за комментарий! Буду пробывать использовать Ваш пример кода. 

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

Tomasina пишет:

#include "DHT.h"
#define DHTPIN 2 
#define DHTTYPE DHT22   

DHT dht(DHTPIN, DHTTYPE);

float currentHumi = 0; 
float currentTemp = 0;
float maxTemp = 0;
float minTemp = 0;

void setup() { 
  Serial.begin(9600); 
  Serial.println("DHTxx test!");

  dht.begin(); 
}

void loop() {

  float currentHumi = dht.readHumidity(); 
  float currentTemp = dht.readTemperature();

  if (isnan(t) || isnan(h)) { 
    Serial.println("Failed to read from DHT"); 
  } 
  else { 
    if (currentTemp > maxTemp) maxTemp = currentTemp;
    if (currentTemp < minTemp) minTemp = currentTemp;
    Serial.print("Humidity: "); Serial.print(currentHumi); Serial.print(" %\t"); 
    Serial.print("Temperature: ");  Serial.print(currentTemp);  Serial.print(" *C\t"); 
    Serial.print("Max: "); Serial.print(maxTemp); Serial.print(" *C\t"); 
    Serial.print("Min: "); Serial.print(minTemp); Serial.println(" *C"); 
  } 
}

Но это будет абсолютный минимум и максимум (за все время измерений).

А для расчета за сутки, надо определиться что под этим понимается: сутки с 00 до 23, или сутки - это текущее время и предыдущие 23:59 часа?

Соответственно, надо либо раз в сутки сбрасывать максимум и минимум, либо каждый час смещать показания назад.

Не могли бы вы набросать такой же код для датчика DS18b20 ? очень бы хотелось иметь данную фичу у себя в акваконтроллере

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Сейчас запостить код сложно - пишу с телефона.
Подключаете библиотеки Wire и DallasTemperature, открываете комплектные к ним примеры чтения с датчиков и добавляет к коду строки 28-33 из вышеприведенного кода. Собственно, тот пример для DHT22 и есть родной от библиотеки, с этим дополнением.

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

я сейчас сам на работе, так что мне не кспеху :) если не сложно то как будет время чикрните сюда его, а я вечером тоже попробую сам

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

При компилировании  ошибка, что не объявлены переменные t и h.

Добавил  2 строки:

void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
float currentHumi = dht.readHumidity();
float currentTemp = dht.readTemperature();

if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT");
}

Загрузил в UNO max.t фиксирует, min.t  одни нули.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Tomasina спасибо за помощь, подскажите как решить проблему с мин.T и значения сохранять в память.

 

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Для датчика DS18b20 есть вот такой скетч:

// include the library code:
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#if defined(ARDUINO) && ARDUINO > 18
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDHCP.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 30
#define TEMPERATURE_PRECISION 9

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define MAX_DS1820_SENSORS 5

char displayBuf[200];

signed int TempPrev[MAX_DS1820_SENSORS];
char deltaT[MAX_DS1820_SENSORS]; // positive delta t 0 = warm, 1 cold

long scanTempInterval = 1000 * 25;        // Интервал замера температуры при больше 25 - не опрашиваются датчики во второй раз
long printInterval = 1000 * 60;           // Интервал обновления экрана при больше 25 - не опрашиваются датчики во второй раз

long previousScanTempMillis = 0;     // Предидущее время замера температуры
long previousPrintMillis = 0;        // Предидущее время обновления экрана

unsigned char sensorCount = 0;
char buf[40];
char bufSerial[20];
char bufFloat[40];

unsigned char screenSizeX=20;
unsigned char screenSizeY=4;

char ledScanTime = 13;
char ledAlarm    = 40;

bool isRestart = true;
bool isRepaint = false;

// Just a utility function to nicely format an IP address.
const char* ip_to_str(const uint8_t* ipAddr)
{
    static char buf[16];
    sprintf(buf, "%d.%d.%d.%d\0", ipAddr[0], ipAddr[1], ipAddr[2], ipAddr[3]);
    return buf;
}

struct sensorData
{
    DeviceAddress addr;     // Адрес датчика
    char name[20];          // Имя для отображения
    bool        trackMin;   // Отслеживать мин. температуру
    bool        trackMax;   // Отслеживать макс. температуру
    signed char minLimit;   // Минимальный лимит температуры
    signed char maxLimit;   // Максимальный лимит
    signed char minTemp;    // Минимальное значение температуры
    signed char maxTemp;    // Максимальное значение температуры
    signed char temp;       // Текущее значение температуры
};

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xdE, 0xED };
byte server[] = { 192,168,0,103 }; // ya.ru
byte ip[] = { 192,168,0,100 };
//byte server[] = { 77,88,21,3 }; // ya.ru

const int printRoundSize = 5;
int printRound[printRoundSize] = {0,3,4};

OneWire oneWire(ONE_WIRE_BUS);  // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);    // Pass our oneWire reference to Dallas Temperature.
DeviceAddress insideThermometer, outsideThermometer;    // arrays to hold device addresses
sensorData sensorsParams[MAX_DS1820_SENSORS] = {
                                                0x28, 0x45, 0xAF, 0xC7, 0x02, 0x0, 0x0, 0x2C,"Out", false, false, 0, 0, 0, 0, 0,//remote
                                                0x28, 0x93, 0xBB, 0xC7, 0x02, 0x00, 0x00, 0x39, "rename me", false, true, 0, 30, 0, 0, 0,
                                                0x28, 0xB0, 0xDB, 0xC7, 0x02, 0x00, 0x00, 0xC7, "Test", false, true, 18, 30, 0, 0, 0,//out
                                                0x28, 0x9B, 0xC5, 0xC7, 0x02, 0x00, 0x00, 0x57, "Ter cold", true, true, 22, 35, 0, 0, 0,
                                                0x28, 0xEE, 0xD6, 0xC7, 0x02, 0x00, 0x00, 0x16, "Ter warm", true, true, 22, 35, 0, 0, 0,
//                                              0x28, 0xFA, 0xDF, 0xC7, 0x02, 0x00, 0x00, 0x62, "Stepan", false, false, 22, 39, 0, 0, 0
                                              };

void roundRotate()
{
    int mem = printRound[0];
    for(int i=0; i < printRoundSize-1; i++)
    {
        printRound[i]=printRound[i+1];
    }
    printRound[printRoundSize-1] = mem;
}

void setup()
{
    pinMode(10, OUTPUT);
    pinMode(4, OUTPUT);
    digitalWrite(10, HIGH);
    digitalWrite(4, HIGH);

    delay(200);
    Serial.begin(9600);
        
    sprintf(displayBuf, "Attempting to obtain a DHCP lease...");
    Serial.println(displayBuf);
    
    EthernetDHCP.begin(mac);
//    Ethernet.begin(mac, ip);    
    const byte* ipAddr = EthernetDHCP.ipAddress();

    sprintf(displayBuf, "A DHCP lease has been obtained.");
    Serial.println(displayBuf);
//    lcd.print(displayBuf);

    sprintf(displayBuf, "My IP address is  %s", ip_to_str(ipAddr));
    Serial.println(displayBuf);

    lcd.clear();
    sensors.begin();
    oneWire.reset_search();
    for(int i=0; i < MAX_DS1820_SENSORS; i++)
    {
        if(oneWire.search(sensorsParams[i].addr))
        {
            sensors.setResolution(sensorsParams[i].addr, TEMPERATURE_PRECISION);
            sensorCount++;
        }
        else
        {
            break;
        }
    }

    pinMode(ledScanTime, OUTPUT);
    pinMode(ledAlarm, OUTPUT);
    lcd.begin(screenSizeX, screenSizeY);
    lcd.setCursor(0,0);
    sprintf(buf, "Found %d sensors", sensorCount);
    Serial.println(buf);
    lcd.print(buf);
    delay(500);
    lcd.clear();
    if(sensorCount==0)
    {
        return;
    }

  digitalWrite(4, HIGH);
}

bool sendToServer(char* aUrl, char* aParams)
{
          digitalWrite(4, HIGH);
    char buf[2048];
    Client client(server, 80);

    if(client.connect())
    {
        Serial.println("connected");
//        client.println("GET /gettime.php HTTP/1.0");

        sprintf(buf, "GET %s%s HTTP/1.0", aUrl, aParams);
//	sprintf(buf, "GET /class/backend/meteo.php?temp=%0d.%d&code=123456 HTTP/1.0", (int)f, abs(temp1));
//        Serial.println(buf);
        client.println(buf);
//        client.print(aData);
        //    client.println("GET / HTTP/1.1");
        //    client.println("GET /test.php");
        //    sprintf(buf, "GET /class/backend/meteo.php?temp=%0d.%d&code=123456 HTTP/1.0", (int)f, abs(temp1));
        client.println();
//        client.println();
    }
    else
    {
        // kf you didn't get a connection to the server:
        Serial.println("connection failed");
    }
    /*    if (!client.connected())
    {
      Serial.println();
      Serial.println("disconnecting.");
        client.stop();
    }*/

    delay(100); // Что бы сервер успел сгенерить ответ
    char data[2048];
    int i = 0;
    int dataSize = client.available();
    Serial.print("dataSize: ");
    Serial.println(dataSize);
    while(i < dataSize)
    {
        data[i] = client.read();
        i++;
    }
    data[i]=0;
  char szKey[] = "HTTP/1.1 200 OK";
  if(strncmp (szKey,data, 15)==0)
  {
     Serial.println("OK!");
  }
else{
    sprintf(displayBuf, data);
    Serial.println(displayBuf);
}
    client.stop();
}



// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
    for (uint8_t i = 0; i < 8; i++)
    {
        // zero pad the address if necessary
        if (deviceAddress[i] < 16) Serial.print("0");
        Serial.print(deviceAddress[i], HEX);
    }
}

void getSensorData()
{
    byte present = 0;
    digitalWrite(ledScanTime, HIGH);
    sensors.requestTemperatures();
    bool isAlarm = false;
    for(int i=0; i<sensorCount; i++)
    {
        int sensor = printRound[i];
        sensorsParams[sensor].temp = sensors.getTempC(sensorsParams[sensor].addr);

        if(TempPrev[sensor] > sensorsParams[sensor].temp)
        {
            deltaT[sensor] = 1;
        }
        else if(TempPrev[sensor] < sensorsParams[sensor].temp)
        {
            deltaT[sensor] = 0;
        }
        else
        {
            deltaT[sensor] = 2;
        }
        if(sensorsParams[sensor].temp < sensorsParams[sensor].minTemp || isRestart)
        {
            sensorsParams[sensor].minTemp = sensorsParams[sensor].temp;

        }
        else if(sensorsParams[sensor].temp > sensorsParams[sensor].maxTemp || isRestart)
        {
            sensorsParams[sensor].maxTemp = sensorsParams[sensor].temp;

        }
            if(sensorsParams[sensor].trackMin && (sensorsParams[sensor].minLimit > sensorsParams[sensor].temp))
            {
                isAlarm = true;
            }

            if(sensorsParams[sensor].trackMax && (sensorsParams[sensor].maxLimit < sensorsParams[sensor].temp))
            {
                isAlarm = true;
            }

        TempPrev[sensor] = sensorsParams[sensor].temp;
    }

          if(isAlarm)
          {
              digitalWrite(ledAlarm, HIGH);
          }
          else
          {
              digitalWrite(ledAlarm, LOW);
          }

    digitalWrite(ledScanTime, LOW);
    isRepaint = true;
}

char* getName(DeviceAddress deviceAddress)
{
    bool isFound = false;
    uint8_t foundId = 0;

    for(uint8_t i = 0; i < sizeof(sensorsParams); i++)
    {
        if(compareAddres(sensorsParams[i].addr, deviceAddress))
        {
            isFound = true;
            foundId = i;
        }
    }
    if(isFound)
    {
        return (sensorsParams[foundId].name);
    }
    else
    {
        return "Unknow sensor";
    }
}

bool compareAddres(DeviceAddress deviceAddress, DeviceAddress deviceAddress2)
{
    int count = 0;
    for (uint8_t i = 0; i < 8; i++)
    {
        // zero pad the address if necessary
        if (deviceAddress[i] == deviceAddress2[i])
            count ++;
    }
    return count==8;
}


void sendTemp()
{
    char url[50] = "/test.php\0";
    char params[50] = "?sensor_id=2&temperatura=23\0";
    sendToServer(url, params);
}


void printTemp()
{
    int startSensor = 0;
    int sensorPrintCount = min(sensorCount, screenSizeY - 1);
    const int n = 0;
    for(int lineNum=startSensor; lineNum < sensorPrintCount; lineNum++)
//    for(int lineNum=startSensor; lineNum < sensorPrintCount; lineNum++)
    {

        int sensor = printRound[lineNum];
        
        char url[50] = "/test.php\0";
//        char params[50] = "?sensor_id=2&temperatura=23\0";

        dtostrf(sensorsParams[sensor].temp, 2, n, bufFloat);
        
        sprintf(displayBuf, "?sensor_id=%i&temperatura=%i\0", sensor, sensorsParams[sensor].temp);
        
        Serial.println(getName(sensorsParams[sensor].addr));
                
        Serial.println(displayBuf);
        sendToServer(url, displayBuf);        
//        int sensor = lineNum;
        lcd.setCursor(0,lineNum);
        if(sensorsParams[sensor].trackMin && (sensorsParams[sensor].minLimit > sensorsParams[sensor].temp))
        {
            lcd.print("!Min");
        }
        if(sensorsParams[sensor].trackMax && (sensorsParams[sensor].maxLimit < sensorsParams[sensor].temp))
        {
            lcd.print("!Max");
        }
        lcd.print(getName(sensorsParams[sensor].addr));

        lcd.setCursor(11, lineNum);
        lcd.print(sensorsParams[sensor].minTemp);
        lcd.print("/");
        lcd.print(sensorsParams[sensor].maxTemp);

        dtostrf(sensorsParams[sensor].temp, 2, n, bufFloat);
        lcd.setCursor(screenSizeX - strlen(bufFloat)-1, lineNum);

        if(deltaT[sensor] == 0)
        {
            lcd.print(217, BYTE); // up
        }
        else if(deltaT[sensor] == 1)
        {
            lcd.print(218, BYTE); // down
        }
        else
        {
            lcd.print(239, BYTE); //round
        }
        lcd.print(bufFloat);
        //        sprintf(buf, "%d:%d Min:%d Max:%d", sensor+1, sensorsParams[sensor].temp, sensorsParams[sensor].minTemp, sensorsParams[sensor].maxTemp);

    }

    isRepaint = false;
    roundRotate();
}

void printTime()
{
    unsigned long Seconds = millis()/1000;
    const unsigned long  SecondsInDay = 60 * 60 * 24;
    int day = Seconds / SecondsInDay;
    // Отбрасываем дни
    Seconds %= SecondsInDay;
    int hours = Seconds / 3600;
    // Отбрасываем часы
    Seconds %= 3600;
    // Вычисляем и выводим количество минут
    int mins = Seconds / 60;
    // Вычисляем и выводим количество секунд
    Seconds = Seconds % 60;
    lcd.setCursor(0, screenSizeY - 1);
    sprintf(buf, "%02d %02d:%02d:%02d", day, hours, mins, Seconds);
    lcd.print(buf);
}

void loop(void)
{
    unsigned long currentMillis = millis();
    if(isRestart)
    {
        getSensorData();
        if(isRepaint)
        {
            printTemp();
        }
        isRestart = false;
    }
    if(currentMillis - previousScanTempMillis > scanTempInterval)
    {
        previousScanTempMillis = currentMillis;
        getSensorData();
    }
    if(currentMillis - previousPrintMillis > printInterval /*|| isRepaint*/)
    {
        lcd.clear();
        previousPrintMillis = currentMillis;
        printTemp();
        printTime();
    }
}

Пробывал убрать из него все что связано Ethernet, оставить только вывод данных на lcd. Не полчилось.

Что может:

Искать подключенные датчики при старте
Опрашивать датчики через нужный интервал времени
Для каждого датчика запоминаеть максимальное и минимальное значения.
Для каждого датчика запоминаеть превыдущее значение. Если оно было выше, рисуется стрелка "вниз", если наоборот: "вверх", иначе отображается "круг".

Нашел здесь: https://github.com/elagin/Arduino-terarium

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

http://electronics-lab.ru/blog/mcu/46.html

DHT11:

Частота опроса не более 1 Гц (не более раза в 1 сек.)

 

DHT22:

Частота опроса не более 0.5 Гц (не более раза в 2 сек.)

 

.....нужно учитывать, что если скорость обращения будет высокая  вместо данных Вы будете получать CRC Error...

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

Благодарю, то что нужно, обязательно попробую прикрутить к своему

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Разобрался почему не фиксировалась minT, пробывал измерять при комнатной тепературе, при первоначальных установках значений минТ = 0. Установил отрицательное значение,  стало отображаться и фиксироваться.

Вот пример:



#include <LiquidCrystal.h>
#include "DHT.h"
#define DHTPIN A0 
#define DHTTYPE DHT22   

DHT dht(DHTPIN, DHTTYPE);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

float maxTemp = -30; \\ максимальные и минимальные значения тепературы 
float minTemp = 30;

void setup() { 
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
    
  lcd.begin(20, 4); 
  dht.begin(); 
}

void loop() {
  float h = dht.readHumidity(); 
  float t = dht.readTemperature();
  float currentTemp = dht.readTemperature();
     
  if (isnan(t) || isnan(h)) { 
    Serial.println("Failed to read from DHT"); 
  } 
  else { 
    
    if (currentTemp < minTemp) minTemp = currentTemp;
    if (currentTemp > maxTemp) maxTemp = currentTemp;
     
    Serial.print("Temperature: ");  Serial.print(currentTemp);  Serial.print(" *C\t"); 
    Serial.print("Max: "); Serial.print(maxTemp); Serial.print(" *C\t"); 
    Serial.print("Min: "); Serial.print(minTemp); Serial.println(" *C"); 
      
    
  lcd.setCursor(0,0); 
  lcd.print("T:"); lcd.print(t,0);lcd.print((char)223); lcd.print("C ");
  lcd.print("H:"); lcd.print(h,0); lcd.print("%");
  lcd.setCursor(0,2);
  lcd.print("MaxT "); lcd.print(maxTemp,0);lcd.print((char)223); lcd.print("C ");
  lcd.print("MinT "); lcd.print(minTemp,0);lcd.print((char)223); lcd.print("C");
    
   delay (2000);
  } 
}

Дальше буду пыаться , сделать чтоб значения соранялись в память и сбрасывались, определеный период времени. Думаю что, по такому же принципу можно показания  давления и влажности фиксировать.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

у тебя одна и та же температура читается дважды (строки 23-24).

в строках 22 и 26 замени t и h на currentTemp и currentHumi 

а строку 23 удали.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Спасибо за подсказку, придеться и строку 40,41 пеписать.

Redmaer
Offline
Зарегистрирован: 30.07.2015

Я на основе этого сделал следующим образом:

/*
 * SDA - A4
 * SDL - A5
 */
 


#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"                                // Объявление переменной класса dht11
#define DHTPIN 2                                // Датчик DHT11 подключен к цифровому пину номер 2

#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

  float maxTemp = -30;                         // максимальные и минимальные значения тепературы
  float minTemp = 30;
  float maxHumi = 0;                           // максимальные и минимальные значения влажности
  float minHumi = 99;


 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);   // Задаем адрес дисплея

  byte degree[8] =         // Битовая маска символа градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};    

void setup()
{
  //Serial.begin(9600); 
  lcd.begin(16,2);                                // Инициализация lcd             
  dht.begin();
  lcd.createChar(1, degree);                      // Создаем символ под номером 1
}

void loop()
{  
  float currentHumi = dht.readHumidity();
  float currentTemp = dht.readTemperature();

  if (currentTemp > maxTemp) maxTemp = currentTemp; //сравниваем измеренное значение температуры с минимумом и максимумом
  if (currentTemp < minTemp) minTemp = currentTemp;

  if (currentHumi > maxHumi) maxHumi = currentHumi; //сравниваем измеренное значение влажности с минимумом и максимумом
  if (currentHumi < minHumi) minHumi = currentHumi;

  lcd.clear();                                    // Очищаем экран и устанавливаем курсор в начало 1 строки
  lcd.print("Humidity =    %");                  // Выводим текст
  lcd.setCursor(11, 0);                           // Устанавливаем курсор на 11 символ 1 строки              
  lcd.print(currentHumi,0);                       // Выводим значение влажности
  lcd.setCursor(0, 1);                            // Устанавливаем курсор в начало 2 строки
  lcd.print("Temp     =   \1C");                 // Выводим текст, \1 - значок градуса
  lcd.setCursor(11, 1);                           // Устанавливаем курсор на 11 символ 1 строки
  lcd.print(currentTemp,0);                       // Выводим значение температуры
  delay(5000);                                    //Ждем 5 секунд

  // После задержки выводим максимальную и минимальную температуру
  
  lcd.clear();
  lcd.print("Max Temp =   \1C");
  lcd.setCursor(11, 0);
  lcd.print(maxTemp,0);
  lcd.setCursor(0, 1);
  lcd.print("Min Temp =   \1C");
  lcd.setCursor(11, 1);
  lcd.print(minTemp,0);
  delay(3000);

  // После задержки выводим максимальную и минимальную температуру

  lcd.clear();
  lcd.print("Max Humi =    %");
  lcd.setCursor(11, 0);
  lcd.print(maxHumi,0);
  lcd.setCursor(0, 1);
  lcd.print("Min Humi =    %");
  lcd.setCursor(11, 1);
  lcd.print(minHumi,0);
  delay(3000);

}

 

bwn
Offline
Зарегистрирован: 25.08.2014

У вас выходит не за сутки, а за весь период работы.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

ага. Заодно можно избавиться от delay. Вот примерное направление развития: раз в 5 сек обновляем информацию, каждые 24 часа обнуляем минмаксы.

// Макрос периодического запуска чего-либо. 
// Подробнее об этой магии тут: alxarduino.blogspot.ru/2013/09/ComfortablyBlinkWithoutDelay.html
#define DO_EVERY_V(varname,interval,action) static unsigned long __lastDoTime_##varname = 0; if( (millis()-__lastDoTime_##varname>interval) ){ {action;}  __lastDoTime_##varname=millis(); }
#define DO_EVERY_V_1(varname,interval,action)  DO_EVERY_V(varname,interval,action) 
#define DO_EVERY(interval,action) DO_EVERY_V_1(__LINE__,interval,action)

/* 
 SDA - A4
 SDL - A5
 */

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "DHT.h"                                // Объявление переменной класса dht11
#define DHTPIN 2                                // Датчик DHT11 подключен к цифровому пину номер 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);
float currentHumi;
float currentTemp;
float maxTemp = -30;                         // максимальные и минимальные значения тепературы
float minTemp = 30;
float maxHumi = 0;                           // максимальные и минимальные значения влажности
float minHumi = 99;
const unsigned long resetMinMaxPeriod = 86400000UL;  // интервал обнуления min и max (сутки в мсек)
unsigned int updateDataPeriod = 3;                   // интервал чтения сенсора (сек, не менее 3)
unsigned int updateLCDPeriod = 5;                    // интервал обновления дисплея (сек)
byte displayState = 0;                               // счетчик экранных страниц

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);   // Задаем адрес дисплея

byte degree[8] =         // Битовая маска символа градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};    

void setup()
{
  //Serial.begin(9600); 
  lcd.begin(16,2);                                 // Инициализация lcd             
  dht.begin();
  lcd.createChar(1, degree);                       // Создаем символ под номером 1
  updateDataPeriod = updateLCDPeriod * 1000;       // переводим секунды в мсек
  updateLCDPeriod = updateLCDPeriod * 1000;        // переводим секунды в мсек
}

void loop()
{  
  DO_EVERY(updateDataPeriod, readSensor());        // раз в 3 сек читаем показания сенсора
  DO_EVERY(updateLCDPeriod, displayData());        // раз в 5 сек выводим показания. Можно 
                                                   // параллельно выводить показания 
                                                   // с других датчиков или делать что-то еще
  DO_EVERY(resetMinMaxPeriod, clearMinMax());      // раз в сутки очищаем min и max
}


void readSensor()
{
  currentHumi = dht.readHumidity();
  currentTemp = dht.readTemperature();

  if (currentTemp > maxTemp) maxTemp = currentTemp; //сравниваем измеренное значение температуры с минимумом и максимумом
  if (currentTemp < minTemp) minTemp = currentTemp;

  if (currentHumi > maxHumi) maxHumi = currentHumi; //сравниваем измеренное значение влажности с минимумом и максимумом
  if (currentHumi < minHumi) minHumi = currentHumi;
}

void displayData()
{
  displayState++;                                    // увеличиваем счетчик экранных страниц
  if (displayState > 3) displayState = 1;
  lcd.clear();                                       // Очищаем экран, курсор в начало
  switch (displayState)                              // смотрим какую страницу надо выводить
  {
  case 1: // экран 1 - выводим текущую температуру и влажность
    {
      lcd.print("Humidity =    %");                   // Выводим текст
      lcd.setCursor(11, 0);                           // Устанавливаем курсор на 11 символ 1 строки              
      lcd.print(currentHumi,0);                       // Выводим значение влажности
      lcd.setCursor(0, 1);                            // Устанавливаем курсор в начало 2 строки
      lcd.print("Temp     =   \1C");                  // Выводим текст, \1 - значок градуса
      lcd.setCursor(11, 1);                           // Устанавливаем курсор на 11 символ 1 строки
      lcd.print(currentTemp,0);                       // Выводим значение температуры
    }
  case 2: // экран 2 - выводим максимальную и минимальную температуру
    {
      lcd.print("Max Temp =   \1C");
      lcd.setCursor(11, 0);
      lcd.print(maxTemp,0);
      lcd.setCursor(0, 1);
      lcd.print("Min Temp =   \1C");
      lcd.setCursor(11, 1);
      lcd.print(minTemp,0);
    }
  case 3:  // экран 3 - выводим максимальную и минимальную влажность
    {
      lcd.print("Max Humi =    %");
      lcd.setCursor(11, 0);
      lcd.print(maxHumi,0);
      lcd.setCursor(0, 1);
      lcd.print("Min Humi =    %");
      lcd.setCursor(11, 1);
      lcd.print(minHumi,0);
    }
  }
}

void clearMinMax()        // обнуляем min и max
{
  maxTemp = -30;                         // максимальные и минимальные значения температуры
  minTemp = 30;
  maxHumi = 0;                           // максимальные и минимальные значения влажности
  minHumi = 99;
}

P.S. Так как RTC нету, то отсчет "суток" ведется от момента включения, плюс может быть незначительное "плавание" точности отсчета суток (в пределах пары сек в сутки).

bankir_1986
Offline
Зарегистрирован: 23.03.2015

Есть DS1307 (пост 1), точность точно падать не будет.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Я проще сделал, с помощью RTC перезагрузка ардуинки раз в сутки.

tss
tss аватар
Offline
Зарегистрирован: 24.02.2014

Скетч писал для домашней метеостанции, фиксация мин. и макс. темп. делал для того чтобы можно было посмотреть какая была за сутки.