The DHT11 sensor you are using appears to use a protocol similar to 1-wire, though the timings look a bit different at a glance. This was invented by Dallas (now Maxim) and is used in many of their devices, the DS18S20 is an example of a similar temperature sensor to the DHT11 made by them.
My experience with 1-wire (and the above maxim part) is that is a great protocol but can be a little fiddly setting up on a small micro due to the quite fast and not-so-tolerant timing, especially if you are using a lowish speed oscillator and C. However this 1-wire part seems to have more relaxed timings and data direction appears to be only one way, so things should be a bit simpler (although the maxim part can do more)
Anyway, the initial presence detect for your part is an easy one since you just have to hold the line down for at least 18ms, raise it high for 20-40us and then release it (set to high impedance input)
I'm not sure why it says to pull it high for the 20-40us, when releasing it and having the pullup do this (the Maxim parts do it this way, and this is standard for open drain communication) would have the same effect and prevent any potential bus conflicts, but it may be to do with the rise time needed. In any case as long as you release the line before 40us it should be okay.
I haven't checked everything, but in your start signal code it looks like you are doing things correctly (although I would avoid setting the output low before setting the pin to input) so it's likely it's to do with the micro settings or a connection issue (e.g. miswired pin, open circuit)
A few things to check:
- Have you tried a simple blink LED routine to confirm your LED is setup correctly?
- Are you absolutely sure your delay routines are producing the correct delay? Have you confirmed this on a scope?
- Have you confirmed the PIC pin is actually outputting the high/low levels correctly to the DHT11? (i.e. pin is setup and connected correctly - test at DHT11 pin to make sure signal is reaching it)
- Is the 5kΩ pullup resistor (recommended in the datasheet for lines <20m, if longer you may have to reduce the value) present on the line?
A couple of weeks ago i wanted to set up a simple circuit, which is going to measure humidity and temperature level in air. When i start to research I don’t have any knowledge about how to set up a circuit or how can i embed a code in a microcontroller unit and many similar question.
So, below I will explain my little challange step by step. I hope it will be helpfull. Before we start you should refill your cups it might be a little long.
Now here is my components list;
Pic 16F877A (40-Pin)
Crystal 4.0 MHz
22pF Capacitor
100nJ Capacitor (0.1uF)
330nJ Capacitor (0.3uF)
DHT11 (Humidity & Temperature sensor)
1uF Capacitor (1 Micro F)
10uF Capacitor
max232
RS232 DB9 Connector
9V battery & battery snap
Setting up;
1) Breadboard
Some kind of breadboards have positive or negative line through the board, on the other hand the other types’ power and ground lines might be diveded in two. You can figure out this via looking at the red and blue lines on the breadboard. And inner part of it, there are letters and numbers. Numbers represent the columns which are connected with each others. So, if I connect 5V to A-0 then B-0, C-0, D-0 and E-0 have same voltage.
2) 7805 Regulator (9V to 5V)
If you read pic16f877a and dht11’s datasheets, you learned that they working with 5V but our battery is 9V.
As you can see above you can easily regulate your voltage. Now you can feed your positive terminal/s from output of regulator.
3) DHT11 (Sensor)
This is a cheap, digital humidity and temperature sensor with 4 pin. Here is nice datasheet (because of my reputation i couldn't post more than 2 links. You can find it on google, if you find, take a look at two or more datasheet because some of them might not be clear enough) which is vital to understand how dht11 works.
While you working on electronic projects you will come across with Vcc, Vdd, Vss, Vee pins in a really short explanation Vcc and Vdd are positive voltage supply, Vee and Vss are negative ground supply. So you can assume that Vcc and Vdd are same for the following pictures.
4) Pic 16F877A (40 Pin)
This is a well known micro controller unit, easy to find and have enough leg for my project that’s why I prefer this pic. Here is datasheet: (unfortunately because of my reputation i couldn't post more than 2 links. You can find it on mikrochip's webpage) Datasheet show you the pin diagram. In diagram you will see numbers from 1 to 40. On following picture notice the small caved in point. It represents the first leg.
5) Crystal (Clock)
Just like every processor, 877a also needs to clock. Please don’t consider the scheme’s crystal Mhz, our circuit works with 4MHz Quartz crystal with 22pF Capacitors.
6) Max232
Ok, as i said that this project going to measure temperature - humidity and send these values to the computer. At this point, to able to get these values from our circuit to pc, we have to build a serial communication part. Do not be afraid of telecommunications words, with the help of RS-232 cable everything is really simple. Before connect the cable you should build the following scheme. On the picture you will see TTL serial TX and RX these two cable going to connect with the pic’s 25 (TX) and 26th (RX) pins.
Above scheme may be confusing imagine that at the bottom of the picture there is a ground and four black node (which are near to the bottom) connected to ground.
For complete proteus tutorial you can find my video below, but do not forget proteus is just a simulation and that is not guaranteed that your hardware is going to work properly. Especially frequency can cause some problems. Here is
My YouTube Video!
In mikroC code I set the leds according to the humidity if it is greater than 20% upper led turns on, and if humidity level pass over 30% 2nd led also turns on.
MikroC Code;
sbit Data at RB0_bit;
sbit DataDir at TRISB0_bit;
unsigned short k;
unsigned short T_Byte1, T_Byte2, RH_Byte1, RH_Byte2;
char temp[] = "Temperature is 00.0 C";
char hum[] = "Humidity is 00.0 %";
void DHT11StartSignal(){
DataDir = 0;
Data = 0;
Delay_ms(25);
Data = 1;
Delay_us(30);
DataDir = 1;
}
unsigned short DHT11CheckResponse(){
k = 150;
while(!Data){
Delay_us(2);
k--;
if(k<1) return 0; // time out
}
k = 150;
while(Data){
Delay_us(2);
k--;
if(k<1) return 0; // time out
}
return 1;
}
unsigned short DHT11ReadByte(){
int i;
unsigned short num = 0;
DataDir = 1;
for (i=0; i<8; i++){
while(!Data);
Delay_us(40);
if(Data) num |= 1<<(7-i);
while(Data);
}
return num;
}
void main() {
UART1_Init(9600);
TRISC.RC0 = 0;
TRISC.RC1 = 0;
TRISC.RC2 = 0;
while(1){
DHT11StartSignal();
if(!DHT11CheckResponse()) continue;
RH_Byte1 = DHT11ReadByte();
RH_Byte2 = DHT11ReadByte();
T_Byte1 = DHT11ReadByte();
T_Byte2 = DHT11ReadByte();
DHT11ReadByte(); /* Checksum */
// Set temp
temp[15] = T_Byte1/10 + 48;
temp[16] = T_Byte1%10 + 48;
temp[18] = T_Byte2/10 + 48;
UART1_Write_Text(temp);
UART1_Write(10);
UART1_Write(13);
// Set hum
hum[12] = RH_Byte1/10 + 48;
hum[13] = RH_Byte1%10 + 48;
hum[15] = RH_Byte2/10 + 48;
UART1_Write_Text(hum);
UART1_Write(10);
UART1_Write(13);
UART1_Write(10);
UART1_Write(13);
PORTC.RC0 = (RH_Byte1) >= 20;
PORTC.RC1 = (RH_Byte1) >= 30;
PORTC.RC2 = (RH_Byte1) >= 40;
// Wait
Delay_ms(1000);
}
}
And final part:
Embeding code into the MPU;
Best Answer
As per the datasheet, the DHT21 timings are shorter with 3.3V and longer with 5V. I switched it from 5V to 3.3V and now it reads the humidity properly. It seems that while in the Arduino you have it at 5V, the software side/routines for the banana pi and raspberry are assuming it is connected at 3.3V.
From the software mentioned in the question, the fastest seems to be lol_dht22. I am using a slightly changed version of it (by myself), that creates files in /var/run aprox every 9-10 seconds to feed rpimonitor.
As @ChrisStratton correctly says, this method of bit banging/polling is highly prone to errors, especially when running in user land.
The simple protocol checksum implemented by the DHT21 is clearly not strong enough to weed out most of the errors/spikes (and there are many). I had to add simple software correction routines to ignore out of place values, and even then there are spikes.
The code for reading the DHT11/DHT21/DHT22 sensors is at my github https://github.com/ruyrybeyro/rdht .
I was also in doubt wether I would need to touch the R1 device tree configuration, as I did to configure the 1Wire protocol with another temperature sensor. It was not needed.
As an additional note, care must be taken when following blindly schematics online. While the Arduino bus operates at +5V, raspberry and compatibles operate at +3V; while apparently it is not the case of the DHT21 (I stress apparently as the R1 bus is more resilient than the rpi bus), feeding at random devices/sensors from +5V connected to an rpi bus can be potentially harmful to your SBC.
The measured temperature(s) also seems consistently to be higher +2 Celsius than what they should be, and these temperature inconsistencies are reported by many others using DHT21 devices.