You are on page 1of 16

TUGAS SISTEM INSTRUMENTASI DAN AKUISISI DATA

Dosen : Dr.Ir.Zahir Zainuddin, M.Sc

Oleh : Puput Dani Prasetyo adi / p2700211407 Nicodemus Rahanra / p2700211406 Suryadi /p2700211408 Alimuddin / p2700211418

Program Pasca Sarjana Fakultas Teknik Elektro Universitas Hasanuddin Makassar 2012
1|DHT11 Sensor

Deskripsi Tugas : 1. Membuat, menganalisa, merakit sensor DHT11 Sebagai sensor pendeteksi Suhu dan Kelembaban menggunakan Mikrokontroller Arduino UNO.

About DHT11 sensor The DHT11 sensor comes in a single row 4-pin package and operates from 3.5 to 5.5V power supply. It can measure temperature from 0-50 C with an accuracy of 2C and relative humidity ranging from 20-95% with an accuracy of 5%. The sensor provides fully calibrated digital outputs for the two measurements. It has got its own proprietary 1-wire protocol, and therefore, the communication between the sensor and a microcontroller is not possible through a direct interface with any of its peripherals. The protocol must be implemented in the firmware of the MCU with precise timing required by the sensor.

DHT11 sensor comes in a single row 4-pin package

Model Terbaru DHT11 Sensor

2|DHT11 Sensor

spesifikasi Pasokan Voltage: 5 V Rentang temperatur :0-50 C kesalahan 2 C Kelembaban :20-90% RH 5% RH error Interface: Digital

Skematic DHT11 Sensor

The following timing diagrams describe the data transfer protocol between a MCU and the DHT11 sensor. The MCU initiates data transmission by issuing a Start signal. The MCU pin must be configured as output for this purpose. The MCU first pulls the data line low for at least 18 ms and then pulls it high for next 20-40 s before it releases it. Next, the sensor responds to the MCU Start signal by pulling the line low for 80 s followed by a logic high signal that also lasts for 80 s. Remember that the MCU pin must be configured to input after finishing the Start signal. Once detecting the response signal from the sensor, the MCU should be ready to receive data from the sensor. The sensor then sends 40 bits (5 bytes) of data continuously in the data line. Note that while transmitting bytes, the sensor sends the most significant bit first.

3|DHT11 Sensor

"Start" and "Response" signals

The 40-bit data from the sensor has the following structure. Data (40-bit) = Integer Byte of RH + Decimal Byte of RH + Integer Byte of Temp. + Decimal Byte of Temp. + Checksum Byte For DHT11 sensor, the decimal bytes of temperature and humidity measurements are always zero. Therefore, the first and third bytes of received data actually give the numeric values of the measured relative humidity (%) and temperature (C). The last byte is the checksum byte which is used to make sure that the data transfer has happened without any error. If all the five bytes are transferred successfully then the checksum byte must be equal to the last 8 bits of the sum of the first four bytes, i.e., Checksum = Last 8 bits of (Integer Byte of RH + Decimal Byte of RH + Integer Byte of Temp. + Decimal Byte of Temp.) Now lets talk about the most important thing, which is signalling for transmitting 0 and 1. In order to send a bit of data, the sensor first pulls the line low for 50 s. Then it raises the line to high for 26-28 s if it has to send 0, or for 70 s if the bit to be transmitted is 1. So it is the width of the positive pulse that carries information about 1 and 0.

4|DHT11 Sensor

Timing difference for transmitting "1s" and "0s"

Start, Response and Data signals in sequence At the end of the last transmitted bit, the sensor pulls the data line low for 50 s and then releases it. The DHT11 sensor requires an external pull-up resistor to be connected between its Vcc and the data line so that under idle condition, the data line is always pulled high. After finishing the data transmission and releasing the data line, the DHT11 sensor goes to the lowpower consumption mode until a new Start signal arrives from the MCU. Circuit diagram Here is the circuit diagram showing the DHT11 sensor and a HD44780-based character LCD interfaced to the PIC16F628A microcontroller. The microcontroller runs at 4.0 MHz clock using an external resonator connected between OSC1 (16) and OSC2 (15) pins. The use of 4.0 MHz clock makes the timing calculation easier as 1 machine cycle becomes 1 s. The timing information will be used to calculate the width of the received data pulse from the sensor so that we could identify if it is carrying a 1 or 0.

