【问题标题】:Turn off analog pins if no serial data for x seconds如果 x 秒内没有串行数据,则关闭模拟引脚
【发布时间】:2020-12-21 14:47:23
【问题描述】:

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

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

【问题讨论】:

  • 您的问题意味着您只想在数据链路从打开到关闭(或从关闭到打开)转换时才做一件事(或一组事情)。如果您想在每个 loop() 上重复执行某些操作,也可以完成,并且比仅转换操作更容易设置。

标签: arduino serial-port arduino-c++


【解决方案1】:

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

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

  1. 确定所需的超时时间
  2. 跟踪数据超时所处的状态(bool serial_fresh -- 您最近是否收到过数据)
  3. 记录您上次收到任何数据的时间
  4. 如果串行线路是新的,请将当前时间与之前的时间进行比较。如果大于您的超时时间,则将 fresh 设置为 false(这是一个状态转换)并执行您想要执行的操作
  5. 如果串行线不是新鲜的,而您刚刚收到数据,则将新鲜设置为 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 */
}

【讨论】:

    【解决方案2】:

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

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

    注意waitInterval 应该以毫秒为单位。

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 1970-01-01
      • 2020-05-26
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 2015-09-05
      • 2018-04-14
      相关资源
      最近更新 更多