File problem

I had added FreeRTOS to an embedded system project and no errors but when i put on a simulator, i got nothing ( atmega32 )

What do you mean “you get nothing?” What exactly happens? Also why do you entitle your question “file problem?” What file?

I got no results on the DC motor or LCD
file problem → maybe I have to change something on the atmega 323 file to work on the Atmega 32

I really don’t know

Sorry, but if you expect to get an answer, you need to provide at least some information. Does the OS start up at all, do any tasks run, do you see anything happening at all, are you stuck in a fault…

I can say the ATMega323 and 32 are compatible, the same build should work on both.

#include "main.h"

QueueHandle_t	 buffer;
xSemaphoreHandle tempSensor;

int main()
{
	LCD_init();
	TWI_init(0x20);

	vSemaphoreCreateBinary(tempSensor);
	buffer = xQueueCreate(10,sizeof(uint8));

	LCD_displayString("temp =      c");

	xTaskCreate(TWI_task,"TWI_task", 200,NULL,3, NULL);
	xTaskCreate(LCD_task,"LCD_task",200,NULL,2,NULL);
	vTaskStartScheduler();

	return 0;
}


void LCD_task(void *pv)
{
	uint8 TempSensor_value;
	uint8 temp_received;
	uint8 check_semaphore;
	while(1)
	{
		temp_received = xQueueReceive(buffer,&TempSensor_value,100);

		check_semaphore = xSemaphoreTake(tempSensor,300);
		if(check_semaphore == 1)
		{
			LCD_moveCursor(0,7);
			LCD_intgerToString((int)TempSensor_value);
			LCD_displayCharacter(' ');

			if(TempSensor_value >= 30)
			{
				displayStringRowColumn(1,3,"Fan On ");
			}

			else
			{
				displayStringRowColumn(1,3,"Fan Off");
			}

		}

		xSemaphoreGive(tempSensor);
		vTaskDelay(100);
	}
}


void TWI_task(void *pv)
{
	uint8 temp_value;
	uint8 check_semaphore;
	while(1)
	{
		check_semaphore = xSemaphoreTake(tempSensor,300);
		if(check_semaphore == 1)
		{
			TWI_receiveAddress();
			temp_value = TWI_readData();
			xQueueSend(buffer,&temp_value,50);
		}
		xSemaphoreGive(tempSensor);
		vTaskDelay(100);
	}
}

is there any problem with this code ?! sorry i’m not femiliar with OS

First of all, it looks as if you do not need the semaphore, the queue object itself should suffice for sync.

Then, can you verify that your task scheduler works at all? That is, verify that your sys tick handler is being invoked and every task gets to at least the head of its infinite loop?

1 Like

In addition to what @RAc mentioned, you should also check the return value of xQueueReceive before using TempSensor_value. In this case, you should remove the semaphore but otherwise, you should only give the semaphore if it was successfully taken. In other words, xSemaphoreGive call should be in if(check_semaphore == 1) block.

1 Like

this is the master code :

#include "main.h"

QueueHandle_t	 buffer;

int main(void)
{
	ADC_ConfigType ADC_configrations = {AREF,F_CPU_8};

	ADC_init (&ADC_configrations);
	DcMotor_init();
	TWI_init();


	buffer = xQueueCreate(10,sizeof(uint8));

	xTaskCreate(TempSensor_task,"Task1",300,NULL, 5, NULL);
	xTaskCreate(DCMotor_task,"Motor_Rotate",300,NULL,4,NULL);
	xTaskCreate(TWI_task,"TWI_sendData",300,NULL,3,NULL);
	vTaskStartScheduler();

	return 0;
}

void TempSensor_task(void* pv)
{
	uint8 TempSensor_value;

	while(1)
	{

		TempSensor_value = LM35_getTemperature ();
		xQueueSend(buffer,&TempSensor_value,50);

		vTaskDelay(150);
	}
}

void DCMotor_task(void *pv)
{
	uint8 TempSensor_value;

	while(1)
	{
		if( xQueueReceive(buffer,&TempSensor_value,100))
		{

			if(TempSensor_value >= 30 && TempSensor_value < 60)
			{
				DcMotor_rotate(DC_MOTOR_CW,25);
			}
			else if(TempSensor_value >= 60 && TempSensor_value < 90)
			{
				DcMotor_rotate(DC_MOTOR_CW,50);
			}
			else if(TempSensor_value >= 90 && TempSensor_value < 120)
			{
				DcMotor_rotate(DC_MOTOR_CW,75);
			}
			else if(TempSensor_value > 120)
			{
				DcMotor_rotate(DC_MOTOR_CW,100);
			}
			else
			{
				DcMotor_rotate(DC_MOTOR_STOP,0);
			}
		}

	}
	vTaskDelay(150);
}


void TWI_task(void *pv)
{
	uint8 TempSensor_value;
	while(1)
	{
		if(xQueueReceive(buffer,&TempSensor_value,100))
		{

			TWI_start(0x20);
			TWI_writeData(TempSensor_value);
			TWI_stop();

		}
		vTaskDelay(150);
	}
}

[RichardB - edited for formatting]

this for the slave :

 #include "main.h"

QueueHandle_t	 buffer;

int main()
{
	LCD_init();
	TWI_init(0x20);

	buffer = xQueueCreate(10,sizeof(uint8));

	LCD_displayString("temp =      c");

	xTaskCreate(TWI_task,"TWI_task", 200,NULL,3, NULL);
	xTaskCreate(LCD_task,"LCD_task",200,NULL,2,NULL);

	vTaskStartScheduler();

	return 0;
}


