Collision 在UART上广播和获取数据

Collision 在UART上广播和获取数据,collision,avr,uart,atmega,rs485,Collision,Avr,Uart,Atmega,Rs485,我有一台计算机(用作服务器)和几块带有Atmega微控制器的板,比如: 计算机连接到UART和RS485(使用USB到RS485转换器)上的板(我有限制,导致我无法使用ModBus)。我想通过总线从服务器广播一条消息,并从每个电路板上获取ID(电路板ID为4位) 当线路板收到广播消息并试图发送自己的ID,而服务器收到一些假ID时,我认为这与所有线路板希望一次发送数据时的冲突问题有关 在我搜索这个问题后,我找到了一种方法,在每个电路板中放置一个常数,为发送数据保存一个特殊的延迟,当电路板接收到广

我有一台计算机(用作服务器)和几块带有
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网络中都是这样实现的。

    在共享总线上同时有多个站点应答广播是个坏主意。在客户端电路板中,您是否有一些逻辑,在他们尝试访问总线以获取答案(这将是CSMA/CD的“CSMA”部分)之前,尝试检测总线当前是否已被占用?…并且服务器接收到一些假ID”-听起来您需要实施更好的消息完整性检查。“但在完全的it中工作正常”--那么你的期望值很低,你应该这样做,对吗?@sawdust和服务器收到一些假ID:我发现查找假ID有错误,但我的问题是如何防止客户端发送假ID…\u但在完全的it中工作正常\u是的,它工作正常,但有我所说的问题。。主要问题可能是2块板的延迟数相同。它再次导致冲突…“我在查找假ID时发现错误”--而不是“查找假ID”,您应该能够检测任何类型的消息冲突,例如通过使用CRC等消息验证。“完全可以”是的,可以,但是…--你没有意识到你在自相矛盾。有些东西“完全起作用”,或者根本不起作用;没有但是。“线路板ID为4位”--一条RS-485线路上是否有10000个可能的线路板?为什么不使用Modbus从机ID,它只有8位?看起来你们并没有正确地分层你们的协议。关于查找假ID,我认为最好在从板上发送ID时查找冲突,而不是在服务器上查找假ID,即使是像CRC这样的验证也可能在服务器上找到假ID。我将这部分“完全工作”替换为“这样工作很好,我看不到冲突,但有一些问题:”关于为什么不使用Modbus从ID,我在板上有限制,不能使用这种方式。你开始觉得你没有正确地分层你的协议,我通过UART协议逐字节发送数据…继续,但设备有随机ID。你知道一个特殊的框架,为这个原因设计一个协议吗?你在回答中说,我可以通过一个板的ID发送命令。但我不知道它们的ID无论如何,他们有一个随机生成的ID,并存储在其中。当我有板的ID列表时,你的方法是可以的。另一件事是我想向板广播消息。不是单播。我的回答解释说你会尝试每个可能的ID。因此,如果您知道ID始终在0和127之间,您可以尝试0,然后尝试1,然后尝试2,等等。这样您就不必提前知道ID。你想要广播的欲望并不那么重要;主要的问题是,你想弄清楚这些电路板有什么ID,你正试图找到解决这个问题的方法。在系统计算出ID后,它可以广播或执行任何您想要的协议