1. 程式人生 > >【Arduino】一份簡單的(偽)多執行緒示例 - print "Hello World" 和 echo 功能

【Arduino】一份簡單的(偽)多執行緒示例 - print "Hello World" 和 echo 功能

Arduino 上執行(偽)多執行緒示例 - print “Hello World” 和 echo 功能

Demo

/**
 * Reference:
 *   N/A
 */

void setup(){
	Serial.begin(9600);
	// Serial1.begin(9600);
} void loop(){ /** * scheduling */ int count = 0; while (1){ if (count == 10){ count = 0; } if (1){ thread_echo(); } if (count == 9){ thread_hello(); } delay(100); count ++; } } void thread_hello(){ Serial.println("Hello world"); // print "Hello World" to the Serial Monitor
} void thread_echo(){ while (Serial.available()){ Serial.write( Serial.read() ); // echo } }

Note

僅在接收端不會出現不斷地傳送資料的情況下有效。

如果接收端會一直髮送資料,則程式會在 thread_echo 函式(偽執行緒)中停留過長時間,則 thread_hello 函式(另一個偽執行緒)的每秒列印一次 “hello world” 就會不準確。

相關

Arduino 定時器(delay()

Arduino 上的 delay 佔用了一個定時器。如果你的板子有兩個定時器,或許你可以寫出更精確的執行緒排程。
在微控制器開發板上,如果不適用實時系統的話,個人的理解,實現多執行緒就是時分複用。可以簡單做成每個“註冊

執行緒”都輪詢執行一定的時間,並且保證該執行緒內不要使用定時器即可。

Arduino Serial

  1. Serial.available() 不會 block。
  2. UART 的中斷已經在底層被 Arduino 封裝過了(Serial 類),所以它有 Serial 中斷,但是你編寫上層程式碼是不能使用這個中斷的。

    但是這一點其實無需在意,UART 的中斷收取資料後儲存在一個 FIFO 中,除非接收端不斷髮送,而程式又一直不去讀取,或者太久之後才讀取,才有可能發生 FIFO 溢位,資料丟失的情況。但是這個時候一般都是上層應用寫得有問題。或者傳送端傳送的資料太快,已經超出了 Arduino 微控制器的處理能力。

  3. Serial.serialEvent() 不是中斷

    正如前面所言,UART 的中斷已經被封裝使用過了,所以這個 Serial.serialEvent() 實際上不是中斷。
    它會在每兩個 loop() 之間呼叫。
    也就意味著這麼寫:

    bool led_blink_flag = false;
    void led_blink(the_bind_ping){
        digitalWrite(the_bind_ping, led_blink_flag);
        led_blink_flag = !led_blink_flag;
        sleep(1000);
    }
    void setup(){ Serial.begin(9600); pinMode(13, OUTPUT); }
    void loop(){
        led_blink(13);
    }
    void serialEvent() {
        while (Serial.available())
            Serial.write( Serial.read() );  // echo
    }
    

    和這樣寫:

    [......]
    void loop(){
        led_blink(13);
        mySerailEvent();
    }
    void mySerailEvent() {
        while (Serial.available())
            Serial.write( Serial.read() );  // echo
    }
    

    效果是完全一樣的。