cancel
Showing results for 
Search instead for 
Did you mean: 

Function return value problem to the FreeRTOS task

USolar
Associate III

Hi All!
I'm doing a project on the STM32F429 discovery board.
In this project, I've used the TouchGFX.
Also, I'm using the FreeRTOS. The idea is to read the Temperature sensors and read their values to the TextAreas in TouchGFX.
TouchGFX was tested and working well.
First, I created, for this purpose separate task in the main.c file.

 

extern xQueueHandle messageQ;
unsigned int val=0;
/* USER CODE END Header_StartsecondTask */
void StartsecondTask(void *argument)
{
  /* USER CODE BEGIN StartsecondTask */
  /* Infinite loop */

  for(;;)
  {
	//val=One_Wire_Reset(Td_GPIO_Port, Td_Pin);		// <<==RESET Function Test
	//val++;		//  <<==TEST COUNTER
	val=temp_18b20(Td_GPIO_Port, Td_Pin, RESOLUTION_9BIT);
	val=(val/16);
	xQueueSend(messageQ,&val,0);
	HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
	osDelay(100);

  }
  /* USER CODE END StartsecondTask */
}

 

For testing, I used a simple counter, to check how it is working in TouchGFX.
Everything was working fine, I could read the counter increasing value in TouchGFX on the Discovery board Display.

Then I wanted to replace the mentioned above counter with Temperature sensor reading Values.
For this purpose, I've used functions from separate library.
I'm using the 1-Wire protocol's DS18B20 Temperature sensor.
In my previous projects, I've used this Library and it was working well (Code listing below).

 

#include "main.h"
#include "stm32f4xx_hal.h"
#include "delay_us.h"
#include "DS18B20.h"

#define SKIP_ROM	0xCC
#define CONVERT_T	0x44
#define READ_SCRATCHPAD	0xBE
#define WRITE_SCRATCHPAD	0x4E
#define COPY_SCRATCHPAD		0X48
#define RESOLUTION_9BIT		0x1F	// 93.75ms max conversion time
#define RESOLUTION_10BIT	0x3F	// 187.5ms max conversion time
#define RESOLUTION_11BIT	0x5F	// 375ms max conversion time
#define RESOLUTION_12BIT	0x7F	// 750ms max conversion time



//**************************************************************************************
//******Reset pulse to the line*********************************************************
char One_Wire_Reset(GPIO_TypeDef* GPIOx, uint8_t GPIO_Pin)
{
	char reset_status;
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
	Delay_us(480);
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
	Delay_us(65);
	if(!HAL_GPIO_ReadPin(GPIOx, GPIO_Pin))
	{reset_status=1;	}
	else
	{reset_status=0;	}
	Delay_us(480);
	return reset_status;
}
//**************************************************************************************
//******Write bit function**************************************************************
void One_Wire_Write_Bit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, char bit)	//
{
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
	Delay_us(5);
	if(bit)
	{HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);	}
	Delay_us(65);
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
}
//**************************************************************************************
//******Write byte function*************************************************************
void One_Wire_Write_Byte(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, unsigned char WData)
{	for(char i=0;i<8;i++)
	{	One_Wire_Write_Bit(GPIOx, GPIO_Pin, WData>>i&1);
	}
}
//**************************************************************************************
//******Read bit function***************************************************************
char One_Wire_Read_Bit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{	char One_Wire_Read=0;
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
	Delay_us(5);
	HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
	Delay_us(10);
	if(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin))
	{One_Wire_Read=1;	}
	else
	{One_Wire_Read=0;	}
	//One_Wire_Read=(HAL_GPIO_ReadPin(LED_GPIO_Port, LED_Pin)?1:0);
	Delay_us(45);
	return One_Wire_Read;
}
//**************************************************************************************
//******Read byte function**************************************************************
unsigned char One_Wire_Read_Byte(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{	char data=0;
	for(char i=0;i<8;i++)
	{	data|= One_Wire_Read_Bit(GPIOx, GPIO_Pin)<<i;	}
	return data;
}
//**************************************************************************************
//******DS18B20 Main Temperature Convert Function***************************************
int  temp_18b20(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,uint8_t RESOLUTION)
{	char LSB=0;
	char MSB=0;
	int ds18_temp=0;
	if(One_Wire_Reset(GPIOx, GPIO_Pin)==1)
	{
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, SKIP_ROM);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, CONVERT_T);
		switch(RESOLUTION)
		{
			case RESOLUTION_9BIT:
				HAL_Delay(95);		// 93.75ms max conversion time
			break;
			case RESOLUTION_10BIT:
				HAL_Delay(190);		// 187.5ms max conversion time
			break;
			case RESOLUTION_11BIT:
				HAL_Delay(380);		// 375ms max conversion time
			break;
			case RESOLUTION_12BIT:
				HAL_Delay(770);		// 750ms max conversion time
			break;
		}
		//HAL_Delay(850);
		One_Wire_Reset(GPIOx, GPIO_Pin);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, SKIP_ROM);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, READ_SCRATCHPAD);
		//-----Reading from 1-wire line-------------
		LSB = One_Wire_Read_Byte(GPIOx, GPIO_Pin);
		MSB = One_Wire_Read_Byte(GPIOx, GPIO_Pin);
		ds18_temp =(int)((MSB<<8)|LSB);
	}
	return ds18_temp;;
}

