Go Down

Topic: 1 wire communication problem (Read 472 times) previous topic - next topic

seanfan84

hi guys,
I'm trying to read 40bits from DHT11(Humidity and temperature sensor).
It uses 1 wire communication.
I need to pull LOW for 18ms, and then pull HIGH to request data from it.
It then send 40bits immediately, 28us represents"0" and 70us represents"1".
Here is the datasheet- www.robotshop.com/PDF/dht11.pdf

I've been trying to get data for several days with pulseIn() and I couldn't get it.

By using the code below,
Code: [Select]
#include <SoftwareSerial.h>
int response;
int data[40];

void setup(){
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  Serial.begin(9600);
  }


void loop(){
  delay(1000);
  pinMode(12,OUTPUT);
  digitalWrite(12,HIGH);
  digitalWrite(12,LOW);
  delay(18);
  digitalWrite(12,HIGH);

  pinMode(12,INPUT);
  response = pulseIn(12,HIGH);
  Serial.println(response);
  Serial.println();

  for (int i=0; i<40;i++){
     data[i] = pulseIn(12,HIGH);
   }
  for (int i=0; i<40;i++){
     Serial.println(data[i]);
   }
  delay(10000);
}


I gets

23
64
23
23
23
24
24
23
24
69
14
23
24
23
23
70
48
69
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0


In contrast, by using a more stupid method,
Code: [Select]
#include <SoftwareSerial.h>
int response;
int data[40];

void setup(){
  pinMode(11,OUTPUT);
  digitalWrite(11,HIGH);
  Serial.begin(9600);
  }


void loop(){
  delay(1000);
  pinMode(12,OUTPUT);
  digitalWrite(12,HIGH);
  digitalWrite(12,LOW);
  delay(18);
  digitalWrite(12,HIGH);

  pinMode(12,INPUT);
  response = pulseIn(12,HIGH);
  Serial.println(response);
  Serial.println();

response = pulseIn(12,HIGH);
  Serial.println(response);
  response = pulseIn(12,HIGH);
  Serial.println(response);
*40 times!!!!!

  }
  delay(10000);
}


guess what? I got only 8 none zero numbers!

Could anybody help with this problem? This is killing me~
Thanks!

johnwasser

I think the serial output might be taking so much time you miss most of the message.  Try removing these two lines:
Code: [Select]

  Serial.println(response);
  Serial.println();
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

seanfan84

But in the first code, I tried to read all bits into an array first.
If this is still not fast enough, I could not figure out a faster way.
Any suggestion for a faster solution? would pointer help?

Thanks.

johnwasser


But in the first code, I tried to read all bits into an array first.
If this is still not fast enough, I could not figure out a faster way.


If the first code you posted above is what you are calling 'the first code' you should read it again:

You signal for the DHT11 to start sending:
Code: [Select]

  digitalWrite(12,LOW);
  delay(18);
  digitalWrite(12,HIGH);


Switch to input mode:
Code: [Select]

  pinMode(12,INPUT);


Measure the length of the acknowledgement pulse:
Code: [Select]

  response = pulseIn(12,HIGH);


AND PRINT OUT THE LENGTH OF THE ACKNOWLEDGEMENT PULSE:
Code: [Select]

  Serial.println(response);
  Serial.println();


Before you fill the buffer with 40 more pulse lengths:
Code: [Select]

  for (int i=0; i<40;i++){
     data[i] = pulseIn(12,HIGH);
  }
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

PeterH

Are you rolling your own 1-wire library? Why not use the standard library? While you're at it, isn't there a driver library for that sensor too?
I only provide help via the forum - please do not contact me for private consultancy.

seanfan84

I removed those two lines, I got 20bits instead of 19 previously.
Still it does not work.
I'm thinking if that is the problem of pulseIn function.
Thanks.




But in the first code, I tried to read all bits into an array first.
If this is still not fast enough, I could not figure out a faster way.


If the first code you posted above is what you are calling 'the first code' you should read it again:

You signal for the DHT11 to start sending:
Code: [Select]

  digitalWrite(12,LOW);
  delay(18);
  digitalWrite(12,HIGH);


Switch to input mode:
Code: [Select]

  pinMode(12,INPUT);


Measure the length of the acknowledgement pulse:
Code: [Select]

  response = pulseIn(12,HIGH);


AND PRINT OUT THE LENGTH OF THE ACKNOWLEDGEMENT PULSE:
Code: [Select]

  Serial.println(response);
  Serial.println();


Before you fill the buffer with 40 more pulse lengths:
Code: [Select]

  for (int i=0; i<40;i++){
     data[i] = pulseIn(12,HIGH);
  }


seanfan84

Thanks, I just found that there is a library of this.
:D :D :D

Are you rolling your own 1-wire library? Why not use the standard library? While you're at it, isn't there a driver library for that sensor too?

Go Up