如何背景睡在Arduino的? [英] How to background a sleep in arduino?

查看:260
本文介绍了如何背景睡在Arduino的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始与Arduino的,我已经爱上它。其中一个项目,我想尝试用follwing伪code流动的交易:

I am just starting with arduino and I already love it. One of the projects I would like to try deals with the follwing pseudo-code flow:

def switch():
    set_pin_2_to_HIGH
    wait_10_seconds
    set_pin_2_to_LOW

loop()
  // some time sensitive code, which should be executed on a
  // reasonably regular cycle
  if_pin_1_is_HIGH:
     switch()
  // some more code where the state of pin_2 will be tested, that code also need
  // to run in a reasonably regular cycle

因此​​,我需要循环来而不开关停止,10秒钟()当条件满足。换言之,可以将功能是在后台运行,或者是有相似于例如一种机制 后() Tkinter的

I therefore need the loop to loop without stopping 10 seconds in switch() when the condition is met. In other words, can a function be backgrounded, or is there a mechanism similar to e.g. after() in Tkinter ?

我发现一个聪明的解决办法其中一个手动检查的时间间隔,但希望更 arduinoic 解决方案。

I found a clever workaround where one "manually" checks time intervals but hope for a more arduinoic solution.

推荐答案

也许你可以试试周围的其他方式。而不是按照一个非阻塞睡眠的概念,您可以使用时分复用或者换句话说..线程。

Maybe you could try the other way around. Instead of following a "non-blocking sleep" concept you can use time-division multiplexing or in other words.. threading.

对于使用线程闪烁听起来过于复杂,但 protothreads 在处理不是时间紧迫的任务,做工精良。
快速引进和Arduino的端口可以在这里找到: http://waynemay.com/threading-in-arduino/从链接帖子介绍如何实现这不正是你要找的连续闪烁,但你的问题可以通过处理闪烁序列来解决。

Using threads for blinking may sound overcomplicated but protothreads work well in handling not time-critical tasks. Quick introduction and arduino port can be found here: http://waynemay.com/threading-in-arduino/ Post from the link shows how to implement continuous blinking which is not exactly what you are looking for but your problem can be solved by handling blinking sequences.

这个想法线程如何被用于处理闪烁序列是你修改了一个全局变量(需要闪烁计数),并使用它从你的逻辑,没有任何闪烁的关注和任何阻塞调用的照顾线程。线程还递减每次进行眨眼的变量。

The idea how threads can be used to handle blink sequences is that you modify a global variable (required blinks count) and use threads which take care of blinking without any attention from your logic and any blocking calls. Threads also decrement the variable each time blink is performed.

下面是我用来处理使用线程闪烁的例子:

Here is a sample of what I use to handle blinks using threads:

#include <graham-pt.h>

#define STATUS_PIN           13
#define SENSING_PIN          2

#define STATUS_BLINK_UPDT_INTRVL 100
#define STATUS_BLINK_ON_DURATION_INTRVL 100
#define STATUS_BLINK_OFF_DURATION_INTRVL 10
#define STATUS_BLINK_SEQUENCE_PAUSE_INTRVL 30

int statusBlinksCnt = 0;
unsigned long nowTs, lastSenseTs = 0;

struct pt ptIoThd, ptStatusBlinkOnThd, ptStatusBlinkOffThd;

/* statusBlinkOnThd turns on status led and control status blinking sequences
 */
static int statusBlinkOnThd(struct pt *pt, unsigned long _now, unsigned long _interval){
  static unsigned long lastUpdtTs = 0;
  static unsigned int onIntrvlsCnt = 0;
  static int constantIntrvlsCnt = 0; 
  static int sequencePauseDuration = -1; 
  PT_BEGIN(pt);

  while(1){
    PT_WAIT_UNTIL(pt, abs(_now - lastUpdtTs) >= _interval);  // millis() will overflow after 59 days so abs val must be calculated; one inconsistent sleep between scans avary 2 months is negible
    lastUpdtTs = _now;
    if (statusBlinksCnt == 0){
      digitalWrite(STATUS_PIN, LOW);
    }
    else{
      if (digitalRead(STATUS_PIN) == HIGH)
        onIntrvlsCnt++;
      if (statusBlinksCnt < constantIntrvlsCnt){
        constantIntrvlsCnt = statusBlinksCnt;   
      } 
    }

    if (onIntrvlsCnt >= STATUS_BLINK_ON_DURATION_INTRVL){
      digitalWrite(STATUS_PIN, LOW);
      onIntrvlsCnt = 0;
      if(statusBlinksCnt>0){
        statusBlinksCnt--;
      }
      else if (statusBlinksCnt<0)
        statusBlinksCnt++;

      if (statusBlinksCnt == 0){ //end of blinking sequence
        if (constantIntrvlsCnt < 0){
          sequencePauseDuration = STATUS_BLINK_SEQUENCE_PAUSE_INTRVL;
        }
      }
    }

    if (sequencePauseDuration > 0){
      sequencePauseDuration--;
      if(sequencePauseDuration==0){
        sequencePauseDuration = -1;
        statusBlinksCnt = constantIntrvlsCnt;
      }
    }


  }

  PT_END(pt);
}

