The following does work, mostly, to read a DHT11 humidity/ temperature sensor. That, I believe, returns 5 bytes: humidity: integer part of “%”, humidity: decimal part of “%”, temperature: integer part, temperature: decimal part, checksum
I’m wondering if it has to be so obscure?
The hardware connects via “Analog 0”. which I suspect (comments welome!) is being used as Digital 14.
I’ve said “works, mostly”. because the decimal part of both the tture and humidity is always zero. (I’ll solve that problem other ways… I only mention it in case you “stub your toe” on what the problem is there!)
#define DHT11_PIN 0 // ADC0
byte read_dht11_dat()
{
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
while(!(PINC & _BV(DHT11_PIN))); // wait for 50us
delayMicroseconds(30);
if(PINC & _BV(DHT11_PIN))
result |=(1<<(7-i));
while((PINC & _BV(DHT11_PIN))); // wait '1' finish
}
return result;
}
void setup()
{
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
Serial.begin(9600);
Serial.println("Ready");
}
void loop()
{
byte dht11_dat[5];
byte dht11_in;
byte i;
// start condition
// 1. pull-down i/o pin from 18ms //(I believe that should be "FOR 18ms")
PORTC &= ~_BV(DHT11_PIN);
delay(18);
PORTC |= _BV(DHT11_PIN);
delayMicroseconds(40);
DDRC &= ~_BV(DHT11_PIN);
delayMicroseconds(40);
dht11_in = PINC & _BV(DHT11_PIN);
if(dht11_in){
Serial.println("dht11 start condition 1 not met");
return;
}
delayMicroseconds(80);
dht11_in = PINC & _BV(DHT11_PIN);
if(!dht11_in){
Serial.println("dht11 start condition 2 not met");
return;
}
delayMicroseconds(80);
// now ready for data reception
for (i=0; i<5; i++)
dht11_dat[i] = read_dht11_dat();
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
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("Current humdity = ");
Serial.print(dht11_dat[0], DEC);
Serial.print(".");
Serial.print(dht11_dat[1], DEC);
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(dht11_dat[2], DEC);
Serial.print(".");
Serial.print(dht11_dat[3], DEC);
Serial.println("C ");
delay(2000);
}
I am asking “Does this have to be so obscure”. For instance, in setup we see…
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
DHT11_PIN has been “#defined” as zero, just to save you looking.
Is there any important difference between the above and…
pinMode(14,OUTPUT);
digitalWrite(14,HIGH);
(I’d put the “14” in a #defined constant. The alternative code, if is IS equivalent to the original, has the advantage(?) of allowing the user to put the sensor on a line other than Analog0-5, besides being easier to read! Of course, the PORTC part has to be worked on if the sensor is connected via, say, Digital 12.)
===
Turning to the “obscure” lines in loop()…
Is my guess on target? I’m guessing that the lines I don’t like “merely” twiddle bits (in the narrow, one-digit-of-a-binary-number sense) and read bits?
Maybe the lines in the code execute faster, or more consistently, than the “less obscure” alternatives? I realize that timing issues may be forcing the “obscure” code.
Help welcomed!
Tom