cancel
Showing results for 
Search instead for 
Did you mean: 

Using DHT22(AM2302) sensor

ArminAmarr
Associate II

Hi,

I'm looking for some example how to use the sensor with STM32 and wonder why all of them, which I've found, are based on the loop not on interrupts.

The response is 40 bits and it takes up to several milliseconds to read it, so during the time MCU is either hanging (if interrupts are disabled) or can miss some bits (if some other interrupt is handled for >24us or, if using RTOS, some other task is started e.g.).

Could you please help me and suggest a good example of using the sensor or advice if I'm wrong and it's senseless for use interrupts for it (I mean to catch failing and rising edges from the sensor and fill an array by "their times").

Thanks in advance!

6 REPLIES 6

Perhaps use a TIM interrupt, and increase the frequency until you reach the saturation point of your processor. Then tell me if that is accommodative of your concept.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal

Well, humidity sensors are very slow, they usually can't measure any faster than once per second.

There are many ways to implement something which is more HW assisted.

First, decide when/how you will read each bit, precise time once, 3 times to filter glitches?

Use a timer channel 1 or 2 connected to a pin, and make the timer overflow longer than the time it takes to perform a full measurement transmission.

Set the output compare to have the exact times you need an interrupt to change the output level or read the input pin level.

This will be the basic to build from.

Take the nucleo timer compare example with interrupt as starting point.

Hi,

Thanks for your reply, could you please have a look at the code, I've tried to implement?

2 physical pins are connected to the one-wire sensor:

PB5 - GPIO in Open drain mode.

PA6 - TIM3_CH1 in Input capture mode.

It seems it works as expected, I'm just trying to find a way how to improve it and get rid of using 2 physical pins.

I'm afraid to use Output compare as it works in push-pull mode and it's possible (because of any mistake, MCU failure) to burn the pin if MCU will have the High state at the pin but the sensor will try to output 0 e.g.

Should I use the single pin in GPIO OD mode and then switch it to TIM IC mode like in the code below or maybe you can advice another way how it's possible to do?

___disableIRQ();

Change the pin type from GPIO OD to TIM IC and start DMA using registers.

After the bus is released there is only 20us to complete with it not to miss sensor response.

___enableIRQ();

void vReadAM2301SensorTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
   uint32_t data[84];
  /* Infinite loop */
  for(;;)
  {
	// >2 sec delay should be between requests and for the initial warming-up
	osDelay(3000);
 
	// Send the request to the sensor
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
	osDelay(1);
 
	// Start reading data using DMA
	HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_1, data, 84);
 
	// Release a bus (should be done in 1-20 ms after the request)
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
 
        // Wait for 10ms and stop DMA
	osDelay(10);
	HAL_TIM_IC_Stop_DMA(&htim3, TIM_CHANNEL_1);
 
	// Parse, verify and publish data...

Thanks in advance!

nowave7
Associate II

Hi Armin,

I've been trying to setup this sensor with the STM32F103RB board, but have found only two, relatively old examples, and all of the used structures and functions have changed significantly since. I could go through all of the and have and have them updated to the current board support package, but then, knowing that at least the software works would be nice. Could you post your solution in short, if it's not too much to ask?

Thank you very much!

Hi Nowave7,

Of course, please my my solution on https://bitbucket.org/aiotko/stm32tests/src/master/NucleoH743ZI2Sensors/

Beware - in the test project I use unsigned integers and output the raw data only without any post-processing after verifying the checksum.

I.e. don't care about temperature below zero and don't divide the value by 10, e.g. just output 269 instead of 26.9 deg. or 32869‬ (0b1000000001100101) instead of -10.1deg.

You are welcome!

Hey Armin,

This is great to get me started. I'm sure these details are not going to make me any problems.

Thank you very much once more!