【问题标题】:Serial communication with Arduino Uno in hexadecimal, and monitoring response with serial monitor以十六进制与 Arduino Uno 进行串行通信,并使用串行监视器监控响应
【发布时间】:2019-07-04 17:58:52
【问题描述】:

我有一个项目,我需要通过串行通信从 Arduino Uno 向第三方设备发送一个十六进制字节数组,设备执行一个操作,并回复一个字节数组,在短暂之后也是十六进制时间(+-500 毫秒)。

第三方 USART USB 接口用于记录第三方设备对计算机的响应,第三方设备 TX 和 USART RX 之间有蓝牙链接。 Arduino TX 和第三方设备 RX 是有线的。

现在有问题的地方:

我的项目要求 Arduino 还捕获来自第三方设备的响应,处理响应,并根据值触发不同的输出 (LED)。

我还需要调试 Arduino 的能力,以确保它接收到的十六进制值得到正确处理并相应地触发输出。

我目前拥有的代码(正在编译,但没有像我预期的那样工作)如下所示:

byte one_shot_FAST[] = {0xAA, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x02, 0x23};

int IncomingByte = 0;

uint8_t q1 = 0;
uint8_t q2 = 0;
uint16_t qtot = 0;
int qVal = 0;
int qValMax = 65535;

const int triggerPin = 2;
int triggerState = LOW;


void setup() {

 Serial.begin(19200);
 pinMode(triggerPin, INPUT);

     Serial.println("<Arduino is ready>");
 
}

void loop() {

triggerState = digitalRead(triggerPin);

if (triggerState == HIGH){
  Serial.write(&one_shot_FAST[0], sizeof(one_shot_FAST));
  //while(!Serial.available());
  IncomingByte = Serial.read();

for (int i=0; i<13; i++) {
  while(!Serial.available()); //wait for character
  IncomingByte = Serial.read();
  Serial.println(IncomingByte,HEX);
delay(10);
}

我希望得到以下回复: AA 00 00 22 00 03 00 00 03 2B 01 E1 35

但我得到一个字符串“#”和每个“#”后面的方块

原理图如下所示:

【问题讨论】:

  • 您能否解释一下您所说的外部 USART 适配器是什么意思?您是否将 Arduino 连接到计算机的 USB 端口?通过监控您的意思是在那台计算机上的终端软件上的交易?你看对了“”这句话吗?
  • 还有一个问题:为什么你会读一次,然后再读 14 次?
  • 外部 USART 适配器 = USB 到 UART 适配器。
  • 我在 Arduino 串行监视器上正确地看到了 语句,但其余部分一团糟。我正在通过 USB 将 Arduino 连接到我的计算机。我单独读取每个字节,因为在这个阶段我只想处理字节 10 和 11,我需要将它们存储在变量中,但这没有在代码中显示。在这个阶段,我很乐意让字符串正确显示。

标签: arduino hex arduino-uno uart


【解决方案1】:

让我们剖析你的问题:

我正在尝试通过串行通信向设备发送 HEX 线,然后读回响应...

你不说是什么设备,你必须假设所说的设备既不是你后面说的 Arduino,也不是电脑。

...同时监控事务。

这根本不可能,除非您有一个多点串行链路(例如 RS485)。如果您想监控串行链路,您需要从任一侧执行此操作,或使用特殊设备(硬件嗅探器)或使用几个额外的串行端口实现您自己的嗅探器。

...但我没有通过 USB 读取正确的传输和任何响应。

如果您的 Arduino 通过 USB 连接到您的计算机,在一般情况下(您可能不是,但您不想解释),您已经为此目的使用了 Arduino 的硬件串行端口(串行监视器打开你的电脑)。

那么,“设备”在哪里连接到您的 Arduino?如果您的意思是您已将其连接到引脚 0 和 1,而您通过 USB 将 Arduino 连接到您的计算机,那么我们发现了您的问题。

来自official documentation

在 Uno、Nano、Mini 和 Mega 上,引脚 0 和 1 用于与计算机通信。 将任何东西连接到这些引脚可能会干扰该通信,包括导致上传失败。

最后,你说:

...虽然外部 USART 适配器确实显示了正确的响应。

显然,您的意思是您正在使用 USB 转串口适配器将“设备”连接到计算机,而 Arduino 根本没有干预。我猜你的意思是你有一个终端程序,比如 Windows 上的 PuTTY 或 RealTerm 或 Linux 上的 Minicom,你打开一个到虚拟串行端口的会话(在你连接电缆时创建),输入命令并按 intro。如果是这种情况,请注意您使用 Arduino 编写的命令不会以 CR 或 LF 终止。您的设备是否需要线路终端?只能猜测……

现在使用您的代码。不知道自己想做什么,或者由于猜测填补了很多空白,要给你很多反馈并不容易。

但这条线似乎特别神秘:

Serial.write(&one_shot_FAST[0], sizeof(one_shot_FAST));

one_shot_FAST 是一个字节数组(出于所有目的都是一个指针),所以当您使用&amp;one_shot_FAST[0] 时,您要求写入数组的第一个元素在内存中占用的地址。我不确定您对此有何想法,但我认为您可能希望删除 &amp; 以在您的命令中发送实际字节。

您的代码中还有其他奇怪的东西:您写入端口并立即(甚至可能在数据离开 TX 缓冲区之前)读取一个字节。我想这会导致Serial.read() 回馈-1

编辑:我已经测试了您的代码并且写入部分(显然我没有硬件来回答命令)工作正常。您看到的正方形和破折号很可能是由于您使用的是 Arduino 串行控制台,它试图将大于 127 的 HEX 值显示为 ASCII,因此它不知道如何显示它们。如果您使用能够显示 HEX 的终端,该命令将正确显示。而且,您当然会遇到尝试将两个以上的设备连接到总线的问题。

【讨论】:

  • 感谢您回复马科斯。我正在编辑我的问题,以便更清楚地了解我正在做什么/试图实现的目标。
  • 关于以下代码行:Serial.write(&amp;one_shot_FAST[0], sizeof(one_shot_FAST)); 它工作正常,删除[0]&amp; 不会从第三方设备产生正确的响应。
  • 关于即时响应,我删除了while(!Serial.available());的第一行(我现在把它放回去并注释掉,对不起,这是马虎)。如果我将它作为我的活动代码的一部分,我永远不会得到设备的响应(或者我可能会,但我无法在我的串行监视器上看到它)。
  • 您好 Adam,感谢您添加草图。我现在有一张更好的照片。如果您的 Arduino 上有两个端口,一个用于您的计算机,另一个用于第三个设备,为什么不使用 Serial1.begin(baudrate) 实例化第二个端口?并且来自第 3 方设备的 TX 线显然去了两个地方(Arduino 上的 RX 和 BT 收发器之一上的 RX)。你不能这样做,串行总线是点对点的,你不能并行连接两个设备。
  • 如果你想监控总线,你可以试试port forwarding,如果你的电脑上有几个空闲端口。否则,您可以购买一堆 RS485 收发器并使您的总线多点。关于Serial.write(),我看不出它是如何工作的,但我可能错了。我会考虑的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
相关资源
最近更新 更多