void LCD_task(void *pv)
{
	uint8 TempSensor_value;
	while(1)
	{
		if(xQueueReceive(buffer,&TempSensor_value,100))
		{

			LCD_moveCursor(0,7);
			LCD_intgerToString((int)TempSensor_value);
			LCD_displayCharacter(' ');

			if(TempSensor_value >= 30)
			{
				displayStringRowColumn(1,3,"Fan On ");
			}

			else
			{
				displayStringRowColumn(1,3,"Fan Off");
			}
		}
		vTaskDelay(200);

	}


	vTaskDelay(200);
}



void TWI_task(void *pv)
{
	uint8 temp_value;


	while(1)
	{
		TWI_receiveAddress();
		temp_value = TWI_readData();
		xQueueSend(buffer,&temp_value,50);
		vTaskDelay(200);
	}
}

[RichardB - edited for formatting]

Hi XV020,

The master code seems to have the following problems:

  • The vTaskDelay(150) of DCMotor_task is outside of the while loop. Since DCMotor_task has higher priority than TWI_task, TWI_task may not have the chance to receive from the queue.

  • Even if we put the vTaskDelay(150) of DCMotor_task inside of the while loop, we still need to consider the TempSensor_task enqueue frequency. If both DCMotor_task and TWI_task are waiting for the queue, DCMotor_task will be woken up due to higher priority. Since TempSensor_task, DCMotor_task and TWI_task are of same frequence ( delayed 150ms ), there is chance that TWI_task doesn’t get the chance to receive from the queue.

I understood what you have said very well and i already made it more simple without TWI at all, but I still don’t receive any result on the DCmotor or LCD.

look at this.

#include <util/delay.h>
#include "adc.h"
#include "lm35.h"
#include "dc_motor.h"
#include "lcd.h"
#include "avr/io.h"

#include "FreeRTOS V10.5.1/Include/FreeRTOSConfig.h"
#include "FreeRTOS V10.5.1/Include/FreeRTOS.h"
#include "FreeRTOS V10.5.1/Include/task.h"
#include "FreeRTOS V10.5.1/Include/semphr.h"
#include "FreeRTOS V10.5.1/Include/queue.h"

void MOTOR_rotate(void *p);
void sendTemperature(void *p);

TaskHandle_t myTask1Handle = NULL;
TaskHandle_t myTask2Handle = NULL;
TaskHandle_t myTask3Handle = NULL;

SemaphoreHandle_t xSemaphore;
QueueHandle_t	  buffer;

uint8 temp;

int main(void)
{

	ADC_ConfigType ADC_configrations = {AREF,F_CPU_8};
	ADC_init (&ADC_configrations);

	DcMotor_Init();
	LCD_init();

	LCD_displayString("temp =     c");

	vSemaphoreCreateBinary( xSemaphore );
	buffer = xQueueCreate(5,sizeof(uint8));

	xTaskCreate(MOTOR_rotate,"Task1",100,myTask1Handle,1, NULL);
	xTaskCreate(sendTemperature,"Task2",100,myTask2Handle,1, NULL);
	xTaskCreate(LCD_display,"Task3",100,myTask3Handle,1, NULL);

	vTaskStartScheduler();

	return 0;
}


void sendTemperature(void *p)
{
	uint8 temp;

	while(1)
	{
		xSemaphoreTake(xSemaphore, 100);

		temp = LM35_getTemperature ();

		xQueueSend(buffer, &temp, 50);

		xSemaphoreGive(xSemaphore);

		vTaskDelay(pdMS_TO_TICKS(200));
	}
}

void LCD_display(void *p)
{
	uint8 temp;
	while(1)
	{
		xSemaphoreTake(xSemaphore, 100);

		LCD_moveCursor(0,7);
		LCD_intgerToString((int)temp);
		LCD_displayCharacter(' ');

		if(temp >= 30)
		{
			displayStringRowColumn(1,3,"Fan On ");
		}

		else
		{
			displayStringRowColumn(1,3,"Fan Off");
		}
		xSemaphoreGive(xSemaphore);

		vTaskDelay(pdMS_TO_TICKS(200));

	}
}

void MOTOR_rotate(void *p)
{
	uint8 temp;

	while(1)
	{
		xSemaphoreTake(xSemaphore, 100);

		xQueueReceive(buffer,&temp,50);

		if(temp >= 30 && temp < 60)
		{
			DcMotor_Rotate(DC_MOTOR_CW,25);
		}
		else if(temp >= 60 && temp < 90)
		{
			DcMotor_Rotate(DC_MOTOR_CW,50);
		}
		else if(temp >= 90 && temp < 120)
		{
			DcMotor_Rotate(DC_MOTOR_CW,75);
		}
		else if(temp > 120)
		{
			DcMotor_Rotate(DC_MOTOR_CW,100);
		}
		else
		{
			DcMotor_Rotate(DC_MOTOR_STOP,0);
		}

		xSemaphoreGive(xSemaphore);

		vTaskDelay(pdMS_TO_TICKS(200));

	}
}

Your code is written VERY sloppily. You must positively check the return values of all FreeRTOS API calls, in particular the semaphore calls. If you call xSemaphoreTake with a timeout, you certainly want to distinguish between timeouting return and success return, otherwise your synchronization will not work as expected.

Also, you still have not answered the question whether your tasks execute at all.

I had checked all the returns but still get nothing, I will try again to check it but I don’t think it’s because of that.

yes, it execute but I think that it doesn’t get the temperature so the DCmotor didn’t work and the LCD didn’t display anything

You need to take a bit more systematic approach to debug this. Disable all the tasks and features and then enable them one by one to isolate the problematic part. Once you determine which part of your code is problematic, we can look into that more closely.

1 Like