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。

猜你喜欢

转载自blog.csdn.net/hhaowang/article/details/87896471