blob: 8614ae694df6694f1a49c4158daa93a9ff1421e3 [file] [log] [blame]
/*
* Copyright (c) 2017 FH Dortmund and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Description:
* RoverDHT22 API - Interfaces for Rover DHT22 temperature and humidity sensor application development
*
* Contributors:
* M.Ozcelikors <mozcelikors@gmail.com>, created RoverDHT22 class 04.12.2017
*
*/
#include <roverapi/rover_dht22.hpp>
#include <wiringPi.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
rover::RoverDHT22::RoverDHT22()
:DHT22Pin(DHT22_RPI_PIN),
DHT22_SETUP_(0)
{
}
rover::RoverDHT22::~RoverDHT22(){}
void rover::RoverDHT22::initialize(void)
{
this->DHT22_SETUP_ = 1;
}
float rover::RoverDHT22::read(void)
{
if (this->DHT22_SETUP_ != 1)
{
fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
}
else
{
return this->readTemperature();
}
}
float rover::RoverDHT22::readTemperature (void)
{
if (this->DHT22_SETUP_ != 1)
{
fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
}
else
{
int data[5] = { 0, 0, 0, 0, 0 };
uint8_t laststate;
uint8_t counter;
uint8_t j;
uint8_t i;
int try_again = 1;
float f, h, c;
while (try_again == 1)
{
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
laststate = HIGH;
counter = 0;
j = 0;
/* pull pin down for 18 milliseconds */
pinMode( this->DHT22Pin, OUTPUT );
digitalWrite( this->DHT22Pin, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( this->DHT22Pin, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( this->DHT22Pin ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( this->DHT22Pin );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
f = c * 1.8f + 32;
#ifdef DEBUG
printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
#endif
try_again = 0;
}
else
{
/* Data not good */
try_again = 1;
//printf ("Data not good, skipping\n");
}
}
/* Return temperature */
return c;
}
}
float rover::RoverDHT22::readHumidity (void)
{
if (this->DHT22_SETUP_ != 1)
{
fprintf(stderr,"You havent set up RoverDHT22. Use RoverDHT22::initialize() !\n");
}
else
{
int data[5] = { 0, 0, 0, 0, 0 };
uint8_t laststate;
uint8_t counter;
uint8_t j;
uint8_t i;
int try_again = 1;
float f, h, c;
while (try_again == 1)
{
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
laststate = HIGH;
counter = 0;
j = 0;
/* pull pin down for 18 milliseconds */
pinMode( this->DHT22Pin, OUTPUT );
digitalWrite( this->DHT22Pin, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( this->DHT22Pin, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( this->DHT22Pin ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( this->DHT22Pin );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ( (j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
f = c * 1.8f + 32;
#ifdef DEBUG
printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
#endif
try_again = 0;
}
else
{
/* Data not good */
try_again = 1;
//printf ("Data not good, skipping\n");
}
}
/* Return humidity */
return h;
}
}
void rover::RoverDHT22::setDHT22Pin (const int pin)
{
this->DHT22Pin = pin;
}
int rover::RoverDHT22::getDHT22Pin (void)
{
return this->DHT22Pin;
}