Skip to main content
This topic has been closed for replies.

4 replies

Eleon BORLINI
ST Employee
March 1, 2021

Hi @M abouhasem​ ,

I've added STM32 topics since I'm expert only of ST sensors and DHT11/DHT22 are not from ST.

I see that these sensors uses a Serial Interface (Single-Wire Two-Way) communication protocol: you can find a description of the use of the SWPMI interface on the H7 MCU family at this link (pdf) or this other link (video).

You can find examples on the use of the SWPMI in the STM32Cube MCU Package for STM32F7 and STM32H7 series (drivers in the HAL layer).

-Eleon

Andrew Neil
Super User
March 1, 2021

"I see that these sensors uses a Serial Interface (Single-Wire Two-Way) communication protocol"

 

Most of these "single-wire" protocols are proprietary - did you see any reason to believe that the specific protocol used by these sensors is compatible with the SWPMI on the H7 ?

 

@M abouhasem​ - Being proprietary, it is quite likely that any code you find on the interwebs will be bit-banging it, therefore that should be easy to port to any other microcontroller - the only bits specific to the particular microcontroller would be:

  1. How to pull a pin low;
  2. How to release a pin (Hi-Z);
  3. How to read the state of a pin;
  4. How to define the timing
A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Eleon BORLINI
ST Employee
March 1, 2021

Hi @Andrew Neil​ ,

No, I'm not sure, that has to be checked

I'm not an expert, that's why I added STM32 topics for support from my colleagues.

The bit-banging approach is anyway an solution, maybe a little tricky but effective.

-Eleon

Andrew Neil
Super User
March 1, 2021

As with any other sensor, the sensor itself neither knows nor cares what microcontroller you use; all it sees is what happens on the wires - so what you need to do is to program your microcontroller - whatever it is - to generate the appropriate levels with the appropriate timings as specified in the sensor's documentation.

http://www.8052mcu.com/forum/read/160143

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
M abouhasem
Associate II
March 2, 2021

@Andrew Neil​ 

I used that code with stm32f4 and stm32f0 and it worked fine I have used it with both F7 and H7 MCU and they couldn't fetch a response I have tried with both modes Pullup pin and No pull. then I tried it with timer input capture mode with Kindly review the sequence of Code below.

#include "main.h"
#include "string.h"
 
 
TIM_HandleTypeDef htim2;
 
UART_HandleTypeDef huart3;
 
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
uint16_t g[100];
 
void delay (uint16_t time)
{
	/* change your code here for the delay in microseconds */
 
	__HAL_TIM_SET_COUNTER(&htim2, 0);
	while ((__HAL_TIM_GET_COUNTER(&htim2))<time);
}
 
uint8_t Rh_byte1, Rh_byte2, Temp_byte1, Temp_byte2;
uint16_t SUM, RH, TEMP;
 
float Temperature = 0;
float Humidity = 0;
uint8_t Presence = 0;
 
void Set_Pin_Output (GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}
 
void Set_Pin_Input (GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}
 
void DHT11_Start (void)
{
	Set_Pin_Output(DHT22_GPIO_Port, DHT22_Pin); // set the pin as output
	HAL_GPIO_WritePin (DHT22_GPIO_Port, DHT22_Pin, 0); // pull the pin low
	delay (18000); // wait for 18ms
 HAL_GPIO_WritePin (DHT22_GPIO_Port, DHT22_Pin, 1); // pull the pin high
	delay (20); // wait for 20us
	Set_Pin_Input(DHT22_GPIO_Port, DHT22_Pin); // set as input
}
 
uint8_t DHT11_Check_Response (void)
{
	uint8_t Response = 0;
	delay (40);
	if (!(HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin)))
	{
		delay (80);
		if ((HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin))) Response = 1;
		else Response = -1; // 255
	}
	while ((HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin))); // wait for the pin to go low
 
	return Response;
}
 
uint8_t DHT11_Read (void)
{
	uint8_t i,j;
	for (j=0;j<8;j++)
	{
		while (!(HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin))); // wait for the pin to go high
		delay (40); // wait for 40 us
		if (!(HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin))) // if the pin is low
		{
			i&= ~(1<<(7-j)); // write 0
		}
		else i|= (1<<(7-j)); // if the pin is high, write 1
		while ((HAL_GPIO_ReadPin (DHT22_GPIO_Port, DHT22_Pin))); // wait for the pin to go low
	}
	return i;
}
 