5|DHT11 Sensor

Circuit connections for PIC16F628A and DHT11 sensor

6|DHT11 Sensor

DHT11 connect with Arduino Uno Microcontroller

Wiring DHT11 at Arduino Uno

7|DHT11 Sensor

Output at COM4 DHT11 connect with Arduino Uno Microcontroller and LCD 16 x 12

Connection DHT11 with arduino and LCD 16 x 12

8|DHT11 Sensor

HASIL DAN FOTO SAAT EKSPERIMENT ATAU PERCOBAAN

Suhu dan kelembaban yang tampil di LCD

9|DHT11 Sensor

1) Program yang digunakan untuk menampilkan output DHT11 Sensor di COM4


#define DHT11_PIN 0 // define analog port 0 byte read_dht11_dat() { byte i = 0; byte result=0; for(i=0; i< 8; i++) { while(!(PINC & _BV(DHT11_PIN))) {}; // wait forever until anlog input port 0 is '1' (NOTICE: PINC reads all the analog input ports //and _BV(X) is the macro operation which pull up positon 'X'to '1' and the rest positions to '0'. it is equivalent to 1<<X.) delayMicroseconds(30); if(PINC & _BV(DHT11_PIN)) //if analog input port 0 is still '1' after 30 us result |=(1<<(7-i)); //this position is 1 while((PINC & _BV(DHT11_PIN))); // wait '1' finish } return result; } void setup() { DDRC |= _BV(DHT11_PIN); //let analog port 0 be output port PORTC |= _BV(DHT11_PIN); //let the initial value of this port be '1' Serial.begin(9600); Serial.println("Ready"); } void loop() { byte dht11_dat[5]; byte dht11_in; byte i;// start condition PORTC &= ~_BV(DHT11_PIN); // 1. pull-down i/o pin for 18ms delay(18); PORTC |= _BV(DHT11_PIN); // 2. pull-up i/o pin for 40us delayMicroseconds(1); DDRC &= ~_BV(DHT11_PIN); //let analog port 0 be input port delayMicroseconds(40); dht11_in = PINC & _BV(DHT11_PIN); // read only the input port 0 if(dht11_in) { Serial.println("dht11 start condition 1 not met"); // wait for DHT response signal: LOW delay(1000); return; } delayMicroseconds(80); dht11_in = PINC & _BV(DHT11_PIN); // if(!dht11_in) { Serial.println("dht11 start condition 2 not met"); //wair for second response signal:HIGH return; 10 | D H T 1 1 S e n s o r

} delayMicroseconds(80);// now ready for data reception for (i=0; i<5; i++) { dht11_dat[i] = read_dht11_dat();} //recieved 40 bits data. Details are described in datasheet DDRC |= _BV(DHT11_PIN); //let analog port 0 be output port after all the data have been received PORTC |= _BV(DHT11_PIN); //let the value of this port be '1' after all the data have been received byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];// check check_sum if(dht11_dat[4]!= dht11_check_sum) { Serial.println("DHT11 checksum error"); } Serial.print("Kelembaban = "); Serial.print(dht11_dat[0], DEC); Serial.print("."); Serial.print(dht11_dat[1], DEC); Serial.print("% "); Serial.print("Suhu = "); Serial.print(dht11_dat[2], DEC); Serial.print("."); Serial.print(dht11_dat[3], DEC); Serial.println("C "); delay(2000); //fresh time }

2) Program yang digunakan untuk menampilkan output DHT11 Sensor di LCD 16x12
//ReadHumTturDHT11alternate2 //ver 19Jly12 //This is a re-written DHT11/ DHT22 reading code. //DHT stuff in subroutines. //See for more information.... //http://sheepdogguides.som/arduino/ar3ne1humDHT11.htm //N.B. "bit" is used in the narrow, computer "1 or 0" // sense throughout. //"DHT" from sensor's names: DHT11, DHT22. //DHT aka Aosong AM2302, and there's an AM2303 which //seems to be in the same family. //Comments on this based on Aosong AM2302, aka DHT22, datasheet. //Believed to generally apply to DHT11 as well, except in the //case of the DHT11, I believe the second and fourth bytes are //always zero. //***N.B.**** //The code WORKS... the comments may not yet be EXACTLY right. //See the web-page cited above for latest news. //This code works with a DHT11 humidity/ temperature sensing module //from nuelectronics.com, complied with ver 0018 of the Arduino environment //Sensor attached to P4 (nuelectonics shield)/ analog 0, aka digital 14. //That "module", according to the 11 | D H T 1 1 S e n s o r

