相当复杂的传感器网络


9

我最近正在从事一个项目,这是第一个涉及到足够使传感器网络复杂化的项目。最后,我认为沟通是整体绩效的瓶颈,我想知道更有经验的人会如何解决这个问题。这是一本长篇小说,但我认为这很有趣,因此请坚持使用。问题是设计一种自主飞艇,该飞艇能够导航障碍物路线并将乒乓球放入棕色盒子目标中。开始:

感测器

  • 4D Systems uCAM-TTL摄像机模块-UART接口
  • HMC6352数字罗盘-I2C接口
  • Maxbotix Sonar ez4-1针模拟接口

执行器

  • 2个L293D电动机驱动器(连接到简单的爱好电动机)-用于双向驱动6个电动机。他们需要PWM输入才能改变速度。现在,我们的3台电机始终在做相同的事情(控制上下运动的电机),因此它们仅需要我们控制器的2个PWM输出即可控制所有3台电机。其他3个控制横向运动的电机都需要单独控制(全向运动),因此我们的控制器还需要另外6个PWM输出。
  • 伺服电机-PWM接口

控制器

由于稍后将变得清楚的原因,我们最终使用了2个ATmega328P。我们使用Arduino Uno对其进行编程(我们无法访问ISP),但是我们制造了定制PCB,因此我们不必使用arduino板,因为这只会给飞艇增加不必要的重量。至于我们为什么选择ATmega328P的原因,我对arduino环境非常熟悉,我认为这使代码开发变得更快,更容易。

通讯与处理

  • 2个Xbee Basic
  • 2个ATmega328P
  • 带有OpenCV的运行C ++的台式计算机

因此,从相机模块可以看出,我们的大多数项目都依赖于计算机视觉。飞艇只能承载这么多的重量,而在微控制器上实现计算机视觉使我们感到不舒服。因此,我们最终要做的是使用XBee将图像数据中继回台式计算机。因此,在服务器端,我们接收到图像数据,并使用openCV处理图像并从中提取出东西。现在,服务器端还需要知道(来自声纳)的高度信息和指南针信息。

首先的麻烦是由于几个原因,我们无法使相机由微控制器控制。主要问题是uP上的内部存储器无法处理存储整个帧。通过聪明的编码可能有解决此问题的方法,但是出于这个问题的目的,让我们假装这是不可能的。因此,为了解决此问题,我们让服务器端通过XBee收发器发送摄像机命令,而XBee接收器(在飞船上)将其输出连接到摄像机的输入。

下一个难题是,单个ATmega328P上没有足够的PWM来控制所有电机,因为I2C接口使用PWM引脚之一(该死的...)。这就是为什么我们决定使用第二个。该代码实际上实际上完全适合于并行处理,因为高度控制完全独立于横向运动控制(因此2微米可能比连接到PWM控制器的1微米更好)。因此,U1负责2个PWM输出(向上/向下)并读取声纳。U2负责读取指南针,控制6个PWM输出(横向电机)以及读取声纳。U2还负责通过XBee从服务器接收命令。

这导致了我们的第一个沟通问题。XBee DOUT线已连接到微控制器和摄像机。当然,现在我们设计了一个协议,这样我们的微命令将忽略摄像头命令,而摄像头命令将忽略微命令,这样很好。但是,当忽略我们的微指令时,相机会在其输出线上发送回NAK数据。由于该命令是针对微型计算机的,因此我们需要某种方式来关闭相机输出到XBee的功能。为了解决这个问题,我们在相机和XBee(即第一个FET)之间以及在U2和XBee(即第二个FET)之间制作了微控2 FET。因此,当摄像机尝试将信息发送回服务器时,第一个FET为“开”,第二个FET为“关”。

