繁体   English   中英

Arduino编程增加毫秒延迟

[英]Arduino Programming adding milliseconds delay

因此,我正在尝试创建一个能量计设备,每分钟读取一次功率,然后每隔5分钟通过LoRa服务器发送一次,使用MKR 1300 arduino。 问题是到目前为止,硬件在延迟上移除了几毫秒,因此服务器中的时间最终为pe:

10时五十○分30秒

10时五十○分30秒

10时五十○分30秒

...... 2个小时后

10时50分29秒

10时50分29秒

...

10时49分59秒

代码如下所示:

#include <MKRWAN.h>
#include "EmonLib.h"
LoRaModem modem;

String appEui = "1234567891011121";
String appKey = "ffffffffffffffffffffffffffffffff";

EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;

double totalWatt;
int time_running;
int sending;
int totalKW;
int DELAY = 60000; // millis

void setup() {
  Serial.begin(115200);
  if (!modem.begin(EU868)) {
    Serial.println("Failed to start module");
    while (1) {}
  };
  Serial.print("Your module version is: ");
  Serial.println(modem.version());
  Serial.print("Your device EUI is: ");
  Serial.println(modem.deviceEUI());

  Serial.println("Connecting");
  int connected = modem.joinOTAA(appEui, appKey);
  if (!connected) {
    Serial.println("Something went wrong; are you indoor? Move near a window and retry");
    while (1) {}
  }
  Serial.println("Connected");

  modem.minPollInterval(60);

  analogReadResolution(9);
  emon1.current(1, 53);
  emon2.current(2, 53);
  emon3.current(3, 53);
  time_running = 0;

  randomSeed(analogRead(A4));

}

void loop() {
  unsigned long StartTime = millis();

  totalWatt = 0;
  unsigned long delay_send = 0;
  int sending = 0;

  double Irms1 = emon1.calcIrms(600);
  if (Irms1 < 0.3) Irms1 = 0;
  double Watt1 = Irms1 * 230;

  double Irms2 = emon2.calcIrms(600);
  if (Irms2 < 0.3) Irms2 = 0;
  double Watt2 = Irms2 * 230;

  double Irms3 = emon3.calcIrms(600);
  if (Irms3 < 0.3) Irms3 = 0;
  double Watt3 = Irms3 * 230;

  totalWatt = Watt1 + Watt2 + Watt3;
  totalKW = totalKW + totalWatt/1000;


  if (time_running == 5) { //15 para 15 mins
    double IrmsTotal = Irms1 +Irms2 + Irms3;
    String msg = "{\"id\":\"avac_aud1\",\"kW\":"+String(totalKW)+", \"current\":"+String(IrmsTotal)+"}";
    int err;
    modem.beginPacket();
    modem.print(msg);
    err = modem.endPacket(true);
    if (err > 0) { 
      //message sent correctly
      time_running = 0;
      totalKW = 0;
    } else {
      Serial.println("ERR");
      time_running = 0;
    }
  }

 time_running = time_running + 1;

 if ((millis() - StartTime) > DELAY){
    delay(10);
    return;
 } else{
    delay(DELAY-(millis() - StartTime));
    return;
 } 
}

我尝试将一个变量ARD_DELAY(上面没有显示)添加到代码中,在最后一个延迟中减去7到8毫秒来尝试修复它,但显然,它只会使它变得更糟(现在它每1小时消除1秒而不是2小时)所以今天我会尝试添加7到8毫米,看看它是否有效,但我真的很想知道为什么会发生这种情况,因为从我的代码中可以看出,延迟总是应该考虑到处理时间包括数据发送时间。

问题是,你的时钟有多精确......

不过,我个人宁愿选择以下方法:

#define DELAY (5UL * 60UL * 1000UL) // or whatever is appropriate...

static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
    // adding a fix constant will prevent accumulating deviations over time
    timestamp += DELAY;
    // run the every-5-min task...
}

编辑:合并1分钟和5分钟任务:

变式1:

#define DELAY_SHORT (1UL * 60UL * 1000UL)
#define DELAY_LONG  (5UL * 60UL * 1000UL)

static unsigned long timestampS = millis();
static unsigned long timestampL = timestampS;
if(millis() - timestampS > DELAY_SHORT)
{
    timestamp += DELAY_SHORT;
    // run the every-1-min task...
}
if(millis() - timestampL > DELAY_LONG)
{
    timestamp += DELAY_LONG;
    // run the every-5-min task...
}

变式2:

#define DELAY_1M (1UL * 60UL * 1000UL)

static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
    // adding a fix constant will prevent accumulating deviations over time
    timestamp += DELAY;
    // run the every-1-min task...

    static unsigned int counter = 0;
    if(++counter == 5)
    {
        counter = 0;
        // run the every-5-min task...
    }
}

您可以跟踪下一个周期的时间,而不是尝试测量开始时间并根据其添加延迟。

unsigned long next_cycle = DELAY;

...

void loop() {
    ...

    delay( next_cycle - millis() );
    next_cycle += DELAY;
}

如果你还想调整程序在初始化或类似程序上花费的时间,你可以next_cycle = millis() + DELAY; 在你进入循环之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM