在 UART 上广播和获取数据
Broadcasting and Fetch Data On UART
我有一台计算机(用作服务器)和几块带有 Atmega
微控制器的电路板,例如:
计算机连接到 UART
和 RS485
上的电路板(使用 USB
到 RS485
转换器)(我有导致 无法使用 ModBus)。我想通过总线从服务器广播消息并从每个板获取ID(板ID是4位)。
当板子收到广播消息并尝试发送它们自己的 ID 而服务器收到一些假 ID 时,我认为这与所有板子都想在 一次发送数据时的冲突问题有关.
在我搜索这个问题后,我找到了一种方法,可以在每个板中放置一个常量,为发送数据保存一个特殊的延迟,并且当板接收广播消息发送 ID 时具有该延迟......这样它工作正常并且我没有看到碰撞,但有一些问题:
- 可能是2块板的延迟数相同
- 小板数的好方法。
- 在总线上安装板卡时的额外过程。
任何人都知道这个问题并且可以帮助我如何用更好的解决方案解决这个问题?
这可能需要更长的时间,但这是另一种方法。首先,设计您的协议,使每个命令都包含(或可以包含)一个 ID,并且板只响应其 ID 的命令。然后,在您的主机上,您将遍历每个可能的 ID,并向每个 ID 发送一个简单的命令。如果您收到回复,您就知道有一个带有该 ID 的板。如果你在一段时间后没有收到回复,你就知道那里没有董事会。
您在问题中提到了 Modbus,尽管您陈述的其他一些事实似乎与此有所不同(例如 4 位设备编号,而 Modbus 只有 1-255)。此外,Modbus 不 支持对广播消息的响应。因此,我有点怀疑你是否真的在使用 Modbus。
您可以使用的方案(通常在 MA 网络中使用)是:
- 接收到广播后,让客户端根据站点 ID 扫描总线以在一定时间范围内寻找响应。如果您的客户端可以看到一个,请让它等待最短总线时间(模块需要根据当前总线时间回复您的广播消息的时间 + 主机确认广播应答的往返时间)加上基于其模块的额外时间ID,然后回到(1)
- 如果客户端发现总线在指定时间内未被占用,则发回广播应答。
- 让主人用尽可能短的消息确认来自此客户端的广播响应。
- 如果发送了广播响应的客户端没有收到正确的ack,回到(1)
这不是 100% 安全,绝对不符合 Modbus 规范,但可以工作。
* is a transmission, - is a "wait"
**** (Bus master broadcast)
--------- station 100 waits 100ms
------------------ station 200 waits 200ms
**** Station 100 sends broadcast response
------------------ station 200 sees bus active and waits another 200ms
*** master acknowledges broadcast response of 100
------------------ station 200 sees bus active again and waits 200ms from last seen activity
**** Station 200 has seen bus quiet for 200ms and sends broadcast response
*** master acks brc response of 200
这可能会花费相当多的时间,并且需要根据广播响应和响应 ack 的传输时间对等待时间进行精细调整,但可以工作,并且实际上在很多 CSMA/CD 中都是以这种方式实现的网络。
我有一台计算机(用作服务器)和几块带有 Atmega
微控制器的电路板,例如:
计算机连接到 UART
和 RS485
上的电路板(使用 USB
到 RS485
转换器)(我有导致 无法使用 ModBus)。我想通过总线从服务器广播消息并从每个板获取ID(板ID是4位)。
当板子收到广播消息并尝试发送它们自己的 ID 而服务器收到一些假 ID 时,我认为这与所有板子都想在 一次发送数据时的冲突问题有关.
在我搜索这个问题后,我找到了一种方法,可以在每个板中放置一个常量,为发送数据保存一个特殊的延迟,并且当板接收广播消息发送 ID 时具有该延迟......这样它工作正常并且我没有看到碰撞,但有一些问题:
- 可能是2块板的延迟数相同
- 小板数的好方法。
- 在总线上安装板卡时的额外过程。
任何人都知道这个问题并且可以帮助我如何用更好的解决方案解决这个问题?
这可能需要更长的时间,但这是另一种方法。首先,设计您的协议,使每个命令都包含(或可以包含)一个 ID,并且板只响应其 ID 的命令。然后,在您的主机上,您将遍历每个可能的 ID,并向每个 ID 发送一个简单的命令。如果您收到回复,您就知道有一个带有该 ID 的板。如果你在一段时间后没有收到回复,你就知道那里没有董事会。
您在问题中提到了 Modbus,尽管您陈述的其他一些事实似乎与此有所不同(例如 4 位设备编号,而 Modbus 只有 1-255)。此外,Modbus 不 支持对广播消息的响应。因此,我有点怀疑你是否真的在使用 Modbus。
您可以使用的方案(通常在 MA 网络中使用)是:
- 接收到广播后,让客户端根据站点 ID 扫描总线以在一定时间范围内寻找响应。如果您的客户端可以看到一个,请让它等待最短总线时间(模块需要根据当前总线时间回复您的广播消息的时间 + 主机确认广播应答的往返时间)加上基于其模块的额外时间ID,然后回到(1)
- 如果客户端发现总线在指定时间内未被占用,则发回广播应答。
- 让主人用尽可能短的消息确认来自此客户端的广播响应。
- 如果发送了广播响应的客户端没有收到正确的ack,回到(1)
这不是 100% 安全,绝对不符合 Modbus 规范,但可以工作。
* is a transmission, - is a "wait"
**** (Bus master broadcast)
--------- station 100 waits 100ms
------------------ station 200 waits 200ms
**** Station 100 sends broadcast response
------------------ station 200 sees bus active and waits another 200ms
*** master acknowledges broadcast response of 100
------------------ station 200 sees bus active again and waits 200ms from last seen activity
**** Station 200 has seen bus quiet for 200ms and sends broadcast response
*** master acks brc response of 200
这可能会花费相当多的时间,并且需要根据广播响应和响应 ack 的传输时间对等待时间进行精细调整,但可以工作,并且实际上在很多 CSMA/CD 中都是以这种方式实现的网络。