Serialization 为什么这个简单的Arduino草图会在短时间后慢下来?

Serialization 为什么这个简单的Arduino草图会在短时间后慢下来?,serialization,arduino,usb,Serialization,Arduino,Usb,我有一个非常简单的Uno3的Arduino草图(见下文),它在主循环中读取多个传感器并串行。打印(发送)结果(以字符形式)到9600波特的串行端口 前24个循环大约以预期的速度(可变等待)运行,但随后速度大大降低——时间戳(毫秒)见下文 我认为这一定与传感器读数有关,因为一个更简单的草图将全速继续发送毫秒()。或者是串行通信阻塞了 我的素描: #include <OneWire.h> #include <DallasTemperature.h> const int on

我有一个非常简单的Uno3的Arduino草图(见下文),它在主循环中读取多个传感器并串行。打印(发送)结果(以字符形式)到9600波特的串行端口

前24个循环大约以预期的速度(可变等待)运行,但随后速度大大降低——时间戳(毫秒)见下文

我认为这一定与传感器读数有关,因为一个更简单的草图将全速继续发送毫秒()。或者是串行通信阻塞了

我的素描:

#include <OneWire.h>
#include <DallasTemperature.h>

const int oneWireBus = 7; 
// read the input on analog pin 0:
int vas = analogRead(A0);
int time = millis();
int wait = 10;


OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
  pinMode(2, OUTPUT);
}

void loop() {
  sensors.requestTemperatures();

  if (millis() > time + wait) {
     time = time + wait; 

    //Serial.println(Serial.availableForWrite());
    Serial.print(millis());
    Serial.print(",");
    Serial.print(analogRead(A0));
    Serial.print(",");
    Serial.print(analogRead(A5));
    Serial.print(",");
    Serial.print(sensors.getTempCByIndex(0));
    Serial.print(",");
    Serial.println(digitalRead(4));
    //delay(10);        // delay in between reads for stability
    if (vas > 300) {
      digitalWrite(2, HIGH);  
    }
    else {
      digitalWrite(2, LOW);  
    }
  }
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(millis());
}
…请注意,在时间737之前,每个循环的时间约为30毫秒,然后增加到约700毫秒

如果我运行这个小草图:

#include <OneWire.h>
#include <DallasTemperature.h>

const int oneWireBus = 7; 
// read the input on analog pin 0:
int vas = analogRead(A0);
int time = millis();
int wait = 10;


OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.begin();
  pinMode(2, OUTPUT);
}

void loop() {
  sensors.requestTemperatures();

  if (millis() > time + wait) {
     time = time + wait; 

    //Serial.println(Serial.availableForWrite());
    Serial.print(millis());
    Serial.print(",");
    Serial.print(analogRead(A0));
    Serial.print(",");
    Serial.print(analogRead(A5));
    Serial.print(",");
    Serial.print(sensors.getTempCByIndex(0));
    Serial.print(",");
    Serial.println(digitalRead(4));
    //delay(10);        // delay in between reads for stability
    if (vas > 300) {
      digitalWrite(2, HIGH);  
    }
    else {
      digitalWrite(2, LOW);  
    }
  }
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(millis());
}
..每个循环大约需要4到10毫秒,并继续这样做

我在每个循环中都尝试了Serial.flush(),并且仅在Serial.availableForWrite()大于30时读取传感器。。没什么不同


有什么建议导致这种速度减慢吗?

您的计时代码错误,容易发生翻滚错误。你必须反过来写,计算时间间隔,而不是未来的时间