因此,让您大致了解这是如何工作的几个示例:

  1. 服务器请求图片-PIC_REQUEST通过XBee到达U2和摄像机。U2会忽略它,并且相机会发回图像数据。
  2. 服务器刚刚完成图片处理,并正在发送电机数据以告诉飞艇右转-MOTOR_ANGLE(70)通过XBee进入并到达U2和摄像机。U2识别为微指令,因此关闭了相机的FET(但是相机可能已经响应了NAK?谁知道...)。然后,U2通过更改电动机PWM输出来响应命令。然后,它将相机的FET重新打开(这是默认设置,因为图像数据非常重要)。
  3. 服务器意识到我们已经到达障碍物路线的某个位置,默认悬停高度现在需要从90英寸而不是50英寸。SET_HEIGHT通过XBee,与示例2相同。U2识别SET_HEIGHT命令并在U1上触发中断。U1现在退出其高度控制循环,并等待从U2接收串行数据。是的,更多串行数据。此时,U2的FET处于打开状态(而相机的FET处于关闭状态),因此服务器将接收U2也发送到U1的高度。那是为了核实目的。现在,U1将其内部变量重置为height2HoverAt。U2现在关闭它的FET,然后重新打开相机的FET。

我肯定会遗漏大量信息,但是我认为这足以理解一些并发症。最后,我们的问题只是同步所有内容。有时缓冲区中会剩下数据,但是只有3个字节(我们所有的命令都是6个字节序列)。有时我们会失去与相机的连接,必须重新同步。

所以我的问题是:你们建议采用什么技术使所有这些组件之间的通信更可靠/更健壮/更简单/更好?

例如,我知道有人会在板载XBee输出和摄像头之间添加一个延迟电路,以便微机有机会在用NAK响应微指令之前关闭摄像头的通话线路。还有其他想法吗?

谢谢,我确定这将需要进行许多修改,敬请期待。


编辑1:对我们来说,通过微型镜之一拼接摄像机的UART数据似乎是不可能的。相机数据有两个选项:原始位图或JPEG。对于原始位图,相机会尽可能快地向您发送数据。ATmega328P仅具有128字节的串行缓冲区(从技术上讲这是可配置的,但我不确定如何配置),我们认为我们无法将其从缓冲区中取出并足够快地传送到XBee。这就留下了JPEG方法,该方法将它发送到每个包并等待控制器对其进行确认(小的握手协议)。最快速度为115200波特。现在由于某种原因,我们能够通过XBee可靠地传输大量数据的最快速度是57600波特(甚至在我们进行了节点/网络配对以允许自动重发功能之后)。在我们的网络中添加额外的停靠点(将摄像机连接到XBee的微型摄像机,而不是将摄像机连接到XBee的微型摄像机),只会减慢传输过多图像所需的时间。为了使电机控制算法正常工作,我们需要在图像上具有一定的刷新率。


3
您在不扩展微控制器技能方面付出了很多努力。我没有反对Arduino的任何东西,但是那不是很合适。您最终可以使它正常工作吗?大概。但是,学习功能更强大的平台会更加有用。如果您想问更多有经验的人会怎么做,我会说一些类似的东西,例如用于openCV和控制的ARM SBC,以及用作所有接口的桥梁的FPGA。但是,这可能会有点跳跃,所以我建议您尝试一个新的重大尝试...也许是一个具有足够外围设备来连接所有内容的32位微型计算机?
darron 2011年

哈哈,是的,我要竭尽全力。看到这个项目是学校的任务,我们希望专注于使其工作,而不是让团队中的两个EE之一学习新的微控制器平台。我实际上正在考虑今年夏天加入ARM和更高级的micros。我们团队中的另一位EE实际上已经上过FPGA课程。。。我会大吼他,因为他不建议= P
NickHalden 2011年

Answers:


4

我知道您想选择一个熟悉的开发环境,这样您就可以开始运行,但是我认为,在硬件/软件之间进行权衡可能会因为坚持使用Arduino而没有选择一个具有全部功能的零件而使您陷入困境您所需的硬件外设,并用中断驱动的C编写所有内容。

我同意@Matt Jenkins的建议,并希望对此进行扩展。

我会选择带有2个UART的uC。一台连接到Xbee,另一台连接到相机。uC接受来自服务器的命令以启动摄像头读取,并且可以编写例程以逐字节为单位将数据从摄像头UART通道传输到XBee UART通道-因此没有缓冲区(或者最多只有很小的缓冲区)一)需要。我会尝试通过选择一个也能满足您所有PWM需求(8个PWM通道?)的零件来消除其他uC,如果您想坚持使用2个不同的uC来照顾它们各自的轴,那么也许不同的通信接口会更好,因为您将采用所有其他UART。

其他人也建议转移到嵌入式linux平台上以运行所有内容(包括openCV),我认为这也将是值得探索的东西。不过,我之前去过那里,一个为期4个月的学校项目,您只需要尽快完成它,就不会因分析而陷入瘫痪状态-我希望结果对您来说还行!


编辑#1 回复@JGord的评论:

我做了一个使用ATmega164p实现UART转发的项目。它具有2个UART。这是该项目的逻辑分析仪捕获(Saleae USB逻辑分析仪)的图像,显​​示了UART转发: 分析仪捕获

第一行是源数据(在这种情况下,它将是您的相机),下一行是被转发到的UART通道(在您的情况下为XBee)。为此编写的例程处理了UART接收中断。现在,您是否相信在进行UART转发时,您可以愉快地配置PWM通道并处理I2C例程?让我解释一下。

每个UART外设(无论如何对于我的AVR而言)都由几个移位寄存器,一个数据寄存器和一个控制/状态寄存器组成。如果满足以下任一条件,则该硬件将自行执行操作(假设您已经初始化了波特率等):

  1. 一个字节进来或
  2. 字节放置在其数据寄存器中并标记为输出

这里重要的是移位寄存器和数据寄存器。假设在UART0上有一个字节进入,我们想将该流量转发到UART1的输出。当一个新字节移入UART0的输入移位寄存器后,它将被传输到UART0数据寄存器,并触发UART0接收中断。如果您已经为其写了一个ISR,则可以将UART0数据寄存器中的字节移到UART1数据寄存器中,然后将UART1的控制寄存器设置为开始传输。它的作用是告诉UART1外设将您刚刚放入其数据寄存器的所有内容放入其输出移位寄存器,然后开始将其移出。从这里,您可以退出ISR,返回到uC被中断之前正在执行的任务。现在是UART0,如果只清除了移位寄存器,并且清除了数据寄存器,则可以在ISR期间开始转移新数据(如果尚未这样做),而UART1正在移出您刚刚放入的字节-所有这些都发生在在您的uC关闭其他任务时无需您的干预即可自行完成。整个ISR需要几微秒的时间执行,因为我们只在某个内存上移动了1个字节,所以这留出了大量的时间进行其他事情,直到UART0的下一个字节进入为止(这需要100微秒)。UART1正在移出您刚刚放入的字节-所有这些都是在您的uC关闭执行其他任务的情况下自行发生的,无需您干预。整个ISR需要几微秒的时间执行,因为我们只在某个内存上移动了1个字节,所以这留出了大量的时间进行其他事情,直到UART0的下一个字节进入为止(这需要100微秒)。UART1正在移出您刚刚放入的字节-所有这些都是在您的uC关闭执行其他任务的情况下自行发生的,无需您干预。整个ISR需要几微秒的时间执行,因为我们只在某个内存上移动了1个字节,所以这留出了大量的时间进行其他事情,直到UART0的下一个字节进入为止(这需要100微秒)。

拥有硬件外围设备的好处是-您只需将其写入一些内存映射寄存器中,它将处理其余的内容,并会通过中断(如我上面刚刚解释的中断)发出信号,引起您的注意。每当UART0上有一个新字节进入时,该过程就会发生。

