FRA221_2015 / Mbed 2 deprecated 1A_PROJECT_DIGITAL

Dependencies:   mbed

Fork of 1A_PROJECT_DIGITAL by Jakkapan Keawsalak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DHT22.cpp Source File

DHT22.cpp

00001 
00002 #include "DHT22.h"
00003 #define DHT22_DATA_BIT_COUNT 41
00004 
00005 DHT22::DHT22(PinName Data) {
00006 
00007     _data = Data;                // Set Data Pin
00008     _lastReadTime = time(NULL);
00009     _lastHumidity = 0;
00010     _lastTemperature = DHT22_ERROR_VALUE;
00011 }
00012 
00013 DHT22::~DHT22() {
00014 }
00015 
00016 DHT22_ERROR DHT22::readData() {
00017     int i, j, retryCount;
00018     int currentTemperature=0;
00019     int currentHumidity=0;
00020     unsigned int checkSum = 0, csPart1, csPart2, csPart3, csPart4;
00021     unsigned int bitTimes[DHT22_DATA_BIT_COUNT];
00022     DHT22_ERROR err = DHT_ERROR_NONE;
00023     time_t currentTime = time(NULL);
00024 
00025     DigitalInOut  DATA(_data);
00026        
00027     for (i = 0; i < DHT22_DATA_BIT_COUNT; i++) {
00028         bitTimes[i] = 0;
00029     }
00030     
00031     if (int(currentTime - _lastReadTime) < 2) {        
00032         err = DHT_ERROR_TOO_QUICK;
00033     }   
00034     retryCount = 0;
00035     
00036     do {
00037         if (retryCount > 125) {
00038             printf("DHT22 Bus busy!");
00039             err = DHT_BUS_HUNG;
00040         }
00041         retryCount ++;
00042         wait_us(2);
00043     } while (DATA==0);   // exit on DHT22 return 'High' Signal within 250us
00044     
00045     // Send the activate pulse
00046     // Step 1: MCU send out start signal to DHT22 and DHT22 send
00047     //         response signal to MCU.
00048     // If always signal high-voltage-level, it means DHT22 is not 
00049     // working properly, please check the electrical connection status.
00050     //
00051     DATA.output(); // set pin to output data
00052     DATA = 0;      // MCU send out start signal to DHT22
00053     wait_ms(18);   // 18 ms wait (spec: at least 1ms)
00054     DATA = 1;      // MCU pull up 
00055     wait_us(40);
00056     DATA.input();  // set pin to receive data
00057     // Find the start of the ACK Pulse
00058     retryCount = 0;
00059     do {
00060         if (retryCount > 40)  { // (Spec is 20-40 us high)
00061             printf("DHT22 not responding!");
00062             err = DHT_ERROR_NOT_PRESENT;
00063         }
00064         retryCount++;
00065         wait_us(1);
00066     } while (DATA==1);   // Exit on DHT22 pull low within 40us
00067     if (err != DHT_ERROR_NONE) {
00068         // initialisation failed
00069         return err;    
00070     }
00071     wait_us(80); // DHT pull up ready to transmit data
00072     
00073     /*
00074     if (DATA == 0) {
00075         printf("DHT22 not ready!");
00076         err = DHT_ERROR_ACK_TOO_LONG;
00077         return err;
00078     }
00079     */
00080     
00081     // Reading the 5 byte data stream
00082     // Step 2: DHT22 send data to MCU
00083     //         Start bit -> low volage within 50us (actually could be anything from 35-75us)
00084     //         0         -> high volage within 26-28us (actually could be 10-40us)
00085     //         1         -> high volage within 70us (actually could be 60-85us)
00086     //         See http://www.sparkfun.com/products/10167#comment-4f118d6e757b7f536e000000
00087     
00088     
00089     for (i = 0; i < 5; i++) {
00090         for (j = 0; j < 8; j++) {
00091             // Instead of relying on the data sheet, just wait while the RHT03 pin is low
00092             retryCount = 0;
00093             do {
00094                 if (retryCount > 75)  {
00095                     printf("DHT22 timeout waiting for data!");
00096                     err = DHT_ERROR_DATA_TIMEOUT;
00097                 }
00098                 retryCount++;
00099                 wait_us(1);
00100             } while (DATA == 0);
00101             // We now wait for 40us
00102             wait_us(40);
00103             if (DATA == 1) {  
00104                 // If pin is still high, bit value is a 1
00105                 bitTimes[i*8+j] = 1;
00106             } else {  
00107                 // The bit value is a 0
00108                 bitTimes[i*8+j] = 0;
00109             }
00110             int count = 0;
00111             while (DATA == 1 && count < 100) {  
00112                 wait_us(1); // Delay for 1 microsecond  
00113                 count++;  
00114             }
00115         }
00116     }
00117     // Re-init DHT22 pin  
00118     DATA.output();  
00119     DATA = 1;
00120 
00121     // Now bitTimes have the actual bits
00122     // that were needed to find the end of each data bit
00123     // Note: the bits are offset by one from the data sheet, not sure why
00124     currentHumidity    = 0;
00125     currentTemperature = 0;
00126     checkSum           = 0;
00127     // First 16 bits is Humidity
00128     for (i=0; i<16; i++) {
00129         //printf("bit %d: %d  ", i, bitTimes[i+1]);
00130         if (bitTimes[i+1] > 0) {
00131             currentHumidity |= ( 1 << (15-i));
00132         }
00133     }
00134     
00135     // Second 16 bits is Temperature 
00136     for (i=0; i<16; i ++) {
00137         //printf("bit %d: %d  ", i+16, bitTimes[i+17]);
00138         if (bitTimes[i+17] > 0) {
00139             currentTemperature |= (1 <<(15-i));
00140         }
00141     }
00142 
00143     // Last 8 bit is Checksum
00144     for (i=0; i<8; i++) {
00145         //printf("bit %d: %d  ", i+32, bitTimes[i+33]);
00146         if (bitTimes[i+33] > 0) {
00147             checkSum |= (1 << (7-i));
00148         }
00149     }
00150    
00151     _lastHumidity = (float(currentHumidity) / 10.0);
00152     
00153     // if first bit of currentTemperature is 1, it is negative value.
00154     if ((currentTemperature & 0x8000)==0x8000) {        
00155         _lastTemperature = (float(currentTemperature & 0x7FFF) / 10.0) * -1.0;
00156     } else {
00157         _lastTemperature = float(currentTemperature) / 10.0;
00158     }
00159 
00160     // Calculate Check Sum
00161     csPart1 = currentHumidity >> 8;
00162     csPart2 = currentHumidity & 0xFF;
00163     csPart3 = currentTemperature >> 8;
00164     csPart4 = currentTemperature & 0xFF;
00165     
00166     if (checkSum == ((csPart1 + csPart2 + csPart3 + csPart4) & 0xFF)) {
00167         _lastReadTime = currentTime;
00168         //printf("OK-->Temperature :: %f , Humidity :: %f\r\n", _lastTemperature, _lastHumidity);
00169         err = DHT_ERROR_NONE;
00170         printf("\n");
00171         
00172     }
00173     else {
00174         //printf("DHT22 Checksum error!\n");
00175         //printf("Calculate check sum is %d\n",(csPart1 + csPart2 + csPart3 + csPart4) & 0xFF);
00176         //printf("Reading check sum is %d\n",checkSum);
00177         err = DHT_ERROR_CHECKSUM;
00178         printf("\n");
00179     }
00180     
00181     return err;
00182 }
00183 
00184 float DHT22::getTemperatureC() {
00185     return _lastTemperature;
00186 }
00187 
00188 float DHT22::getHumidity() {
00189     return _lastHumidity;
00190 }