Challenge 2 of the rtos course . What did I do wrong

Hello,

I have to make code that contains 2 tasks.
One that blink the build_in led with a delay
One that reads a number from the serial monitor that can change the delaytime of the built in led

So I have this :

// my solution to lesson 3 

// Learned so far 
// - writing task 
// - task scheduling 

// Challenge 

// Write 2 tasks. 
// On to display a led and one where a user can enter a number which delays the blinking 

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

// Pins 
static const int led_pin = 2;

int delayTime = 500; 

//Our task  blink a led 
void toggleLed(void * parameter) {
 while(1) {
   digitalWrite(led_pin, HIGH);
   vTaskDelay(delayTime / portTICK_PERIOD_MS ); 
   digitalWrite(led_pin, LOW); 
   vTaskDelay(delayTime / portTICK_PERIOD_MS);
 }
}

// Our task is to read in a number 
void changeBlinkRate(void * parameter) {
 char ch; 
 char buff[20];
 int idx; 

 //clear the buffer
 memset(buff, 0, 20);

 if (Serial.available() > 0) {
   ch = Serial.read();  

   if (ch == '\n') {
     delayTime = atoi(buff);
     Serial.print("Updated LED delay to: ");
     Serial.println(delayTime);

     // clear buffer 
     memset(buff, 0, 20);
     idx = 0 ; 
   } else {
     if (idx < 19) {
       buff[idx] = ch; 
       idx++;
     }
   }
}}



void setup() {
 pinMode(led_pin, OUTPUT); 
 Serial.begin(9600); 
 Serial.println("RW"); 

 // Task to run forever 
  xTaskCreatePinnedToCore(
   toggleLed,    // Function to be called
   "ToggleLed",  // name of the function 
   1024,         // stack size
   NULL,         // parameter to pass to the function 
   1,            // priority
   NULL ,        // task handle
   app_cpu
 );

 // Task to run forever 
  xTaskCreatePinnedToCore(
   changeBlinkRate,    // Function to be called
   "ChangeBlinkRate",  // name of the function 
   1024,         // stack size
   NULL,         // parameter to pass to the function 
   1,            // priority
   NULL ,        // task handle
   app_cpu
 );
}

void loop() {

}

But on wokwiki I do not see the serial monitor appear and the led does not blink.
So what I did not understand.

Till now I learned only about writing task and task priority

The `changeBlinkRate` task’s logic is incorrect; it’s not structured to continuously read from the serial port. It just runs once and returns.

Refer:

Tasks are normally implemented as an infinite loop; the function which implements the task must never attempt to return or exit.

Instead of the current logic, it should be an infinite loop similar to the LED task, where it checks for serial data and processes its once its available.

Still no luck with this change

// my solution to lesson 3

// Learned so far
// - writing task
// - task scheduling

// Challenge

// Write 2 tasks.
// On to display a led and one where a user can enter a number which delays the blinking

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

// Pins
static const int led_pin = 2;

int delayTime = 500;

//Our task  blink a led
void toggleLed(void * parameter) {
  while (1) {
    digitalWrite(led_pin, HIGH);
    vTaskDelay(delayTime / portTICK_PERIOD_MS );
    digitalWrite(led_pin, LOW);
    vTaskDelay(delayTime / portTICK_PERIOD_MS);
  }
}

// Our task is to read in a number
void changeBlinkRate(void * parameter) {
  char ch;
  char buff[20];
  int idx;

  while (1) {
    //clear the buffer
    memset(buff, 0, 20);

    if (Serial.available() > 0) {
      ch = Serial.read();

      if (ch == '\n') {
        delayTime = atoi(buff);
        Serial.print("Updated LED delay to: ");
        Serial.println(delayTime);

        // clear buffer
        memset(buff, 0, 20);
        idx = 0 ;
      } else {
        if (idx < 19) {
          buff[idx] = ch;
          idx++;
        }
      }
    }
  }
}



void setup() {
  pinMode(led_pin, OUTPUT);
  Serial.begin(9600);
  Serial.println("RW");

  // Task to run forever
  xTaskCreatePinnedToCore(
    toggleLed,    // Function to be called
    "ToggleLed",  // name of the function
    1024,         // stack size
    NULL,         // parameter to pass to the function
    1,            // priority
    NULL,         // task handle
    app_cpu
  );

  // Task to run forever
  xTaskCreatePinnedToCore(
    changeBlinkRate,    // Function to be called
    "ChangeBlinkRate",  // name of the function
    1024,         // stack size
    NULL,         // parameter to pass to the function
    1,            // priority
    NULL,         // task handle
    app_cpu
  );
}

void loop() {

}

Still no blinking and the serial monitor is not visible

I can see the LED blinking in the default scenario, how are you providing the serial input?

you are right.

I was assuming that this

Serial.begin(9600);
  Serial.println("RW");

take care that the serial monitor will pop up.

And if you mean the reading that will be this code :

if (Serial.available() > 0) {
      ch = Serial.read();

Which can be found in changeBlinkRate at the beginning

I don’t think it will automatically create a serial monitor, intead I think a serial monitro needs to be attached to your ESP32 via wokwi UI, I might be wrong here as I haven’t used wokwi before.

According to this it schould work :

oke

I asked also the wokwiki people for help and it seems that you have to change the connection string to

  "connections": [ [ "esp:TX0", "$serialMonitor:RX", "" ], [ "esp:RX0", "$serialMonitor:TX", "" ] ]

Still something wrong with the code
I now can enter some number but I cannot see that the blinkRate task is executed.

What is more wrong here in my code ?

oke

That one is solved but still delaytime is zero whatever I fill in in the serial monitor

Can someone give me a hint what is still wrong at my code

Your code seems to be working and it’s updating the `delayTime`, however wokwi seems to not be refreshing the LED status fast enough to see the blinks for higher blink frequencies (lower delayTime).

I can see the delay getting doubled when delayTime is set to 1000.

oke

and I found out that the delayTime was always zero because I did not give delayTime a value when I declared it.

For me this one is solved