void ds18b20_RES_CONFIG(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t RESOLUTION)
{	//*********DS18B20_Configuration_Function*******************************
		One_Wire_Reset(GPIOx, GPIO_Pin);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, SKIP_ROM);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, WRITE_SCRATCHPAD);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, 0);					//TH
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, 0);					//TL
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, RESOLUTION);			//Desired Resolution
		One_Wire_Reset(GPIOx, GPIO_Pin);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, SKIP_ROM);
		One_Wire_Write_Byte(GPIOx, GPIO_Pin, COPY_SCRATCHPAD);
		HAL_Delay(12);
	//**********************************************************************
}

 

BUT, instead of Temperature readings, I have 0xFF value all the time.
Then I've checked the Sensor's data pin on logic analyzer.
I could read the 1-Wire Communication routine on the sensor, and actual temperature data as well (picture below).

Analyzer_Cmd.pngAnalyzer_Data.png

So, that's means, that the sensor operating well and I cannot receive any data from the sensor's convert Function.
Now, I'm stuck. What could be wrong with my ds18b20 Library, with its main conversion function?
I tried to check the Sensor's reset function and found it was working ok.
Maybe, I missed something in FreeRTOS Tasks procedures?
I would greatly appreciate any help!

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

FreerRTOS will mess with the timing of software-timed 1-wire transfers.  Depending on interrupts and other task priorities your Delay_us() calls could be much much longer if a task switch or interrupt happens during your Delay_us(5) when the GPIO pin is low.  That would cause the temperature chip to reset/reboot in the middle of the transaction.

For example, the "reset" pulse looks to be almost 1ms wide, not the 480us that you expect.  I don't know that the 1-wire protocol specifies as max "low" time, but that looks suspicious.

In the 2nd image you posted, I see the labels above the last 2 bytes saying 0x88 and 0x01 but the data lines do not look like that data (to my eyeballs).

 

View solution in original post

3 REPLIES 3
Bob S
Principal

FreerRTOS will mess with the timing of software-timed 1-wire transfers.  Depending on interrupts and other task priorities your Delay_us() calls could be much much longer if a task switch or interrupt happens during your Delay_us(5) when the GPIO pin is low.  That would cause the temperature chip to reset/reboot in the middle of the transaction.

For example, the "reset" pulse looks to be almost 1ms wide, not the 480us that you expect.  I don't know that the 1-wire protocol specifies as max "low" time, but that looks suspicious.

In the 2nd image you posted, I see the labels above the last 2 bytes saying 0x88 and 0x01 but the data lines do not look like that data (to my eyeballs).

 

MM..1
Chief III

Your library is writed for use without multithread or long ISR code. You can try rewrite it based on timer or record with DMA and then decode. But more simpler is thermal sensors with ADC I2C or an supported bus on MCU

Thank you for your reply!

The data has 2 last bytes, 0x88 and 0x01. LSB is going first. So, the temperature data is 0x0188, which is 392 in dec. To get the temperature, I need 392/16=24.5C. Which is actual temperature in my room.

With time delays, you are right. After analyzing, I noticed one issue. All delays of Delay_us() function, are twice longer as supposed to be, exactly twice. The HAL_Delay() doesn't has such issue and long as supposed to be.

So, all delays of Delay_us() function I divided by 2. After that, I succeeded to read the temperature on the Display. The timings on analyzer became correct.

Looks like, the sensor was converting the temperature, but the function couldn't read it because of the incorrect timings.

I need to reconsider my Delay_us() function.

Anyway, thank you once again for help.