请注意,逻辑捕获中的延迟只有1个字节,因为如果您想那样的话,我们只会“缓冲” 1个字节。我不确定您是如何得出O(2N)估计的-我将假设您已将Arduino串行库函数放置在等待数据的阻塞循环中。如果考虑到必须在uC上处理“读取摄像机”命令的开销,则中断驱动方法更像O(N+c)c包含单字节延迟和“读取摄像机”指令的地方。考虑到您要发送大量数据(图像数据对吗?),这将非常小。

有关UART外设的所有详细信息(以及uC上的每个外设)已在数据表中进行了详细说明,并且都可以用C进行访问。我不知道Arduino环境是否会给您这么低的访问权限,以便您可以开始访问注册-就是这样-如果不是这样,您会受到其实现的限制。如果您使用C编写了所有内容,那么您将掌控一切(如果在汇编中完成,甚至可以做到),并且可以真正将微控制器推向真正的潜力。


我想我解释得不好。将微型计算机置于相机和XBee之间的问题在于,微型计算机在获取图像数据时无法执行任何其他操作,除非其他所有定时器中断。此外,如果您假设获得一张N像素的图片需要5秒钟,那么当您将其放入微距镜时,则需要10秒钟。确保它仍然是O(N),但实际上是2N运行时,在这种情况下足以破坏我们的刷新率目标。最终,内存空间并不是真正的限制因素,主要是速度。叹气,这似乎是唯一的真实答案……
NickHalden

是使用更先进的硬件。我希望有人能提出一些非常聪明的建议,这将成为我从事EE多年的便利。哦,好吧,我想至少意味着我不太傻,以至于不能想到这个技巧= P哦,它的工作效果很好。
NickHalden

@JGord,碰巧,我做了一个使用UART转发的项目,就像我在描述使用ATmega164在芯片卡和洗衣机之间描述的方式jonathan-lee.ca/DC18-Smart-Card.html我在说的是使用UART ISR将单个字节从UART数据寄存器移至另一个UART的数据寄存器,然后返回。UART硬件独立运行,并从那里移出数据。ISR需要几微秒的时间,从ISR返回后,uC可以自由地做任何想做的事情,直到移入下一个字节为止。每当我回到家时,都会有一个更好的解释。
乔恩·L

有趣。那么,您的建议是让服务器仅与微控制器通信吗?然后,那个微中继从服务器到摄像机的命令以及从摄像机到服务器的响应?因此,在UART0 ISR(与服务器端通信)中,我可以检查其是否为照相机命令。如果是,则将UART1镜像到摄像机。如果不是,则不要镜像,而是更改一些值(例如,边角,高度等,我的控制循环要检查的某些变量。)然后UART1的ISR将总是简单地将图像数据镜像到UART0上。是的,我想那行得通。因此,实际上只有一个带有2个UART的微
控制器

足够的PWM通道本来应该是这样。因此,现在让我们假设服务器发送了一个get_data请求,微型计算机应该以6个字节的序列进行响应,在该请求中,它发送高度,罗盘方向和一些ECC。由于某种原因,它们的服务器读取6个字节,但是它们没有正确的协议,即,开始和结束消息字节未对齐。谁知道为什么?您只是将味精扔出去然后再次请求还是什么?因为如果缓冲区中有一些伪字节,那么6字节消息将永远不会再次对齐?您是否建议在味精失败后进行冲洗?
NickHalden

1

为什么不能通过µC传送摄像机数据?我并不是要缓冲图像,而是通过µC中继UART数据,以便它可以决定应该发回什么以及不应该发回什么?

如果您有一个带有两个UART的µC,最简单的方法是在软件中进行仿真。


嗯,那是我遗漏的事情之一...现在编辑问题。好主意,当我们想到这一点时,我们也很兴奋。
NickHalden

1

我想到了另一种选择,但这对于您的项目而言可能有点笨重和沉重:-

  • 为什么不使用通过USB-> RS232适配器连接到小型USB集线器的无线USB服务器来为系统的不同部分提供多个控制通道?

是的,体积庞大,但是如果将它们拆下来,并在可能的情况下使用USB代替RS232,则可能会摆脱它...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.