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