int main(void)
{
 
 
 HAL_Init();
 
 SystemClock_Config();
 MX_GPIO_Init();
 MX_TIM2_Init();
 MX_USART3_UART_Init();
 /* USER CODE BEGIN 2 */
 HAL_TIM_Base_Init(&htim2);
 HAL_TIM_Base_Start_IT(&htim2);
 uint32_t i=0;
	char buffer[1999];
 
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	 HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
	 delay(50000);
	 DHT11_Start();
 // Set_Pin_Input(DHT22_GPIO_Port, DHT22_Pin); // set as input
	 Presence = DHT11_Check_Response();
	 Rh_byte1 = DHT11_Read ();
	 Rh_byte2 = DHT11_Read ();
	 Temp_byte1 = DHT11_Read ();
	 Temp_byte2 = DHT11_Read ();
	 SUM = DHT11_Read();
	 TEMP = Temp_byte1;
	 RH = Rh_byte1;
	 //Temperature = (float) TEMP;
	 // Humidity = (float) RH;
	 sprintf(buffer,"temp=%d.%d hum=%d.%d\n\r",Temp_byte1,Temp_byte2,Rh_byte1,Rh_byte2);
	 HAL_UART_Transmit(&huart3,buffer,strlen(buffer),1000);
	// HAL_Delay(1000);
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}
 
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
 /** Supply configuration update enable 
 */
 HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
 /** Configure the main internal regulator output voltage 
 */
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
 /** 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_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 1;
 RCC_OscInitStruct.PLL.PLLN = 120;
 RCC_OscInitStruct.PLL.PLLP = 2;
 RCC_OscInitStruct.PLL.PLLQ = 20;
 RCC_OscInitStruct.PLL.PLLR = 2;
 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
 RCC_OscInitStruct.PLL.PLLFRACN = 0;
 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_CLOCKTYPE_PCLK2
 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
 {
 Error_Handler();
 }
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_USB;
 PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;
 PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /** Enable USB Voltage detector 
 */
 HAL_PWREx_EnableUSBVoltageDetector();
}
 
 
 
 
 
 
static void MX_TIM2_Init(void)
{
 
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 
 htim2.Instance = TIM2;
 htim2.Init.Prescaler = 239;//timer APB1 timer perpherial 240 MHz 
 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim2.Init.Period = 0xFFFF;
 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 
 
}
 
/**
 * @brief USART3 Initialization Function
 * @param None
 * @retval None
 */
static void MX_USART3_UART_Init(void)
{
 
 
 huart3.Instance = USART3;
 huart3.Init.BaudRate = 115200;
 huart3.Init.WordLength = UART_WORDLENGTH_8B;
 huart3.Init.StopBits = UART_STOPBITS_1;
 huart3.Init.Parity = UART_PARITY_NONE;
 huart3.Init.Mode = UART_MODE_TX_RX;
 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart3.Init.OverSampling = UART_OVERSAMPLING_16;
 huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
 
 
}
 
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOB, LD3_Pin|LD2_Pin, GPIO_PIN_RESET);
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET);
 
 /*Configure GPIO pin : USER_Btn_Pin */
 GPIO_InitStruct.Pin = USER_Btn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);
 
 /*Configure GPIO pins : LD3_Pin LD2_Pin */
 GPIO_InitStruct.Pin = LD3_Pin|LD2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
 /*Configure GPIO pin : PD7 */
 GPIO_InitStruct.Pin = GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
}
 
void Error_Handler(void)
{
 
}
 #ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{ 
 
}
#endif
 

Ozone
Principal
March 2, 2021

If you already have a working platform, record the bus signals in both instances (F0/F4 vs. F7/H7), and compare them.

M abouhasem
Associate II
March 2, 2021

the same code worked fine with same sensor with both f4 and f0 MCUs as per datasheets its mandatory requirement to pullup and wait

0693W000007ZscSQAS.jpg

Andrew Neil
Super User
March 2, 2021

"the same code worked fine with same sensor with both f4 and f0 MCUs"

So, again, compare what happens with your working code against what happens with your non-working code - that will show you where it's going wrong.

"its mandatory requirement to pullup"

Did you read my previous reply?

"Pullup" means that you let the pullup resistor do the pulling - you do not want the controller to actively drive high.

It's exactly the same principle as used for I2C: the drivers only ever pull down - it's the pullup resistors which do the pulling up.

That's why you see the rounded rising edges:

0693W000007ZswqQAC.png 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate
March 8, 2024

Hello Andrew.

You have resolved a question that was giving me headaches. I was wondering after this, why this code wasn't working for me. I have this board and it already has installed a pull-up resistor. But the guy from controllerstech, was using the sensor without the board, so no pull-up is included. He actively set pin high, with HAL_GPIO_WRITE_PIN() function. But in my case, my datasheet shows a rounded edge as you mentioned. 

I had no idea this could affect, could you please tell me where to read more about this? Maybe I have to know something about electronics?

Thanks in advance.