Pomiar wilgotności oraz temperatury w ulu

Pomiar wilgotności oraz temperatury w ulu

Dane:

Konstrujemy przyrząd do sprawdzania wilgotności i temperatury w ulu lub innych obiektach nas interesujących

Arduino Uno
Dht22
Moduł czytnika kart SD
Powerbank zasilajacy
Kabelki przyłączeniowe

Szukane:

Celem niniejszego projektu jest sprawdzenie temperatury i wilgotności w ulu oraz możliwość zapisu na karcie micro sd

Rozwiązanie:

// Include Libraries
include „Arduino.h”
include „DHT.h”
include „SD.h”
// Pin Definitions
define DHT_PIN_DATA 2
define SDFILE_PIN_CS 10
// Zmienne globalne i definicje
// inicjalizacja obiektu
DHT dht(DHT_PIN_DATA);
File sdFile;
// zdefiniuj zmienne do menu testowania
const int timeout = 10000; //define timeout of 10 sec
char menuOption = 0;
long time0;
// Skonfiguruj niezbędne elementy do działania obwodu. Działa pierwszy za każdym razem, gdy obwód jest zasilany energią elektryczną.
void setup()
{
// Skonfiguruj Serial, który jest przydatny do debugowania
// Użyj Serial Monitor, aby wyświetlić drukowane wiadomości
Serial.begin(9600);
while (!Serial) ; // poczekaj na połączenie z portem szeregowym. Potrzebny do natywnego USB
Serial.println(„start”);
dht.begin(); // Ustaw pin SPI SS na wyjście, w przeciwnym razie funkcje biblioteki SD nie będą działać. // SD jest domyślnie ustawiony na używanie SPI SS Arduino pin 10 jako wybór chipa (CS). // Aby zmienić pin użyj SD.begin (SD_CS_PIN) pinMode(SDFILE_PIN_CS, OUTPUT); // Aby zmienić pin używać SD.begin (SD_CS_PIN) if (!SD.begin()) { Serial.println(F("Karta nieudana lub nieobecna")); while(1); } Serial.println(F("karta zainicjowana.")); menuOption = menu();
}
// Główna logika twojego obwodu. Definiuje interakcję między wybranymi komponentami. Po instalacji działa w kółko, w wiecznej pętli.
void loop()
{
if(menuOption == '1') { // DHT22/11 Humidity and Temperature Sensor - Test Code // Odczyt wilgotności w% float dhtHumidity = dht.readHumidity(); // Odczyt temperatury w stopniach Celsjusza, do użytku w stopniach Fahrenheita .readTempF () float dhtTempC = dht.readTempC(); Serial.print(F("Humidity: ")); Serial.print(dhtHumidity); Serial.print(F(" [%]\t")); Serial.print(F("Temp: ")); Serial.print(dhtTempC); Serial.println(F(" [C]")); } else if(menuOption == '2') { // Micro SD module - Test Code // Przykładowy kod SD tworzy plik datalog.txt do rejestrowania danych czujnika // otwórz plik. pamiętaj, że jednocześnie może być otwarty tylko jeden plik, // więc musisz zamknąć to przed otwarciem kolejnego. sdFile = SD.open("datalog.txt", FILE_WRITE); // jeśli plik istnieje na karcie SD, zapisz dane czujnika if (sdFile) { //zapis do pliku sdFile.println("ENTER SENSOR DATA HERE"); // zamkniecie tego pliku sdFile.close(); // Odkomentowanie drukowania do portu szeregowego //Serial.println("ENTER SENSOR DATA HERE"); } else { // if the file didn't open, print an error Serial.println(F("błąd podczas otwierania pliku.")); } } if (millis() - time0 > timeout) { menuOption = menu(); }
}
// Funkcja menu do wyboru komponentów do testowania
// Postępuj zgodnie z instrukcjami monitora szeregowego
char menu()
{
Serial.println(F("\nKtóry składnik chcesz przetestować?")); Serial.println(F("(1) DHT22/11 Humidity and Temperature Sensor")); Serial.println(F("(2) Micro SD module")); Serial.println(F("(menu) wyślij cokolwiek innego lub naciśnij przycisk resetowania na pokładzie\n")); while (!Serial.available()); // Read data from serial monitor if received while (Serial.available()) { char c = Serial.read(); if (isAlphaNumeric(c)) { if(c == '1') Serial.println(F("Teraz testuję czujnik wilgotności i temperatury DHT22 / 11")); else if(c == '2') Serial.println(F("Testuję teraz moduł Micro SD")); else { Serial.println(F("nielegalne wprowadzanie!")); return 0; } time0 = millis(); return c; } }
}
DHT.cpp
/* DHT library
MIT license
written by Adafruit Industries
*/
include „DHT.h”
define MIN_INTERVAL 2000
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
_pin = pin;
_type = type;
#ifdef __AVR
_bit = digitalPinToBitMask(pin);
_port = digitalPinToPort(pin);
#endif
_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for
// reading pulses from DHT sensor.
// Note that count is now ignored as the DHT reading algorithm adjusts itself
// basd on the speed of the processor.
}
void DHT::begin(void) {
// set up the pins!
pinMode(_pin, INPUT_PULLUP);
// Using this value makes sure that millis() – lastreadtime will be
// >= MIN_INTERVAL right away. Note that this assignment wraps around,
// but so will the subtraction.
_lastreadtime = -MIN_INTERVAL;
DEBUG_PRINT(„Max clock cycles: „); DEBUG_PRINTLN(_maxcycles, DEC);
}
//boolean S == Scale. True == Fahrenheit; False == Celcius
float DHT::readTemperature(bool S, bool force) {
float f = NAN;
if (read(force)) {
switch (_type) {
case DHT11:
f = data[2];
if(S) {
f = convertCtoF(f);
}
break;
case DHT22:
case DHT21:
f = data[2] & 0x7F;
f *= 256;
f += data[3];
f *= 0.1;
if (data[2] & 0x80) {
f *= -1;
}
if(S) {
f = convertCtoF(f);
}
break;
}
}
if (isnan(f))
{
Serial.println(„Failed to read Temperature!”);
}
return f;
}
float DHT::convertCtoF(float c) {
return c * 1.8 + 32;
}
float DHT::convertFtoC(float f) {
return (f – 32) * 0.55555;
}
float DHT::readHumidity(bool force) {
float f = NAN;
if (read()) {
switch (_type) {
case DHT11:
f = data[0];
break;
case DHT22:
case DHT21:
f = data[0];
f *= 256;
f += data[1];
f *= 0.1;
break;
}
}
if (isnan(f))
{
Serial.println(„Failed to read Humidity!”);
}
return f;
}
float DHT::readTempC()
{
return readTemperature();
}
float DHT::readTempF()
{
return convertCtoF(readTemperature());
}
//boolean isFahrenheit: True == Fahrenheit; False == Celcius
float DHT::computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit) {
// Using both Rothfusz and Steadman’s equations
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
float hi;
if (!isFahrenheit)
temperature = convertCtoF(temperature);
hi = 0.5 * (temperature + 61.0 + ((temperature – 68.0) * 1.2) + (percentHumidity * 0.094));
if (hi > 79) {
hi = -42.379 +
2.04901523 * temperature +
10.14333127 * percentHumidity +
-0.22475541 * temperature*percentHumidity +
-0.00683783 * pow(temperature, 2) +
-0.05481717 * pow(percentHumidity, 2) +
0.00122874 * pow(temperature, 2) * percentHumidity +
0.00085282 * temperature*pow(percentHumidity, 2) +
-0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);
if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0)) hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882); else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0)) hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
}
return isFahrenheit ? hi : convertFtoC(hi);
}
boolean DHT::read(bool force) {
// Check if sensor was read less than two seconds ago and return early
// to use last reading.
uint32_t currenttime = millis();
if (!force && ((currenttime – _lastreadtime) < 2000)) {
return _lastresult; // return last correct measurement
}
_lastreadtime = currenttime;
// Reset 40 bits of received data to zero.
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// Send start signal. See DHT datasheet for full signal diagram:
// http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
// Go into high impedence state to let pull-up raise data line level and
// start the reading process.
digitalWrite(_pin, HIGH);
delay(250);
// First set data line low for 20 milliseconds.
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW);
delay(20);
uint32_t cycles[80];
{
// Turn off interrupts temporarily because the next sections are timing critical
// and we don’t want any interruptions.
InterruptLock lock;
// End the start signal by setting data line high for 40 microseconds. digitalWrite(_pin, HIGH); delayMicroseconds(40); // Now start reading the data line to get the value from the DHT sensor. pinMode(_pin, INPUT_PULLUP); delayMicroseconds(10); // Delay a bit to let sensor pull data line low. // First expect a low signal for ~80 microseconds followed by a high signal // for ~80 microseconds again. if (expectPulse(LOW) == 0) { DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); _lastresult = false; return _lastresult; } if (expectPulse(HIGH) == 0) { DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); _lastresult = false; return _lastresult; } // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 // microsecond low pulse followed by a variable length high pulse. If the // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds // then it's a 1. We measure the cycle count of the initial 50us low pulse // and use that to compare to the cycle count of the high pulse to determine // if the bit is a 0 (high state cycle count < low state cycle count), or a // 1 (high state cycle count > low state cycle count). Note that for speed all // the pulses are read into a array and then examined in a later step. for (int i=0; i<80; i+=2) { cycles[i] = expectPulse(LOW); cycles[i+1] = expectPulse(HIGH); }
} // Timing critical code is now complete.
// Inspect pulses and determine which ones are 0 (high state cycle count < low // state cycle count), or 1 (high state cycle count > low state cycle count).
for (int i=0; i<40; ++i) { uint32_t lowCycles = cycles[2i]; uint32_t highCycles = cycles[2i+1]; if ((lowCycles == 0) || (highCycles == 0)) { DEBUG_PRINTLN(F(„Timeout waiting for pulse.”)); _lastresult = false; return _lastresult; } data[i/8] <<= 1; // Now compare the low and high cycle times to see if the bit is a 0 or 1. if (highCycles > lowCycles) {
// High cycles are greater than 50us low cycle count, must be a 1.
data[i/8] |= 1;
}
// Else high cycles are less than (or equal to, a weird case) the 50us low
// cycle count so this must be a zero. Nothing needs to be changed in the
// stored data.
}
DEBUG_PRINTLN(F(„Received:”));
DEBUG_PRINT(data[0], HEX); DEBUG_PRINT(F(„, „));
DEBUG_PRINT(data[1], HEX); DEBUG_PRINT(F(„, „));
DEBUG_PRINT(data[2], HEX); DEBUG_PRINT(F(„, „));
DEBUG_PRINT(data[3], HEX); DEBUG_PRINT(F(„, „));
DEBUG_PRINT(data[4], HEX); DEBUG_PRINT(F(” =? „));
DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX);
// Check we read 40 bits and that the checksum matches.
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
_lastresult = true;
return _lastresult;
}
else {
DEBUG_PRINTLN(F(„Checksum failure!”));
_lastresult = false;
return _lastresult;
}
}
// Expect the signal line to be at the specified level for a period of time and
// return a count of loop cycles spent at that level (this cycle count can be
// used to compare the relative time of two pulses). If more than a millisecond
// ellapses without the level changing then the call fails with a 0 response.
// This is adapted from Arduino’s pulseInLong function (which is only available
// in the very latest IDE versions):
// https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
uint32_t DHT::expectPulse(bool level) {
uint32_t count = 0;
// On AVR platforms use direct GPIO port access as it’s much faster and better
// for catching pulses that are 10’s of microseconds in length:
#ifdef __AVR
uint8_t portState = level ? _bit : 0;
while ((*portInputRegister(_port) & _bit) == portState) {
if (count++ >= _maxcycles) {
return 0; // Exceeded timeout, fail.
}
}
// Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266
// right now, perhaps bugs in direct port access functions?).
#else
while (digitalRead(_pin) == level) {
if (count++ >= _maxcycles) {
return 0; // Exceeded timeout, fail.
}
}
#endif
return count;
}

