我写的程序的功能是通过USB端口将来自传感器的传入模拟数据传输到计算机上的程序。为了一点乐趣,我决定在程序中添加一个按钮来打开/关闭一盏灯。灯将连接到继电器,该继电器连接到arduino。我知道如何编程,但我想知道这是否会中断传感器数据传输?
当按下按钮时,我将从arduino获得灯的当前状态(HIGH(1)或LOW(0)),然后写入arduino(HIGH(1)或LOW(0)),具体取决于目前的状态。由于与传感器输出相关的原因,我在arduino程序的每个循环之间有5秒的延迟;但是,我想我必须改变它,以便当按下按钮时,arduino循环不会错过它,或者这是不可能的?
我以为我在某个地方读到你无法在同一串行上传输/接收流媒体数据......在这种情况下,我需要Mega。
答案 0 :(得分:2)
您必须记住并将Arduino视为单线程设备。当它正在做任何时,它无法做任何其他事情。期!但是,对于串行端口,缓冲区仍将接受RX上的输入数据,但是如果在阻塞时发生溢出情况,则无法进行管理。
请参阅以下直接取自Arduino参考资料
但是,当delay()函数控制Atmega芯片时,某些事情会继续,因为延迟功能不会禁用中断。记录RX引脚上出现的串行通信,保持PWM(analogWrite)值和引脚状态,并且中断将按预期工作。 Reference
现在说当你在循环(delay(5000)
)之间将延迟设置为5秒时,你基本上阻止它做任何其他几乎完全停止的事情。
Arduino框架暴露了一个计数器(millis()
),该计数器基本上从启动时刻开始运行大约50天,增量为一(1)毫秒。见Arduino - millis()
在您的应用程序中,您将定义(记住)您应该运行的循环&当所述循环完成时,不允许其他循环运行,直到millis()
计数器的定义量超过计数。 (请记住将计数定义为long
)
然后你做的是将你的循环移到单独的函数中,这些函数只有在if
语句返回true时才会执行...
例如......
long interval = 5000; // Define interval outside of the main loop
long previousCount = 0; // Used to store milli count when finished
int loopPosition = 1;
void loop()
{
if ((long)millis() - previousCount >= 5000 )
// This if statement will only return true every 5 seconds (5000ms)
{
if (loopPosition == 1)
{
function_One();
previousCount = millis(); // Redefine previousCount to now
loopPosition++; // Increment loop position
}
else if (loopPosition == 2)
{
function_Two();
previousCount = millis();
loopPosition--; // Decrement loop position
}
}
// Do Anything Here You Want
// - While ever the if statement above returns false
// the loop will move to this without hesitation so
// you can do things like monitor a pin low / high scenario.
}
void function_One()
{
// Do Your First Loop
}
void function_Two()
{
// Do Your Second Loop
}
以上内容将阻止您使用阻止功能的任何延迟,更重要的是,如果在正确的情况下正确实施,几乎会使延迟过时。
关于你的串行数据评论,就像我在本文顶部所说的那样,Arduino只能 一次做一件事。即使使用Mega,也无法在完全同时发送和接收。例如,像'Uno'这样的电路板只能使用一个串行接口,而'Mega'只能有四个。
祝你好运.... NB-对于初学者阅读本文,以下教程/示例以相当简单的术语涵盖了我的上述内容,并且是进一步实现的一个很好的构建块! Arduino - Blink Without Delay