如果 x 秒没有串行数据,请关闭模拟引脚

问题描述

我的计算机上有一个程序,它向我的 Arduino 发送串行数据,指示 Arduino 上的模拟写入。我如何检查 x 秒内是否没有发送新的串行数据,以及是否没有执行任何操作。例:

if (newDataInLastSeconds(10) {
    // Do Something...
}```

解决方法

对于这个问题,您可以使用状态机来跟踪串行链路的状态,并设置在状态转换时触发的操作。如果您还想根据链接的状态设置每 loop() 次发生的操作,则设置起来更容易(未显示)。

您可能已经在检查 Serial.available() 以查看串行线路上是否接收到任何字节,对吗?您需要做的就是创建一个非常简单的两态状态机:

  1. 确定您想要的超时时间
  2. 跟踪数据超时处于什么状态(bool serial_fresh -- 您最近是否收到过数据)
  3. 记录您上次收到任何数据的时间
  4. 如果串行线路是新鲜的,则将当前时间与前一时间进行比较。如果大于您的超时时间,则将 fresh 设置为 false(这是一个状态转换)并执行您想做的操作
  5. 如果串行线路不新鲜,而您刚收到数据,则将 fresh 设置为 true(另一个状态转换)并在该转换中执行您想要执行的操作
// start in the unfresh state,we won't transition to fresh until
// we receive the first byte - if this doesn't match what you want change to fit
bool g_serial_fresh = false; 
const unsigned long SERIAL_TIMEOUT_MS = 5000; // or however many milliseconds
unsigned long g_last_serial_rx_ms = 0;

void transitionToFresh() {
    g_serial_fresh = true;
    /* do what you want to do when the link comes back up - turn on ADC */
}

void transitionToStale() {
    g_serial_fresh = false;
    /* do what you want to do when the link times out - shutdown ADC */
}

bool serialTimedOut() {
    return (millis() - g_last_serial_rx_ms) > SERIAL_TIMEOUT_MS;
}
void doStateMachine() {
    bool received_data_this_loop = false;

    if (Serial.available() > 0) { // assumes you read all available bytes later
        g_last_serial_rx_ms = millis();
        received_data_this_loop = true;
    }

    if (!g_serial_fresh && received_data_this_loop) {
        transitionToFresh();
    }

    else if (g_serial_fresh && serialTimedOut()) {
        transitionToStale();
    }
}
void loop() {
    doStateMachine();

    /* do regular programmy things here */
}
,

您可以创建一个带有 while 循环的函数,通过使用 Serial.available 函数在特定时间段内检查新数据:

boolean newDataInInterval(long waitInterval){
  long startTime = millis();
  while (millis() <= (startTime+waitInterval)) {
    if (Serial.available() > 0) {
      return true;
    }
  }
  return false;
}

请注意,waitInterval 应以毫秒为单位给出。