I'm trying to send the array that we get through UART and passing the array to the "hex_to_bin" function. The data received is perfect and this is also passed to the queue. I want only one byte at a time so that I can extract bit from it in the "turn_on_off" task and perform the timer functions. I used binary semaphore thinking that queue will wait and send the data, bit extraction is done successfully but I can't process timer functions. Please help me in this regard.
#include "main.h"
QueueHandle_t data_queue;
void turn_on_off(void *pvParameters)
{
uint8_t bit;
int data_index = 0;
timer_start(TIMER_GROUP, TIMER_INDEX);
gpio_set_level(GPIO_NUM_2, true);
int bit_check = 0;
int prev_bit_check;
UartDataStruct UartDataStruct_Onewire;
timer_set_counter_value(TIMER_GROUP, TIMER_INDEX, 0);
while (true)
{
if ((xQueueReceive(data_queue, &UartDataStruct_Onewire, portMAX_DELAY) == pdPASS))
{
// printf("Received data is : %s | len : %d\r\n",&UartDataStruct_Onewire.UartDataBuffer[0],UartDataStruct_Onewire.len);
timer_set_counter_value(TIMER_GROUP, TIMER_INDEX, 0);
while (true)
{
timer_get_counter_value(TIMER_GROUP, TIMER_INDEX, &task_counter_value);
// printf("Task counter value: %lld",task_counter_value);
if (bit_check == 0)
{
if (task_counter_value > 200000) // 1000 count per ms
{
gpio_set_level(GPIO_NUM_2, false);
if (task_counter_value > 256000)
{
gpio_set_level(GPIO_NUM_2, true);
bit_check++;
timer_set_counter_value(TIMER_GROUP, TIMER_INDEX, 0);
}
}
}
else
{
for (data_index = 0; data_index < UartDataStruct_Onewire.len - 1; data_index++)
{
for (int itr = 7; itr >= 0; itr--)
{
bit = (UartDataStruct_Onewire.UartDataBuffer[data_index] >> itr) & 0x01;
// ESP_LOGI("Onewire","Bit extracted: %d", bit);
if (bit == 1)
{
for (prev_bit_check = bit_check; bit_check > prev_bit_check;)
{
if (task_counter_value > 30000) // 1000 COUNT PER ms
{
gpio_set_level(GPIO_NUM_2, false);
if (task_counter_value > 38000)
{
gpio_set_level(GPIO_NUM_2, true);
bit_check++;
timer_set_counter_value(TIMER_GROUP, TIMER_INDEX, 0);
}
}
}
}
else
{
for (prev_bit_check = bit_check; bit_check > prev_bit_check;)
{
if (task_counter_value > 6000) // 1000 COUNT PER ms
{
gpio_set_level(GPIO_NUM_2, false);
if (task_counter_value > 26000)
{
gpio_set_level(GPIO_NUM_2, true);
bit_check++;
timer_set_counter_value(TIMER_GROUP, TIMER_INDEX, 0);
}
}
}
}
}
printf("---------------\r\n");
}
}
if (data_index == UartDataStruct_Onewire.len - 1)
{
bit_check = 0;
break;
}
}
}
}
}
Considering the information from the comments vTaskDelay is your friend here (you finally can drop the timer entirely):
xSemaphoreTake(data_semaphore, portMAX_DELAY);
// side note: you do not handle the case of the semaphore NOT having been taken!
// assuming setting to low switches the LED on – if not, invert the values!
gpio_set_level(GPIO_NUM_2, false);
vTaskDelay(200 / portTICK_PERIOD_MS); // see documentation
gpio_set_level(GPIO_NUM_2, true);
vTaskDelay(56 / portTICK_PERIOD_MS);
for(bits...)
{
if(bit == 1)
{
onTime = 30;
offTime = 8;
}
else
{
onTime = 6;
offTime = 20;
}
gpio_set_level(GPIO_NUM_2, false);
vTaskDelay(onTime / portTICK_PERIOD_MS);
gpio_set_level(GPIO_NUM_2, true);
vTaskDelay(offTime / portTICK_PERIOD_MS);
}
xSemaphoreGive(data_semaphore);
Note: Totally untested code, if you find a bug please fix yourself.