模糊计时器(边界内随机)(Arduino)

Posted

技术标签:

【中文标题】模糊计时器(边界内随机)(Arduino)【英文标题】:Fuzzy Timer (random within boundaries) (Arduino) 【发布时间】:2016-01-29 01:08:39 【问题描述】:

我需要一些帮助,试图让计时器变得有点模糊。我想使用这样的固定时间间隔:

____|_______|____|_____|_________|_____|___|_______|

其中管道是事件发生,下划线是数组中的延迟,如下所示:

int myIntervals =  1000, 2000, 750, 850, 1200, 850, 500, 1000;

但值是任意的。

我想为事件创建一个轻微的随机性,但不允许随机性影响整体时间:

___*|*_____*|*__*|*___*|*_______*|*___*|*_*|*_____*|

其中随机性被描述为星号所包含的时间。

所以事件总是在间隔 +- 随机延迟发生:

intfuzzyPeriod = random(-75, 75);

我已经对此进行了试验,但无济于事......当模糊周期为负时,我发现自己处于递归中,或者像这样我显然遇到了 millis() 溢出问题。

int sequence[] = 1000, 750, 950, 1150, 1200, 1500, 1000, 1900, 2000;
unsigned int index;
unsigned long startMillis = 0;
unsigned int fuzzy = sequence[0];

void setup()

  Serial.begin(9600);
  pinMode(13, OUTPUT);


void loop()

  if (startMillis < millis())  // will have rollover issues <<<<<<<
  
    if (millis() - startMillis >= fuzzy)
    
      digitalWrite(13, !digitalRead(13));
      startMillis += sequence[index];   // advance startMillis by the last interval used
      index++;
      if (index >= sizeof(sequence) / sizeof(sequence[0]))
      
        index = 0;
        Serial.println("Restarted Sequence");
      
      fuzzy = sequence[index] + random(-75, 76); // arbitrary offset needs to be positive or negative
      Serial.print("fuzzy = ");
      Serial.println(fuzzy);
    
  

我希望我在解释方面做得很好......我这辈子都做不到,我知道我已经到了需要一点帮助的地步!

【问题讨论】:

我对arduino一无所知,但它可能有助于存储绝对计时值。例如。而不是您的 1000,750,950,... 存储 1000,1750,2700,...。然后将它们随机化(可能除了最后一个)并将差异计算为序列[index]-sequence[index-1]。 我考虑过,但是数据量要大一些,MCU的存储能力很小。 【参考方案1】:

类似这样的:

unsigned int index;
unsigned long nextMillis;
int prevFuzzy = 0;
int fuzzy = 0;

void setup()

    //...
    nextMillis = millis();


void loop()

    if (millis() >= nextMillis)
    
        fuzzy = random(-75, 76);
        // compensate for previous deviation and add new one
        nextMillis += sequence[index] - prevFuzzy + fuzzy;
        fuzzy = prevFuzzy;

        // or just:
        // fuzzy = random(-75, 76) - fuzzy
        // nextMillis += sequence[index] + fuzzy;

        index++;
        if (index >= sizeof(sequence) / sizeof(sequence[0]))
        
            index = 0;
        

        // Do stuff
    

【讨论】:

对不起,不会这样做,时间可能会级联不同步。 nextMillis += sequence[index] + random(-75, 76); @JimfromPrinceton 我就知道你会写这个!查看更新的代码。【参考方案2】:

首先,您必须使用 unsigned long 毫秒来正确解决溢出问题。

然后我也在不同的地方初始化变量,用不同的值启动Millis

int sequence[] = 1000, 750, 950, 1150, 1200, 1500, 1000, 1900, 2000;
unsigned int index = 0;
unsigned long startMillis;
unsigned int fuzzy = sequence[0] + random(-75, 76);

#include <limits.h>

void setup()

  Serial.begin(9600);
  pinMode(13, OUTPUT);
  randomSeed(analogRead(0));
  startMillis = millis();


void loop()

  long MilliDiff;
  if (startMillis <= millis())
    MilliDiff = millis() - startMillis;
  else
    MilliDiff = ULONG_MAX - startMillis + millis();

  if (MilliDiff >= fuzzy)
    
      digitalWrite(13, !digitalRead(13));
      startMillis += sequence[index];   // advance startMillis by the last interval used

      index++;
      if (index >= sizeof(sequence) / sizeof(sequence[0]))
      
        index = 0;
        Serial.println("Restarted Sequence");
      

      fuzzy = sequence[index] + random(-75, 76); // arbitrary offset needs to be positive or negative
      Serial.print("startMillis = ");
      Serial.print(startMillis);
      Serial.print(",  sequence = ");
      Serial.print(sequence[index]);
      Serial.print(",  fuzzy = ");
      Serial.println(fuzzy);
    

这段代码似乎在我的 Uno 上运行

【讨论】:

以上是关于模糊计时器(边界内随机)(Arduino)的主要内容,如果未能解决你的问题,请参考以下文章

Arduino:在 C++ 类中使用定时器

我在将arduino网络中实现Atmega328计时器时遇到问题

Arduino定时器中断采样

Arduino:如何使用 arduino 创建闹钟

Arduino Due 中的定时器

Arduino ESP32定时器功能使用