Why is there no blink and why does the delaytime is not chancing?

Hello,

Im busy with another challenge of the YT course.
im trying to make code so that the user can enter a number which is put on a queue after the enter.
A second task schould read the queue and chancing the rate in which the builtin led is blinking

But I ran into 2 problems.
First the led is not blinking at all.
Second if I try to change the rate the second time , it seems that the change is not picked up with the second task at all.

Can anyone give me some hints how to solve this ?

Code so far : https://wokwi.com/projects/440717381141203969

What did you try to fix your problems so far ?

I did a Serial print of what the delayTime is at the moment and I saw that it is every time the same value which I do not understand why.

So I ask here for some hints where to look

Edit 1 : oke, so the first problems is solved by adding this :

memset(buff, 0, 20);
        idx = 0 ; 

Why the led is not blinking , I do not have a idea how to solve that.

I also changed the board to a board which has a led but still no luck

You need to have a separate task which blinks the LED and you need to yield in the enterBlinkRate task to ensure that it does not hog the CPU. Here is a working solution:

#if CONGIG_FREETOS_UNICORE
static const BaseType_t app_cpu = 0 ;
#else
static const BaseType_t app_cpu = 1;
#endif

static const uint8_t msg_queue_len = 5;
static portMUX_TYPE my_spinlock = portMUX_INITIALIZER_UNLOCKED;

static QueueHandle_t msg_queue;
static const int led_pin = 2;

int blinkRate = 500;

void enterBlinkRate(void * parameter) {
  char ch;
  char buff[20];
  int idx = 0;
  int enteredDelayTime;

  while (1) {
    //clear the buffer
    if (Serial.available() > 0) {
      ch = Serial.read();
      if (ch == '\n') {

        enteredDelayTime = atoi(buff);
        memset(buff, 0, 20);
        idx = 0;

        if (xQueueSend(msg_queue, (void *) &enteredDelayTime, 10) != pdTRUE) {
          Serial.println("Queue full");
        }

      } else {
        if (idx < 20) {

          buff[idx] = ch;
          idx++;
        }
      }
    }
     vTaskDelay(10 / portTICK_PERIOD_MS );
  }
}

void changeBlinkRate(void * parameters) {

  int enteredDelayTime;
  while(1) {
    if (xQueueReceive(msg_queue, (void *)&enteredDelayTime, portMAX_DELAY) == pdTRUE) {
      /* Ensure serialization while updating the global variable. */
      taskENTER_CRITICAL(&my_spinlock);
      blinkRate = enteredDelayTime;
      taskEXIT_CRITICAL(&my_spinlock);
    }
  }
}

void ledBlinkTask(void * parameters) {
  while(1)
  {
    digitalWrite(led_pin, HIGH);
    vTaskDelay(blinkRate / portTICK_PERIOD_MS );
    digitalWrite(led_pin, LOW);
    vTaskDelay(blinkRate / portTICK_PERIOD_MS);
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(led_pin, OUTPUT);

  // Wait a moment to start (so we don;t miss Serial output)
  vTaskDelay(1000 / portTICK_PERIOD_MS);
  Serial.println();
  Serial.println("----FreeRTOS QUEUE Challenge ----");

  msg_queue = xQueueCreate(msg_queue_len, sizeof(int));

  xTaskCreatePinnedToCore(enterBlinkRate,
                          "Enter blink rate",
                          1024,
                          NULL,
                          1,
                          NULL,
                          app_cpu
  );

  xTaskCreatePinnedToCore(changeBlinkRate,
                          "Change blink rate",
                          1024,
                          NULL,
                          1,
                          NULL,
                          app_cpu
  );

  xTaskCreatePinnedToCore(ledBlinkTask,
                          "LED blink task",
                          1024,
                          NULL,
                          1,
                          NULL,
                          app_cpu
  );
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
}

Thanks for showing me but mutex is explained in the next chapter.
This was a challenge to practice with queue’s .

So my solution is :

static const uint8_t msg_queue_len = 5;



static QueueHandle_t msg_queue;
static const int led_pin = 2; 

void enterBlinkRate(void * parameter) {
  char ch;
  char buff[20];
  int idx = 0;

  
  while (1) {
    //clear the buffer
    int delayTime ; 
    if (Serial.available() > 0) {
      ch = Serial.read();
      if (ch == '\n') {
        buff[idx] = '\0';
        delayTime = atoi(buff);

        if (xQueueSend(msg_queue, (void *) &delayTime, 10) != pdTRUE) {
          Serial.println("Queue full"); 
        }

        idx = 0 ; 
        

      } else {
        if (idx < 3) {
           
          buff[idx] = ch;

                 
          idx++;
        }
      }
    } else {
      vTaskDelay(10 / portTICK_PERIOD_MS);
    }
  }
}

void changeBlinkRate(void * parameters) {

  int rate = 500; 
  while(1) {
    int newValue; 
    if (xQueueReceive(msg_queue, (void *)&newValue,0) == pdTRUE) {
    rate = newValue; 
    }

    
      digitalWrite(led_pin, HIGH);
      vTaskDelay(rate / portTICK_PERIOD_MS ); 
      digitalWrite(led_pin, LOW); 
      vTaskDelay(rate / portTICK_PERIOD_MS);

    //wait before trying again 
    //vTaskDelay(1000 / portTICK_PERIOD_MS); 
  }
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(led_pin, OUTPUT); 
  
  // Wait a moment to start (so we don;t miss Serial output)
  vTaskDelay(1000 / portTICK_PERIOD_MS); 
  Serial.println(); 
  Serial.println("----FreeRTOS QUEUE Challenge ----"); 

  msg_queue = xQueueCreate(msg_queue_len, sizeof(int)); 

  xTaskCreate(enterBlinkRate,
                          "Enter blink rate", 
                          1024, 
                          NULL, 
                          1, 
                          NULL 
                         
  ); 

  xTaskCreate(changeBlinkRate,
                          "Change blink rate", 
                          1024, 
                          NULL, 
                          1, 
                          NULL 
                          
  ); 
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
}

I hope it is also good ?