c - 寻找好的算法在给定时间运行特定代码。 (Arduino C 程序)

标签 c algorithm time arduino

我正在为 Arduino 编写一个定时器/调度程序简单程序。

这是一个 C 程序,带有一次又一次运行的“主”循环。 Arduino 连接有 DS3231 RTC 模块,提供当前星期几、小时、分钟、秒等。

我需要实现的是通过串行端口发送特定的字符串,但与许多有关“在特定时间点亮 LED”的示例相比 - 我不能允许代码运行多次。 因此,如果正常的“在特定时间点亮 LED”只是一次又一次循环“if”检查,并根据它设置数字输出“高”或“低”(一次又一次) - 我无法使用这种方法。

我现在使用的并且有效的方法是这样的: 我用想要的时间和每次的“操作代码”创建了一个数组 - 它们都是整数,如下所示:

const int A = 6;    // Action Array Size
  int ActionTimes[A][4] = {
    {6,18,37,1},
    {6,18,38,2},
    {5,15,20,11},
    {5,16,35,51},
    {5,16,40,52},
    {5,23,55,15}   
  };

然后,从主循环中,我调用一个“Check”函数,该函数运行一个“for”循环来检查是否存在应在当前时间运行的操作:

 int i;
  for ( i = 0; i < A; i++ ) {

    if ((dt.DayOfWeek()==ActionTimes[i][0]) && (dt.Hour()==ActionTimes[i][1]) && (dt.Minute()==ActionTimes[i][2]) && (dt.Second() < 2)) {
        RunMyAction(ActionTimes[i][3]);
}

然后 - 我有“action”函数来运行实际需要的代码,如下所示:

void RunMyAction(const int& MyActionCode)
{
  switch(MyActionCode) {
    case 1:
      digitalWrite(2, LOW);  // Turn the LED on by making the voltage LOW
      Serial.println("S041ONE");
      break;  
     case 2:
      digitalWrite(2, HIGH);  // Turn the LED off by making the voltage HIGH
      Serial.println("S017ONE");
      break;        
     case 11:     //Before Knissat Shabat - Full status update.
      Serial.println("S01D00000D00ES02D01001100ES03D00101101ES04D1100D0DDES05D10011DDDE");
      delay(1000);
      break;
     case 15:     //Last GoodNight Shabat - Full status update.
      Serial.println("S01D00000000ES02D00000000ES03D00000100ES04D1000D00DES05D00011DDDE");
      delay(1500);
      break;
     case 51:
      Serial.println("S036OFE");
      delay(1500);
      break;
     case 52:
      Serial.println("S047OFES036ONE");
      delay(1500);
      break;
  }
}

这对我有用并且“完成工作”,但我觉得(从算法上来说)也许这不是最好的编写方式。

例如 - 所有操作和所需时间都硬编码到程序本身中。对于任何添加的操作 - 我必须手动更改数组大小的常量,手动更改数组定义,并向 switch 函数添加其他代码。

(考虑过用excel制作的#include文件合并到数组部分和switch函数中,但这也必须为每次/ Action 更改重新编译程序)。

对于如何以更专业、更有效的方式看待它的任何见解,我们将不胜感激。

非常感谢!

最佳答案

为了避免连续执行相同的操作两次,我添加一个全局变量来保存最近执行的操作的 ActionTImes[] 中的索引,然后在 if 语句中测试该变量。

int latestActionIndex = -1; // -1 so on startup we don't think we've executed ActionTimes[0].

然后在 For 循环中:

if ((dt.DayOfWeek()==ActionTimes[i][0])
    && (dt.Hour()==ActionTimes[i][1])
    && (dt.Minute()==ActionTimes[i][2]
    && latestActionIndex != i)) {
  latestActionIndex = i; // note that we've run this action
  RunMyAction(ActionTimes[i][3]);
}

我从 if 语句中删除了 (dt.Second() < 2),因为该操作可能会在 dt.second() == 0 的一秒左右内执行,并且新变量使 RunMyAction() 无法执行被多次处决。

关于c - 寻找好的算法在给定时间运行特定代码。 (Arduino C 程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59521598/

相关文章:

c - 在 OS X 上使用 icc 时如何链接到 sse 内在函数

c - 在 ubuntu for arm 上编译 TCC 的问题

algorithm - O、Ω 和 Θ 之间有什么区别?

r - 时区在R系统时间的输出中消失

python - 如何将类似 time.gmtime() 的元组转换为 UNIX 时间?

c - 如何确定哪个条件为真?

c - 远程过程调用清理

date - 根据 Google 表格中的当前日期和时间选择 "Time Description"(VLookup、查询)

python - 压缩由0和1组成的长向量

algorithm - 最小化二叉搜索树的高度