//nuelectronics site, and visual inspection simply provides for easy //connection of an Aosong DHT11 unit to the nuelectronics datalogging //shield. Only 3 wires are involved: Vcc, ground, and a single data //line. One of the DHT11's 4 pins goes nowhere. //You should not need to change anything except the next line to use //the software with the sensor on a different line, or for a DHT22. //Just "huffing" on the sensor from deeply filled lungs should show //a near instant rise in humidity //#define dht_PIN 0 //no ; here. deprecate ADC0... //even though we are using it as a digital pin. //Other parts of code restrict us to using //ADC0-5, aka D14-19 #define dht_dpin 14 //no ; here. Set equal to channel sensor is on, //where if dht_dpin is 14, sensor is on digital line 14, aka analog 0 #define LIGHT_SENSOR_PIN 1 // include the library code: #include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(2, 3, 4, 5, 6, 7); byte bGlobalErr; //for passing error code back from complex functions. byte dht_dat[4]; //Array to hold the bytes sent from sensor. int light_intensity = 0; unsigned int flip = 0; void setup(){ //Blink LED to detect hangs pinMode(13, OUTPUT); // set up the LCD's number of columns and rows: lcd.begin(16, 2); lcd.print("HALLO, PUPUT!"); InitDHT(); //Do what's necessary to prepare for reading DHT //Serial.begin(9600); delay(300); //Let system settle //Serial.println("Humidity and temperature\n\n"); delay(700); //Wait rest of 1000ms recommended delay before //accessing sensor } //end "setup()" void loop(){ // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): //lcd.setCursor(0, 1); // print the number of seconds since reset: //lcd.print("100"); //lcd.print(millis()/1000); if ( flip & 1 ) { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } flip++; 12 | D H T 1 1 S e n s o r

light_intensity=analogRead(LIGHT_SENSOR_PIN); ReadDHT(); //This is the "heart" of the program. //Fills global array dht_dpin[], and bGlobalErr, which //will hold zero if ReadDHT went okay. //Must call InitDHT once (in "setup()" is usual) before //calling ReadDHT. //Following: Display what was seen... switch (bGlobalErr) { case 0: lcd.setCursor(0, 0); // Serial.print("humdity = "); lcd.print("Suhu = C"); lcd.setCursor(7, 0); lcd.print( dht_dat[2], DEC); //Serial.print(dht_dat[0], DEC); //Serial.print("."); //Serial.print(dht_dat[1], DEC); //Serial.print("% "); lcd.setCursor(0, 1); //Every 7 out of 15 times we show humidity, rest temp if ((flip % 15) > 7 ) { lcd.print("Kelembaban %"); lcd.setCursor(11, 1); lcd.print( dht_dat[0], DEC); } else { lcd.print("Cahaya = "); lcd.setCursor(8, 1); lcd.print( light_intensity, DEC); } //Serial.print("temperature = "); //Serial.print(dht_dat[2], DEC); //Serial.print("."); //Serial.print(dht_dat[3], DEC); //Serial.println("C "); break; case 1: //Serial.println("Error 1: DHT start condition 1 not met."); break; case 2: //Serial.println("Error 2: DHT start condition 2 not met."); break; case 3: //Serial.println("Error 3: DHT checksum error."); break; default: //Serial.println("Error: Unrecognized code encountered."); break; } //end "switch" delay(800); //Don't try to access too frequently... in theory //should be once per two seconds, fastest, //but seems to work after 0.8 second. 13 | D H T 1 1 S e n s o r

} // end loop() /*Below here: Only "black box" elements which can just be plugged unchanged unchanged into programs. Provide InitDHT() and ReadDHT(), and a function one of them uses.*/ void InitDHT(){ //DDRC |= _BV(dht_PIN);//set data pin... for now... as output //DDRC is data direction register for pins A0-5 are on //PORTC |= _BV(dht_PIN);//Set line high //PORTC relates to the pins A0-5 are on. //Alternative code... // if (dht_dpin-14 != dht_PIN){Serial.println("ERROR- dht_dpin must be 14 more than dht_PIN");};//end InitDHT pinMode(dht_dpin,OUTPUT); // replaces DDRC... as long as dht_dpin=14->19 digitalWrite(dht_dpin,HIGH); //Replaces PORTC |= if dht_pin=14->19 } //end InitDHT void ReadDHT(){ /*Uses global variables dht_dat[0-4], and bGlobalErr to pass "answer" back. bGlobalErr=0 if read went okay. Depends on global dht_PIN for where to look for sensor.*/ bGlobalErr=0; byte dht_in; byte i; // Send "start read and report" command to sensor.... // First: pull-down i/o pin for 18ms digitalWrite(dht_dpin,LOW); //Was: PORTC &= ~_BV(dht_PIN); delay(18); delayMicroseconds(600);//TKB, frm Quine at Arduino forum /*aosong.com datasheet for DHT22 says pin should be low at least 500us. I infer it can be low longer without any] penalty apart from making "read sensor" process take longer. */ //Next line: Brings line high again, // second step in giving "start read..." command digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN); delayMicroseconds(40); //DHT22 datasheet says host should //keep line high 20-40us, then watch for sensor taking line //low. That low should last 80us. Acknowledges "start read //and report" command. //Next: Change Arduino pin to an input, to //watch for the 80us low explained a moment ago. pinMode(dht_dpin,INPUT); //Was: DDRC &= ~_BV(dht_PIN); delayMicroseconds(40); dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN); if(dht_in) { bGlobalErr=1; //Was: Serial.println("dht11 start condition 1 not met"); return; } //end "if..." delayMicroseconds(80); 14 | D H T 1 1 S e n s o r

dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN); if(!dht_in) { bGlobalErr=2; //Was: Serial.println("dht11 start condition 2 not met"); return; } //end "if..." /*After 80us low, the line should be taken high for 80us by the sensor. The low following that high is the start of the first bit of the forty to come. The routine "read_dht_dat()" expects to be called with the system already into this low.*/ delayMicroseconds(70); //now ready for data reception... pick up the 5 bytes coming from // the sensor for (i=0; i<5; i++) dht_dat[i] = read_dht_dat(); //Next: restore pin to output duties pinMode(dht_dpin,OUTPUT); //Was: DDRC |= _BV(dht_PIN); //N.B.: Using DDRC put restrictions on value of dht_pin //Next: Make data line high again, as output from Arduino digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN); //N.B.: Using PORTC put restrictions on value of dht_pin //Next see if data received consistent with checksum received byte dht_check_sum = dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3]; /*Condition in following "if" says "if fifth byte from sensor not the same as the sum of the first four..."*/ if(dht_dat[4]!= dht_check_sum) {bGlobalErr=3; } //Was: Serial.println("DHT11 checksum error"); }; //end ReadDHT() byte read_dht_dat(){ //Collect 8 bits from datastream, return them interpreted //as a byte. I.e. if 0000.0101 is sent, return decimal 5. //Code expects the system to have recently entered the //dataline low condition at the start of every data bit's //transmission BEFORE this function is called. byte i = 0; byte result=0; for(i=0; i< 8; i++) { //We enter this during the first start bit (low for 50uS) of the byte //Next: wait until pin goes high while(digitalRead(dht_dpin)==LOW) ; //Was: while(!(PINC & _BV(dht_PIN))); //signalling end of start of bit's transmission. //Dataline will now stay high for 27 or 70 uS, depending on //whether a 0 or a 1 is being sent, respectively. delayMicroseconds(30); //AFTER pin is high, wait further period, to be //into the part of the timing diagram where a 0 or a 1 denotes 15 | D H T 1 1 S e n s o r

//the datum being send. The "further period" was 30uS in the software //that this has been created from. I believe that a higher number //(45?) would be more appropriate. //Next: Wait while pin still high if (digitalRead(dht_dpin)==HIGH) //Was: if(PINC & _BV(dht_PIN)) result |=(1<<(7-i)); // "add" (not just addition) the 1 //to the growing byte //Next wait until pin goes low again, which signals the START //of the NEXT bit's transmission. while (digitalRead(dht_dpin)==HIGH) ; //Was: while((PINC & _BV(dht_PIN))); } //end of "for.." return result; } //end of "read_dht_dat()"

16 | D H T 1 1 S e n s o r

You might also like