DHT.h
/* DHT library
MIT license
written by Adafruit Industries
*/
ifndef DHT_H
define DHT_H
if ARDUINO >= 100
#include „Arduino.h”
else
#include „WProgram.h”
endif
// Uncomment to enable printing out nice debug messages.
//#define DHT_DEBUG
// Define where debug output will be printed.
define DEBUG_PRINTER Serial
define DHTTYPE DHT22
// Setup debug printing macros.
ifdef DHT_DEBUG
#define DEBUG_PRINT(…) { DEBUG_PRINTER.print(VA_ARGS); }
#define DEBUG_PRINTLN(…) { DEBUG_PRINTER.println(VA_ARGS); }
else
#define DEBUG_PRINT(…) {}
#define DEBUG_PRINTLN(…) {}
endif
// Define types of sensors.
define DHT11 11
define DHT22 22
define DHT21 21
define AM2301 21
class DHT {
public:
DHT(uint8_t pin, uint8_t type = DHTTYPE, uint8_t count=6);
void begin(void);
float readTemperature(bool S=false, bool force=false);
float readTempC();
float readTempF();
float convertCtoF(float);
float convertFtoC(float);
float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true);
float readHumidity(bool force=false);
boolean read(bool force=false);
private:
uint8_t data[5];
uint8_t _pin, _type;
#ifdef __AVR
// Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask
// for the digital pin connected to the DHT. Other platforms will use digitalRead.
uint8_t _bit, _port;
#endif
uint32_t _lastreadtime, _maxcycles;
bool _lastresult;
uint32_t expectPulse(bool level);
};
class InterruptLock {
public:
InterruptLock() {
noInterrupts();
}
~InterruptLock() {
interrupts();
}
};
endif



Plik zip do pobrania:

Wygląd gotowego zestawu