我有以下代码(我使用的是Arduino IDE和带有MAX3232的NodeMCU):
#include <SoftwareSerial.h>
SoftwareSerial RS232Serial(D1, D2); // RX | TX
void setup() {
Serial.begin(9600);
while (!Serial);
RS232Serial.begin(9600);
while (!RS232Serial);
}
void loop() {
Serial.println("Sending msg...");
char msg[] = {0x7E, 0x00, 0x78, 0xF0, 0x7E};
RS232Serial.write(msg, sizeof(msg));
Serial.println("Waiting incomming message:");
while(RS232Serial.available() <= 0) {
delay(1);
}
while(RS232Serial.available() > 0) {
Serial.print(RS232Serial.read(), HEX);
}
Serial.println("");
Serial.println("------------ END -----------");
}
我正在使用Docklight来测试通信。到目前为止,我能够收到NodeMCU板首先发送的HEX char msg[] = {0x7E, 0x00, 0x78, 0xF0, 0x7E};
。但我无法从Docklight正确接收数据。
我试图从Docklight发送的HEX是7E 00 00 70 15 7E
。使用串行监视器进行调试,有时我只收到7E
,有时收到0FF
,而不是完整的邮件。波特率,开始/停止位和奇偶校验设置为默认值。
我的代码出了什么问题?
答案 0 :(得分:2)
不按预期工作的一个原因是:
Docklight应用笔记Arduino Serial Communication中有一个相关示例 - 请查看第5页的代码清单。它使用Arduino SerialEvent() function来收集每字节字节的传入电报。只有在收到电报标记结束后(这里:换行&#34; \ n&#34;字符),它才会设置一个标志,告诉主循环()中的代码对累积的数据电报做某事。
Docklight示例中使用的SerialEvent方法不是必须的。你也可以单独解决这个内部循环()。但你肯定需要改变
while(RS232Serial.available() <= 0) {
...
while(RS232Serial.available() > 0) {
部件将等待直到收到完整电报(或发生超时)。
现在让我感到恼火的是你写的有时会收到&#34; 0FF&#34;即使你从来没有从Docklight发送它。这可能表明实际的RS232通信仍然存在第二个问题,但如果没有额外的信息,很难猜测。
但如上所述重新处理电报接收部分应该已经使事情更加清晰,然后是&#34; 0FF&#34;可能更明显。
答案 1 :(得分:0)
while(RS232Serial.available() <= 0) {
delay(1);
}
您只是在等待串行缓冲区至少有1个字节,但是当您致电RS232Serial.available()
时,无法保证您的完整消息(6个字节)会出现。
在尝试读取之前,您应该等待串行缓冲区累积至少6个字节。
while(RS232Serial.available() < 6) {
delay(1);
}
他们可以通过以下方式阅读完整的缓冲区:
while(RS232Serial.available() > 0) {
Serial.print(RS232Serial.read(), HEX);
}
或只有6个字节:
for (int i=0; i<6; i++) {
Serial.print(RS232Serial.read(), HEX);
}
我不知道您的0FF
,但Serial.print(RS232Serial.read(), HEX)
没有填充十六进制字符串,这实际上可能是00 0F 0F
或00 FF
。
您应该用以下字符打印出字节:
byte b = RS232Serial.read();
if (b < 16) Serial.print('0'); // zero pad
Serial.print(b, HEX);
Serial.print(' '); // add space after each byte