如何实现多线程控制-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 27224|回复: 8

如何实现多线程控制

[复制链接]
发表于 2013-12-16 12:37 | 显示全部楼层 |阅读模式
  我现用一块Arduino Uno R3的板子实现一个家庭防盗防火报警系统,有红外热释传感器,烟雾传感器,火焰传感器,温湿度传感器,一个蜂鸣器和一个红外遥控器,红外遥控器是用来当有报警的声音的时候可以用红外遥控关闭报警的声音,现在在修改代码的时候用到了Pt库,实现了红外报警和烟雾传感器的报警,其他的功能还没有实现,希望有大神可以指导一下剩下的代码如何实现,现有代码如下,我的QQ:806002393 跪求大神加我指导一下 万分感激

#include <pt.h>//ProtoThreads必须包含的头文件
int flame = A0;
int mq = A1;
int Beep = 3;
int val = 0;
int val1 = 0;
int hw = 5;
int val3;
static int counter1, counter2, counter3, state1 = 0, state2 = 0, state3 = 0; //counter为定时计数器,state为每个灯的状态
static int protothread1(struct pt *pt) //线程1,控制灯1
{
  PT_BEGIN(pt);  //线程开始
  while (1) //每个线程都不会死
  {
    PT_WAIT_UNTIL(pt, counter1 == 1); //如果时间满了1秒,则继续执行,否则记录运行点,退出线程1
    val = analogRead(flame);
    Serial.print("flame=");
    Serial.println(val);
    delay(1000);
    if (val >= 500)
    {
      digitalWrite(Beep, LOW);
    }
    else
    {
      digitalWrite(Beep, HIGH);
    }
    counter1 = 0; //计数器置零
  }
  PT_END(pt); //线程结束
}

static int protothread2(struct pt *pt) //线程2,控制灯2
{
  PT_BEGIN(pt); //线程开始
  while (1) {   //每个线程都不会死
    PT_WAIT_UNTIL(pt, counter2 == 1); //如果时间满了5秒,则继续执行,否则记录运行点,退出线程2
    val1 = analogRead(mq);
    Serial.print("mq2=");
    Serial.println(val1);
    delay(1000);
    if (val1 >= 500)
    {
      digitalWrite(Beep, LOW);
    }
    else
    {
      digitalWrite(Beep, HIGH);
    }
    counter2 = 0; //计数清零
  }
  PT_END(pt);  //线程结束
}
static int protothread3(struct pt *pt) //线程1,控制灯1
{
  PT_BEGIN(pt);  //线程开始
  while (1) //每个线程都不会死
  {
    PT_WAIT_UNTIL(pt, counter3 == 1); //如果时间满了1秒,则继续执行,否则记录运行点,退出线程1
    val = digitalRead(hw); //将数字接口 7 的值读取赋给 val
    if (val == LOW) //当红外热释电传感器检测有信号时,LED 亮起
    {
      
      digitalWrite(Beep, HIGH);
      
    }
    else
    {
     digitalWrite(Beep, LOW);
    }
    counter3 = 0; //计数器置零
  }
  PT_END(pt); //线程结束
}
static struct pt pt1, pt2, pt3;
void setup()
{
  pinMode(Beep, OUTPUT);
  pinMode(hw, INPUT);
  Serial.begin(9600);
  PT_INIT(&pt1);  //线程1初始化
  PT_INIT(&pt2);  //线程2初始化
  PT_INIT(&pt3);  //线程2初始化
}
void loop () //这就是进行线程调度的地方
{
  protothread2(&pt2);  //执行线程2
  protothread1(&pt1);  //执行线程1
  protothread3(&pt3);  //执行线程1
  delay(10); //时间片,每片1秒,可根据具体应用设置大小
  counter1++;
  counter2++;
  counter3++;
}

发表于 2013-12-17 15:17 | 显示全部楼层
单片机的编程思想和电脑是有差别的,硬要比较的话可以看成“只有一个线程的无限循环”。只有中断可以打断这个循环。中断分内部(比如:串口中断,计数器中断,看门狗中断。。。。。),外部(中断管脚的电平变化)
发表于 2013-12-16 13:18 | 显示全部楼层
只能用中断实现
发表于 2013-12-16 13:18 | 显示全部楼层
不用这么麻烦吧,红外线控制用中断,其他的直接写到“loop”里面就好了呀。线程什么的,太为难Arduino了。而且MCU堆栈是有限制的(好像是10个)call太多重很容易就溢出的。让它傻傻的“loop”吧,功耗很低的

点评

pt是用宏写的,没有call  发表于 2013-12-16 21:21
 楼主| 发表于 2013-12-16 13:23 | 显示全部楼层
我只用了不到5个 设计初衷就是让这几个传感器同时运行  麻烦再问一下 中断加在哪里啊大神
发表于 2013-12-16 16:27 | 显示全部楼层
让它loop,循环查询各路传感器,响应时间应该毫无问题吧?
发表于 2013-12-16 21:27 | 显示全部楼层
这样写不知你能不能看懂
loop()
{
   void func1(){};
   void func2(){};
   void func3(){};
   .
   .
   .
   void func(){};
}
void func1(){} //读传感器1
void func2(){} //读传感器2
void func3(){} //读传感器3
.
.
.
void func(){} //根据传感器状态的反应

没你想多那么复杂,单片机读每个传感器的时间,几乎可以忽略
 楼主| 发表于 2013-12-16 21:32 | 显示全部楼层
我现在单个传感器都可以实现 我把每个单模块套用您这个可以不
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2025-1-1 21:11 , Processed in 0.073677 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表