Arduino多線程技術


目錄

Table of Contents

Introduction

使用方法

示例1:SCoop-example

示例2:測試程序



Introduction

在Arduino實際開發中我們可能遇到這樣的問題:

  • arduino需要不斷的讀取外部管腳所輸入的傳感器數值;

  • 於此同時,要產生PWM方波來控制步進電機;

  • 如果有上位機,則還需要完成數據的收發工作;

  • 按鍵key輸入時需要消抖延時delay(30),但是這樣的延時30ms等會導致整個Arduino硬件處於閒置狀態,而後臺需要完成的任務也被擱置。

針對此類多任務同時處理的工作場景,解決方法有多種,第一:使用計時器或外部中斷機制,完成多任務處理;第二:使用Arduino 多線程技術,本質上也是中斷機制。

於是,Github上的牛人們幫我們寫好了一個Scoop多線程庫,傳送門:

https://github.com/fabriceo/SCoop/tree/master/SCoop


使用方法

  1. Github鏈接下載或克隆文件夾到本地;
  2. 解壓文件,找到SCoop文件夾,將其重新壓縮成.zip 文件,另存;
  3. 打開Arduino IDE 在【項目】選項中找到加載項目庫選項,然後找到剛纔壓縮的SCoop.zip文件;
  4. 成功添加庫文件之後,可以在【文件】-【示例】中找到【SCoop】-example1 等例子程序。
  5. 選擇新建項目,實際測試Arduino多線程。

示例1:SCoop-example


// EXAMPLE 1
/* VERSION 1.2  NEW YEAR PACK 10/1/2013                                       */

#include <SCoop.h>     //包含SCoop頭文件
#define led1 LED_BUILTIN

defineTaskLoop(myTask1)    //創建線程myTask1
{ 
    Serial.println("hello from task1"); 
    sleep(1000); 
}
defineTask(myTask2);   //創建線程myTask2

void myTask2::setup() { //設定線程myTask2
    trace("task2setup"); pinMode(led1, OUTPUT); 
}

void myTask2::loop()  { //設定線程myTask2循環
  Serial.println("led1 HIGH"); digitalWrite(led1, HIGH); sleepSync(500);
  Serial.println("led1 LOW");  digitalWrite(led1, LOW);  sleepSync(500); 
}

defineTimerRun(Timer1,100) 
{ if (Serial.available()) { 
     char c = Serial.read(); 
	 Serial.print(c);Serial.println(" key pressed"); 
	 if (c=='a') myTask1.pause();
	 if (c=='b') myTask1.resume();
	 } }
  
void setup() { Serial.begin(57600); while (!Serial); mySCoop.start(); }

void loop()  { Serial.println("do whatever you want here also"); 
mySCoop.sleep(500); }

示例2:測試程序


測試完整代碼及子線程完整定義,注意延遲函數使用sleep(),不要使用delay(); sleep()只在當前線程進行延遲,delay()則會在全局進行延遲。

/*實現線程1以1s的頻率閃爍,線程2以2s的頻率閃爍*/

#include <SCoop.h>


defineTask(TaskTest1);//創建子線程1
defineTask(TaskTest2);//創建子線程2
void TaskTest1::setup()//線程1設定
{
  pinMode(2, OUTPUT);
}
void TaskTest1::loop()//線程1循環
{
  digitalWrite(2, HIGH);
  sleep(1000);
  digitalWrite(2, LOW);
  sleep(1000);
}

void TaskTest2::setup()//線程2設定
{
  pinMode(3, OUTPUT);
}
void TaskTest2::loop()//線程2循環
{
  digitalWrite(3, HIGH);
  sleep(2000);
  digitalWrite(3, LOW);
  sleep(2000);
}
void setup() {
  mySCoop.start();
}

void loop()
{
  yield();
}

最後想說一下,畢竟這個只是 arduino ,雖然這個可以實現併發處理,但最多隻能支持兩三個併發任務,再多就不行可能報錯了,如果還想處理更多併發任務,推薦用 stm32。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章