如果(毫秒()>时间+等待){ 时间=时间+等待

应该是

如果(毫秒()-时间>等待){ 时间=时间+等待

这个问题通常不会这么快就困扰你,但你也有一个时间变量的变量类型问题,我在对你的问题的评论中指出了这个问题。这里再次说明:

int time = millis(); 
我猜它可以正常运行30秒多一点。查看一个int变量可以保存哪些类型的值,看看你是否能理解我是如何知道的。然后看看经典的“无延迟闪烁”示例。它们都使用unsigned long表示时间,这就是millis()返回的结果

阅读一下“立即闪烁”的例子,你就会明白为什么不签名很重要

或者是串行通信阻塞了

…请注意,在时间737之前,每个循环的时间约为30毫秒,然后增加到约700毫秒

有什么建议是什么导致了这种减速

您正在使用的达拉斯温度传感器的ADC锁定默认12位分辨率的温度值的时间小于或等于750ms。当传感器准备就绪时,它们会使用单线协议将响应信号传回总线主机(Arduino)

您可以看到计时的延迟。在前737毫秒,磁带库准备好读取数据。在此之后,磁带库将阻塞并等待传感器发送读数

您可以使用
setWaitForConversion(FALSE)
获得更恒定的延迟。从:


通过Ben T、Delta_G和gre gor的上述非常有用的评论,我为自己的问题提供了一个可行的解决方案

出于教学方面的原因,我扩展了这个示例,以允许在不同传感器的读取之间有不同的时间间隔。比我需要的更灵活,但它可能会派上用场

例如,我希望尽可能多地读取按钮状态(按下/未按下),否则我可能会错过短时间按下按钮。因此,我在循环中完全没有延迟

相反,我对每5秒读取一次温度非常满意。然而,电位计和潜水传感器的读数应该更频繁,尽管不像按钮按下那样频繁。我也不需要通过串行端口将结果输出——10次/秒就可以了。50次/秒似乎不行o大约是我的Arduino Uno rev3能够管理的最大值——这对我来说已经足够了:-)

#包括
#包括
const int oneWireBus=7;//从数字7读取温度
常量字节电位计引脚=A0;//读取模拟引脚0上的电位计输入
const byte submersion pin=A5;//读取模拟引脚5上的浸没输入
const byte buttonPin=4;//读取数字引脚4上的按钮输入
const byte relayPin=2;//将继电器输出写入数字引脚2
无符号长时间LastSerialOutput=millis();//保存最后一次串行输出的时间
const long serialOutputWait=100;//串行输出之间的等待时间(毫秒)
无符号长时间LastTemperatureInput=millis();//保存最后一次温度输入的时间
const long temperatureInputWait=5000;//温度读取之间的等待时间(毫秒)
浮点温度InputValue=0;//保存最新的温度读数
无符号长时间LastPotentialInput=millis();//保存最后一个电位计输入的时间
const long potentialInputWait=500;//电位计读数之间的等待时间(毫秒)
int potentialInputValue=0;//保持最新电位计读数(0-255)
unsigned long timeofLastSubmersion输入=millis();//保存最后一次浸没输入的时间
const long undersionInputWait=500;//在两次浸没读取之间等待多长时间(毫秒)
int submersion input value=0;//保存最新的浸没读数(0-255)
bool buttonInputValue=false;//保存最新的按钮读数
bool buttonPressed=false;//如果自上次检查以来一直按下按钮,则保留1
unsigned long presentTime=millis();//保存当前时间
OneWire OneWire(oneWireBus);
达拉斯温度传感器(单线);
无效设置(){
Serial.begin(9600);
传感器。setWaitForConversion(假);
begin();
pinMode(2,输出);
}
void循环(){
//我们尽可能多地阅读时间和按钮输入——我们不想错过一次短暂的按钮按下!
当前时间=毫秒();
buttonInputValue=!digitalRead(buttonPin);//我们反转(!),因为打开开关=1,关闭开关=0
如果(但是)
#include <OneWire.h>
#include <DallasTemperature.h>

const int oneWireBus = 7;         // read the temperature from digital 7
const byte potentiometerPin = A0; // read the potentiometer input on analog pin 0
const byte submersionPin = A5;    // read the submersion input on analog pin 5
const byte buttonPin = 4;         // read the button input on digital pin 4
const byte relayPin = 2;          // write the relay output to digital pin 2

unsigned long timeOfLastSerialOutput = millis();        // holds time of last serial output
const long serialOutputWait = 100;                    // how long to wait between serial outputs (ms)

unsigned long timeOfLastTemperatureInput = millis();    // holds time of last temprature input
const long temperatureInputWait = 5000;               // how long to wait between temperature reads (ms)
float temperatureInputValue = 0;                      // holds the lastest temperature reading

unsigned long timeOfLastPotentiometerInput = millis();  // holds time of last potentiometer input
const long potentiometerInputWait = 500;              // how long to wait between potentiometer reads (ms)
int potentiometerInputValue = 0;                      // hold the latest potentiometer reading (0-255)

unsigned long timeOfLastSubmersionInput = millis();     // holds time of last submersion input
const long submersionInputWait = 500;                 // how long to wait between submersion reads (ms)
int submersionInputValue = 0;                         // holds the latest submersion reading (0-255)

bool buttonInputValue = false;                        // holds the latest button reading
bool buttonPressed = false;                           // holds 1 if button has been pressed since last check

unsigned long presentTime = millis();                 // holds present time 

OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  sensors.setWaitForConversion(false);
  sensors.begin();
  pinMode(2, OUTPUT);
}

void loop() {
  // we read the time and button input as often as possible -- we dont want to miss a short button press!
  presentTime = millis();
  buttonInputValue = !digitalRead(buttonPin); // We reverse (!) because open switch=1, closed switch=0
  if (buttonInputValue) { // we must remember a (short) button press in future loops -- only reset to 0 after serial send
    buttonPressed = true;
  }

  // Time to read temperature input?
  if (presentTime - timeOfLastTemperatureInput > temperatureInputWait) {
    timeOfLastTemperatureInput = presentTime;
    sensors.requestTemperatures();
    temperatureInputValue = sensors.getTempCByIndex(0);
  }

  // Time to read potentiometer input?
  if (presentTime - timeOfLastPotentiometerInput > potentiometerInputWait) {
    timeOfLastPotentiometerInput = presentTime;
    potentiometerInputValue = analogRead(potentiometerPin);
    if (potentiometerInputValue > 300) {
      digitalWrite(2, HIGH);  
    }
    else {
      digitalWrite(2, LOW); 
    }
  }

  // Time to read submersion sensor input?
  if (presentTime - timeOfLastSubmersionInput > submersionInputWait) {
    timeOfLastSubmersionInput = presentTime;
    submersionInputValue = analogRead(submersionPin);
  }

  // Time to write to serial output?
  if (presentTime - timeOfLastSerialOutput > serialOutputWait) {
    timeOfLastSerialOutput = presentTime;
    Serial.print(presentTime);
    Serial.print(",");
    Serial.print(potentiometerInputValue);
    Serial.print(",");
    Serial.print(submersionInputValue);
    Serial.print(",");
    Serial.print(temperatureInputValue);
    Serial.print(",");
    Serial.println(buttonPressed);
    buttonPressed = false;
  }
}