Arduino 在很长一段时间后停止向串口发送数据
我使用 Arduino Uno rev2 设备作为永久连接的设备,有时会向 PC 发送信号( Windows 7 x64)。使用来自 arduino.cc 的 Arduino 1.0 软件编译的代码
arduino.cc 上的主题, Arduino 在很长一段时间后停止向串口发送数据
它工作得很好,但有时,经过很长一段时间后,PC 停止从 Arduino 设备接收数据。这不是 PC 软件问题,因为所有软件(putty、telnet 等)的行为都是相同的 - 我可以将数据发送到 Arduino(设备响应命令);我就是收不回来。
串行通信在长时间后停止中描述了类似的问题。 ,但没有提出解决方案。
断开/连接设备暂时解决了问题,但这并不是解决方案,因为设备应该永久且完全自动使用。
使用板重置按钮重置程序和一开始的所有价值观都无济于事。 PC 未开始接收数据。
注意:
millis() 翻转错误在使用 Arduino 1.0 软件的 Arduino Uno 板上无法重现 - 我想这个问题已被修复,而且 millis() 现在只能在 50 天内真正翻转,就像文档中所说的那样。此外,代码中的 millis() 独立代码 也没有响应。
向 PC 发送数据期间闪烁的 LED 仍然闪烁。
字符串的使用可能会增加内存使用量,但是这个程序太小了,这不会成为问题。程序运行 10 多个小时后没有使用额外的内存,因此我不会真的费心用其他东西替换字符串,因为串行端口问题要严重得多。
如果你认为问题出在arduino程序bug上,请想想如何解释TX闪烁&重置没有帮助。
I am using an Arduino Uno rev2 device as a permanently connected device that sometimes sends signals to a PC (Windows 7 x64). Code compiled with Arduino 1.0 software from arduino.cc
Topic on arduino.cc, Arduino stops sending data to Serial after a long time period
It works perfectly but sometimes, after a long period of time, the PC stops receiving data from the Arduino device. It is not a PC software issue, as all software(putty, telnet, etc..) acts the same - I can send data TO the Arduino (the device responds to commands); I just can't receive it back.
A similar problem was described here in Serial communication stops after long periods., but no solution was suggested.
Disconnecting/connecting the device solved the issue temporarily, but this can't be a solution, as the device is supposed to be used permanently and fully automatically.
Using board reset button that resets program & all values to it's start wont help. Data does not start to be being received by PC.
Notes:
millis() rollover bug is not reproducable on Arduino Uno board with Arduino 1.0 software - I guess this was fixed and millis() now do really rollover only in 50 days, like it is said in documentation. Besides code has millis() independent code that is not responding too.
LED that is blinking during sending data to PC still blinks.
Strings usage could increase memory usage, but this program is way too small for that to be a problem. No additional memory was used after 10+ hours of program running, so I'm not really going to bother with replacing Strings with something else, as Serial port problem is far more major.
If you think that the problem is in arduino program bug, please think of how to explain TX blinking & reset not helping.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
也许通过软件重置您的问题就可以解决。
我运行了以下代码来确定软件重置是否会重置时钟,从而重置
millis()
函数:如代码中所述,要使软件重新启动,只需创建一个指向地址 0 的函数指针并调用它。
我确实得到了满意的结果:
我希望这能解决您的问题:)
Perhaps making a software reset your problem would be solved.
I ran the following code to find out if a software reset would reset the clock and therefore the
millis()
function:As explained in the code, to make a software reboot simply create a function pointer to address 0 and call it.
I, indeed, had satisfactory results:
I hope this solves your problem :)
如果您不断轮询 Arduino,那么作为一种解决方法,您可以在 Arduino 中实现一个看门狗,如果 Arduino 长时间没有向 PC 输出数据,它将重置 Arduino。您可以监视 Arduino TX 引脚,将其连接到另一个输入引脚,使用中断...重点是在每次 TX 活动后重置看门狗。
If you constantly poll Arduino, then as a workaround you can implement a watchdog in Arduino which will reset Arduino if it hasn't output data to PC for a long time. You can monitor Arduino TX pin, bring it to another input pin, use interrupt... The point is to reset watchdog after each TX activity.
时钟有可能折叠起来。
previousclock = millis() 可能会在折叠之前卡在一个较高的值。您可以扩展测试以包括(当前毫利斯 < 先前毫利斯)加/减一些模糊因子的情况。
顺便说一句,它使用了 ignas 的源代码(OP 源代码在没有注册的情况下无法读取,我不想注册)
编辑:我从 wakkerbot 复制了下面的片段,并对其进行了一些编辑。这只是为了
演示环绕如何使您的last_action时间戳停留在int间隔的顶部(如果凹凸值不是int_max的除数)
您可能可以稍微简化上面/下面的逻辑,因为您只对内部/外部间隔测试感兴趣。 Stamp 的 typedef 当然应该适应 millis() 的类型(unsigned long ?),并删除 fakemillis() 并将对其的引用替换为 millis()。
如果您在“普通”计算机上编译并运行上述程序,您可以看到 badlast 和 badtest 卡住了。恕我直言,这也是你的arduino上发生的事情。
更新:肯定溢出/翻转。 (GIYF)
http://www.arduino.cc/cgi-bin/yabb2 /YaBB.pl?num=1200662708
更新 2:不相关,但不好的编码实践:
您正在此处比较两个字符串。 (这可能按照 C++ 的预期进行处理,但在 C 中这是完全错误的。我还建议用一个巨大的 switch 语句替换重复的 if(...) {...} ,这至少可以避免调用重复使用 substr() 函数(或者它是内联的?)
更新 20111211:这是一个不注意换行的比较和设置函数,它需要一个指向要比较和设置的值的指针以及宽度预期的间隔:
该函数在loop()部分中使用如下:
最后:恕我直言,RESET不起作用的原因是并非所有全局变量都在setup()函数中初始化另外:我认为你应该摆脱它。 String 的东西(运行时有 GC 吗?)并使用普通的字符缓冲区来代替。
It is possible that the clock folds around.
previousclock = millis() might get stuck at a high value, just before folding around. You could extend the test to include the case that (currentmilis < previousmillis) plus/minus some fudge factor.
BTW It used ignas's source code (the OP sourcecode was not readble without registration, and I don't want to registrate)
EDIT: I copied the fragment below from wakkerbot, and edited it a bit. It is just to
demonstrate how wraparound can get your last_action timestamps stuck at the top of an int interval (if the bump value is not a divisor for int_max)
You could probably simplify the above/below logic a bit, since you are only interested in inside/outside interval tests. The typedef for Stamp should of course be adapted to the type of millis() (unsigned long ?) and fakemillis() removed and references to it replaced by millis().
If you compile and run the above program on a "normal" computer, you can see the badlast and badtest getting stuck. That is what happens on your arduino, too, IMHO.
Update: definitely overflow/rollover. (GIYF)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1200662708
Update2: unrelated, but bad coding practice:
You are comparing two strings here. (this might be handled as intended by c++, but in C it is just plain wrong. I'd also suggest replacing the repeating if(...) {...} by a giant switch statement, that would at least avoid calling the substr() function repeatedly. (or is it inlined?)
UPDATE 20111211: here is a wrap-oblivious compare&set function it needs a pointer to the value to compare and set, and the width of the intended interval:
This function is used in the loop() section as follows:
Finally: IMHO the reason why RESET does not work, is that not all global variables are initialised in the setup() function. Also: I think you should get rid of the String thingies (is there GC in the runtime ?) and use ordinary character buffers instead.
几个小时后,Arduino 无法通过有线方式执行来自 Arayks 和 TX 900 的命令,但重新启动后 Arduino 已启用。
After a few hours, the Arduino is not able to execute commands from Arayks and TX 900 with wire, but after the restart the Arduino is enabled.