2019-10-17 12:40 PM
I'm trying to use DHT22(temperature and humidity sensor). I'm using STM32F030F4 Here is it's datasheet DHT22 Datasheet
In first few seconds. I can get values. But after a while it stucks in here:
So i try to implement a timeout to prevent this. I start another timer (TIM14). And after 2 seconds i try pull the pin to low manually.
But as a result, variable 'k' (which is in the HAL_TIM_PeriodElapsedCallback function) never increments. So, again code stucks in same line. Could you help me, how can i implement a timeout to pull the pin low after a while
Here is the link of datasheet:https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim14;
/* USER CODE BEGIN PV */
uint8_t Rh_byte1, Rh_byte2, Temp_byte1, Temp_byte2;
uint16_t sum, RH, TEMP;
uint8_t check = 0;
uint8_t volatile k=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM14_Init(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void DHT22_start (void)
{
set_gpio_output (); // set the pin as output
HAL_GPIO_WritePin (GPIOA, GPIO_PIN_2, 0); // pull the pin low
delay_us(500); // wait for 500us`
HAL_GPIO_WritePin (GPIOA, GPIO_PIN_2, 1); // pull the pin high
delay_us(30); // wait for 30us
set_gpio_input (); // set as input
}
void check_response (void)
{
delay_us(40);
if (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2)))
{
delay_us (80);
if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2))) check = 1;
}
while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2))); // wait for the pin to go low
}
uint8_t read_data (void)
{
uint8_t i,j,k=0;
for (j=0;j<8;j++)
{
while (!(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2))); // wait for the pin to go high
delay_us(40); // wait for 40 us
if ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2)) == 0) // if the pin is low
{
i&= ~(1<<(7-j)); // write 0
}
else i|= (1<<(7-j)); // if the pin is high, write 1
HAL\_TIM\_Base\_Start(&htim14); //start timer
while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2))); //code stucks in here
HAL_TIM_Base_Stop(&htim14); //stop timer
}
return i;
}
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PA1 */
void set_gpio_input (void)
{
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/*Configure GPIO pin : PA2 */
void set_gpio_output (void)
{
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void delay_ticks(uint32_t ticks)
{ //SYSTICK TIMER 24 BIT
SysTick->LOAD = ticks;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK_DIV8;
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
// COUNTFLAG is a bit that is set to 1 when counter reaches 0.
// It's automatically cleared when read.
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
SysTick->CTRL = 0;
}
void delay_us(uint32_t us)
{
delay_ticks(us * 8); //8 e boldun
}
static inline void delay_ms(uint32_t ms)
{
delay_ticks(ms * 8000); //8 e boldun
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM3)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_4);
DHT22_start ();
check_response ();
Rh_byte1 = read_data ();
Rh_byte2 = read_data ();
Temp_byte1 = read_data ();
Temp_byte2 = read_data ();
sum = read_data();
TEMP = ((Temp_byte1<<8)|Temp_byte2);
RH = ((Rh_byte1<<8)|Rh_byte2);
}
if(htim->Instance == TIM14)
{
k++; //it never increments
if(k==2) //if it reaches two seconds pull the pin to low
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
k=0;
}
}
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim14);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief TIM3 Initialization Function
* @param Nonelara
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 7999;
htim3.Init.CounterMode = TIM_COUNTERMODE_DOWN;
htim3.Init.Period = 3999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
}
/**
* @brief TIM14 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 7999;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 999;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2|GPIO_PIN_4, GPIO_PIN_RESET);
/*Configure GPIO pin : PA1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PA2 PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
Solved! Go to Solution.
2019-10-18 06:25 AM
You'd need some secondary test so it actually leaves the loop at some point, Perhaps via an iteration count, or inspecting the TIM CNT to determine a maximum for elapsed time. ie 20 or 40 ms, whatever is reasonable for the sensor.
Also be aware that callbacks are operating in interrupt context, if they block they will prevent other interrupts from firing.
2019-10-17 01:13 PM
Perhaps you should handle the case where the device doesn't respond? Like having a timeout and retrying rather than loop infinitely. If you sense this case you could set a GPIO to trigger an analyser to inspect the situation in more detail.
Your ms delay is same as us delay, might want to pause longer between probes.
2019-10-18 05:11 AM
thanks. i fixed my delay. I tried to implement a timeout. But still it stcuks on line 67. Can you take a look again, please?
2019-10-18 06:25 AM
You'd need some secondary test so it actually leaves the loop at some point, Perhaps via an iteration count, or inspecting the TIM CNT to determine a maximum for elapsed time. ie 20 or 40 ms, whatever is reasonable for the sensor.
Also be aware that callbacks are operating in interrupt context, if they block they will prevent other interrupts from firing.
2019-10-18 06:56 AM
thank you. i added these two lines and now it works:
uint32_t ilk = TIM3->CNT;
while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2 && (( TIM3->CNT - ilk) < 8000) )));
uint32_t ilk = TIM3->CNT;
while ((HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_2 && (( TIM3->CNT - ilk) < 8000) )));