/* statusBlinkOffThd turns off status led when blinking takes place
 */
static int statusBlinkOffThd(struct pt *pt, unsigned long _now, unsigned long _interval){
  static unsigned long lastUpdtTs = 0;
  static unsigned int offIntrvlsCnt = 0; 
  PT_BEGIN(pt);

  while(1){
    PT_WAIT_UNTIL(pt, abs(_now - lastUpdtTs) >= _interval);  // millis() will overflow after 59 days so abs val must be calculated; one inconsistent sleep between scans avary 2 months is negible
    lastUpdtTs = _now;
    if (statusBlinksCnt == 0){
      digitalWrite(STATUS_PIN, LOW);
    }
    else{
      if (digitalRead(STATUS_PIN) == LOW)
        offIntrvlsCnt++;
    }

    if (offIntrvlsCnt >= STATUS_BLINK_OFF_DURATION_INTRVL){
      digitalWrite(STATUS_PIN, HIGH);
      offIntrvlsCnt = 0;
    }
  }
  PT_END(pt);
}

void setup(){
  pinMode(SENSING_PIN, INPUT_PULLUP);
  pinMode(STATUS_PIN, OUTPUT);
  PT_INIT( &ptStatusBlinkOnThd );
  PT_INIT( &ptStatusBlinkOffThd );
  statusBlinksCnt = 2;
}

void loop(){
  nowTs = millis();

  // updating threads
  statusBlinkOnThd(&ptStatusBlinkOnThd, nowTs, STATUS_BLINK_UPDT_INTRVL);
  statusBlinkOffThd(&ptStatusBlinkOffThd, nowTs, STATUS_BLINK_UPDT_INTRVL);

  // debounce digital read by setting statusBlinkCnt indirectly - after certain delay after switch is pressed and hold
  if (digitalRead(SENSING_PIN) == LOW){
    if (lastSenseTs == 0){
     lastSenseTs = nowTs;
    }
  }
  else{
    lastSenseTs = 0;
  }

 //simple bouncing; may not work on millis counter overflow every ~59 days
  if(lastSenseTs > 0)
     if(nowTs - lastSenseTs > 50){
       statusBlinksCnt = 1; 
       lastSenseTs = 0;             // should be removed if blinking should be continuous when input is kept at LOW 
     }
}

上面的code使得与之间暂停1秒启动了两个10秒闪烁。如果设置 statusBlinksCnt 来,许多闪烁由闪烁的线程执行的正值。如果设置 statusBlinksCnt 为负值你的Arduino将继续闪烁不断在 STATUS_BLINK_SEQUENCE_PAUSE_INTRVL 。关闭,并暂停持续时间可以通过 STATUS_BLINK_UPDT_INTRVL 以毫秒为单位pssed前$ P $乘以定义来计算。

The code above makes two 10 second blinks on start up with 1 second pause in between. If you set statusBlinksCnt to a positive value that many blinks will be performed by the blinking threads. If you set statusBlinksCnt to a negative value your arduino will keep blinking defined sequence of blinks continuously with pause between sequences defined in STATUS_BLINK_SEQUENCE_PAUSE_INTRVL. Off, on and pause durations can be calculated by multiplying defines by STATUS_BLINK_UPDT_INTRVL expressed in milliseconds.

我没有时间(和试验板上附近..)来测试输入引脚的阅读和琐碎的谴责,但它应该工作,但是我只是注意到要检测高压状态,而我的code使用拉的输入和低输入状态闪烁。

I didn't have time (and breadboard nearby..) to test the input pin reading and trivial denouncing but it should work however I just noticed you want to sense HIGH state whereas my code uses pull-up on input and blinks on the LOW input state.

这篇关于如何背景睡在Arduino的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