簡體   English   中英

如何使用信號量從 Arduino 上的 FreeRTOS 中的串行端口讀取?

[英]How to read from Serial port in FreeRTOS on Arduino using Semaphores?

我正在嘗試根據從串行端口接收到的命令來控制閃爍的任務。 這個想法是從串行端口獲取 0 以使 LED 閃爍一次。

#include <Arduino_FreeRTOS.h>
#include <semphr.h>

// define tasks
void TaskReadFromSerial( void *pvParameters ); // Get commands
void TaskBlink( void *pvParameters ); // LED as actuator


//define smaphore handlers
SemaphoreHandle_t activateActuatorSem;

//define global variable
String input = "-1";

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect.
  }

  activateActuatorSem = xSemaphoreCreateBinary();

    if ( activateActuatorSem != NULL ) {
      xSemaphoreGive( activateActuatorSem );  // Make the Serial Port available for use, by "Giving" the Semaphore.
  }

  // Now set up tasks to run independently.
  
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *) "Blink"   // A name just for humans
    ,  128  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 1 being the highest, and 4 being the lowest.
    ,  NULL );

   xTaskCreate(
    TaskReadFromSerial
    ,  (const portCHAR *) "ReadFromSerial"
    ,  128  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskReadFromSerial( void *pvParameters )
{
  (void) pvParameters;

  for (;;)
  {
    if(Serial.available()>0) {
      input = Serial.readString();
      Serial.println("read");
      if (xSemaphoreTake(activateActuatorSem, portMAX_DELAY) == pdTRUE) {
        Serial.println("Input:");
        Serial.println(input);
        Serial.println("sema");
        xSemaphoreGive(activateActuatorSem);
      }
    }
    vTaskDelay(1); 
  }
}

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    if (xSemaphoreTake(activateActuatorSem, portMAX_DELAY) == pdTRUE) {
      if (input.equals("1\n")) {
        digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
        vTaskDelay( 250 / portTICK_PERIOD_MS ); // wait for one second
        digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
        vTaskDelay( 250 / portTICK_PERIOD_MS ); // wait for one second 
      }
      xSemaphoreGive(activateActuatorSem);
    }
    
  }
}

加載上面的代碼,我在顯示器中看不到任何東西,或者從我的計算機發送命令。

最后,我可以修復上面的代碼。

#include <Arduino_FreeRTOS.h>
#include <semphr.h>

// define tasks
void TaskReadFromSerial( void *pvParameters ); // Get commands
void TaskBlink( void *pvParameters ); // LED as actuator

//define smaphore handlers
SemaphoreHandle_t activateActuatorSem;

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect.
  }

  activateActuatorSem = xSemaphoreCreateBinary();

  if ( activateActuatorSem != NULL )
    xSemaphoreGive( activateActuatorSem );  // Make the Serial Port available for use, by "Giving" the Semaphore.

  // Now set up tasks to run independently.
  
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *) "Blink"   // A name just for humans
    ,  256  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 1 being the highest, and 4 being the lowest.
    ,  NULL );

   xTaskCreate(
    TaskReadFromSerial
    ,  (const portCHAR *) "ReadFromSerial"
    ,  256  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskReadFromSerial( void *pvParameters )
{
  (void) pvParameters;
  
  for (;;)
  {   
    if(Serial.available()>0){
      char c = Serial.read();
      if (c == '1')
        xSemaphoreGive(activateActuatorSem);
    }
    vTaskDelay( 250 / portTICK_PERIOD_MS ); 
  }
}

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
     xSemaphoreTake(activateActuatorSem, portMAX_DELAY);
     digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
     vTaskDelay( 250 / portTICK_PERIOD_MS ); // wait for one second
     digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
     vTaskDelay( 250 / portTICK_PERIOD_MS ); // wait for one second  
  }
}

ReadFromSerial 任務因為字符串而被卡住。 最好使用 char 代替。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM