I want to read timer 0 values with 1us instruction cycle to read DH11 data bits

Hello,

I'm working now for testing DH11 sensor bits timings with TIMER0.

I want to do a test with my Arduino board, but since the Arduino is running at 16MHz with instruction cycle of 62.5ns, so when I read timer0 values for the data pulses I get different readings than it should be.

I need a timer running at 1us to measure the data bits.

For example, I want to measure the HIGH bit which is 70us with the TIMER0, where the TIMER0 is running at 62.5ns each increment, so 70us would be measured as 70us/16 = 4.375us.

Any ideas?!

1. Set the TC0 Prescaler to divide factor 8; you will get the Timer-0 clocking frequency (clkTC0) as 16 MHz/8 = 2 MHz with 0.5us period. The codes are:

TCCR0A = 0x00;
TCCR0B = 0x00;
TCCR0B = 0x02

2. If you really want to drive Timer-0 at 1 MHz clock frequency, set the 'System Clock Prescaler' division factor at 16. (Caution: this scheme will bring down the operating clock of the Arduino UNO at 1 MHz in place of the original 16 MHz. The codes are:

CLKPR = 0b10000000;
CLKPR = 0b00000100;

LOL, what a mistake! I forgot to include the timer init function :slight_smile: so sorry.

But when I included it in the setup function, it worked and also I can control TIMER0 too.

Here’s my code:

void setup() {
  I2C_init();
  LCD_Init();
  TCCR0B = 0x02;
}

void loop() {
TCNT0=0;
_delay_us(100);
num = (TCNT0/2);
itoa(num,str_arr,10);
LCD_string(str_arr);
_delay_ms(1000);
clr_dis();
}

With this setup, the Atmega is running at 16MHz, so instruction cycle should be 62.5ns, prescaler is Fosc/8 so the timer should run at 0.5us

Measuring 100us delay, I should get 200, which is what I have right now on the LCD, dividing the timer result by 2 I should get 100!

Another interesting performance aspect I noticed is that implementing:

while(m<100){m++;}

Instead of

_delay_us(100);

Changes the results, I get 50 timer results with the while loop instead of the actual 100 for the _delay_us.

So the incrementing process takes an extra CPU clock, I think AVR-GCC _delay_us/ms functions apply timers for their functionality.

I’ve done my DH11 timings test and the results are impressive!

I got the precise timings as expected, I couldn’t get the same results with my PIC18F4550, I don’t know why.

The PIC18F4550 worked well for measuring the IR sensor VS1838b received bits, but didn’t with the DH11! I don’t know why.

This is the code:

void DH11_init(void)
{
  _delay_ms(2000);
  TCCR0B = 0x02;	// enable timer0
}

void DH11_read(uint8_t *bits_timing)
{
	uint8_t i;
	DDRB = 0xFF;		            // Pin0 output
	PORTB &= ~(1<<PB0);
	_delay_ms(18);
	PORTB |= (1<<PB0);
	DDRB = 0xFE;                        // Pin0 input

	TCNT0=0;
	while((PINB & (1<<PINB0)));        // measuring these pulses for testing purposes
	bits_timing[0]=TMR0_MSK;

	TCNT0=0;
	while(!(PINB & (1<<PINB0)));       // DH11 LOW 80us response
	bits_timing[1]=TMR0_MSK;

	TCNT0=0;
	while((PINB & (1<<PINB0)));        // DH11 HIGH 80us response
	bits_timing[2]=TMR0_MSK;	

	for (i=3;i<43;i++)
    {
        while(!(PINB & (1<<PINB0)));       // wait for 0 leading bit
        TCNT0=0;
        while(PINB & (1<<PINB0));          // high bit 0 is 24us or 1 is 70us
        bits_timing[i] = TMR0_MSK;
    }
}

I have used few libraries for DHT11 Sensor where the temperature and humidity readings show only the integer part of the variables. But, the data sheet says that the value is: 8-bit integer + 8-bit decimal from which I wish to infer that the variable has a fractional part. As you have been able to measure the pulse duration of the DHT11's response, you will be able to formulate a simple algorithm to show the value of the variable (temperature/humidity) in floating point format.