首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >射频电机/伺服控制

射频电机/伺服控制
EN

Stack Overflow用户
提问于 2016-05-16 08:45:13
回答 2查看 427关注 0票数 0

在过去的几个星期里,我一直在沉溺于这个问题上,无法在网上找到有用的信息,说明我该怎么做。

目标:

  • 驱动多个伺服/RC马达无线从一个pi到另一个pi
  • 本质上,我希望使用RC构建一个pi远程控制,接收端有第二个pi

到目前为止我所做的:

  • 我已经能够使用串行库和两个Pi上的Tx和Rx引脚成功地通过一个廉价的433 the接收机/发射机发送串行数据。然而,我需要同时发送至少六对两位数的数字(即12个数字).这可以使用pi/arduino上的串行库来完成,但是它会导致主连续程序循环的采样率降低到200 of以下,这是一个问题。

下一步和问题:

  • 由于串行数据传输不能正常工作,所以我考虑将PWM信号直接嵌入到射频信号中。(据我所知,这就是RC控制器的业余爱好。)
  • pi (据我所知)在发送精确的脉宽调制信号方面是垃圾,更糟糕的是正确地获取它们。
  • 为了澄清这一点,我必须通过一个射频模块,,而不是在网络上。

我该怎么做?

也许用两个阿杜亚诺来做传输和接收?

有我能买到的“盾牌”吗?

是否有库可以为我做到这一点?(Pi还是adruino?)

编辑: Roland谢谢您的回复

我已经添加了当前的串行传输代码。我认为这不是最有效的方法。如果在另一个PWM信号之间暂停发送PWM信号,则可以发送更多的数据,而不仅仅是发送比特。我不完全确定,但我想这就是遥控RC飞机控制器发送信号的方式。

请注意,我插入的代码是一个大得多的程序的一个简单的摘录,有几个模块和几百行代码。我确实认为下面的几行是串行发射机的核心。

代码语言:javascript
复制
import serial

bProgramLoop = True
while (bProgramLoop == True):

    #...lots of code...

    iThrustPort = int(fThrustPort)
    iThrustStrb = int(fThrustStrb)
    iThrustTail = int(fThrustTail)
    iPortMotorAngle = int(fPortMotorAngle) + 50
    iStrbMotorAngle = int(fStrbMotorAngle) + 50

    sPortMotorSignal = '{:02d}'.format(iThrustPort)
    sStrbMotorSignal = '{:02d}'.format(iThrustStrb)
    sTailMotorSignal = '{:02d}'.format(iThrustTail)
    sPortAngleSignal = '{:02d}'.format(iPortMotorAngle)
    sStrbAngleSignal = '{:02d}'.format(iStrbMotorAngle)

    sSignal = sPortMotorSignal + sStrbMotorSignal + sTailMotorSignal + sPortAngleSignal + sStrbAngleSignal

    oSer.write(sSignal) #where sSignal = 1234567890 for example or any combination of numbers from 0 to 9
EN

回答 2

Stack Overflow用户

发布于 2016-05-16 09:33:47

串行波特率

在你的评论中,你提到波特率为4800。这对于串行端口来说是非常低的。串行端口使用两级(二进制)信令,因此每秒以位为单位的数据速率等于波特率中的符号速率。

但是我看了一个收发器的数据表,列出了5 kbit/s作为典型的传输速度,9.6 kbit/s作为最大传输速率。也许你可以试着改进天线来提高传输速率?

但是4800波特串行意味着你不会得到超过4800/8 = 600字节/秒的带宽(这不包括停止位和奇偶校验位)。有了10字节的消息,你最多可以得到60赫兹。一个5字节的消息可以提高到120赫兹.因此,发射机似乎是限制因素。

这意味着你必须节约每一分钱!

数据包装

您的代码以级联十进制字符串的形式传输数据。对于5个数字,这需要10个字节。有可能将其减半:

让我们在0-100范围内生成5个2位数的数字.

代码语言:javascript
复制
In [1]: import random

In [2]: data = [random.randint(0, 101) for _ in range(5)]

In [3]: data
Out[3]: [18, 80, 55, 96, 44]

两个数字的十进制数只需要一个字节来存储它们。即使是两位数的十六进制数也可以用一个字节来表示.让我们把数字组合成一个字节字符串。

代码语言:javascript
复制
In [4]: import struct

In [5]: struct.pack('5B', *data)
Out[5]: b'\x12P7`,'

In [6]: len(struct.pack('5B', *data))
Out[6]: 5

您可以在单个串行write调用中发送此5字节字符串,并在接收端解压它们。

让我们比较一下这两个节拍的速度。我已经用函数包装了您的原始代码和我的struct解决方案,所以我可以很容易地使用IPython的%timeit魔术命令来度量它们。

代码语言:javascript
复制
In [7]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:def astext():
:    data = [random.randint(0, 101) for _ in range(5)]
:    sPortMotorSignal = '{:02d}'.format(data[0])
:    sStrbMotorSignal = '{:02d}'.format(data[1])
:    sTailMotorSignal = '{:02d}'.format(data[2])
:    sPortAngleSignal = '{:02d}'.format(data[3])
:    sStrbAngleSignal = '{:02d}'.format(data[4])
:    sSignal = (sPortMotorSignal + sStrbMotorSignal + sTailMotorSignal +
:               sPortAngleSignal + sStrbAngleSignal)
:    return sSignal
:
:
:def asbinary():
:    data = [random.randint(0, 101) for _ in range(5)]
:    return struct.pack('5B', *data)
:--

In [8]: %timeit astext()
10000 loops, best of 3: 31.6 µs per loop

In [9]: %timeit asbinary()
10000 loops, best of 3: 23.5 µs per loop

In [10]: (31.6-23.5)/31.6
Out[10]: 0.2563

(这是在英特尔core2处理器上。Pi中的ARM芯片可能会慢一些。)生成二进制字符串比生成文本字符串花费的时间大约少25%。

但从这些时候,您可以看到,这些可能不是性能的关键。它们可以在>30 kHz的时候组装数据。要想做到时间紧迫,Pi必须慢150倍。

重要的是二进制字符串的长度是文本字符串的一半,所以我希望它的传输速度大约是文本字符串的两倍。

您应该仔细考虑的是,对于每个信号,实际需要多少个不同的信号级别?4位给出2⁴= 16级,8位给出2⁸=256个级别。如果您的应用程序可以使用16个信号级别,则可以将您的消息打包为5*4= 20位。

票数 0
EN

Stack Overflow用户

发布于 2016-05-29 10:04:33

(代表“任择议定书”张贴)。

解决了上述串行数据传输问题。有关详细信息,请转到我的另一篇文章:使用Raspberry Pi的串行数据传输输入输出延迟。

希望这对任何人都有帮助。通过这种方式,您可以在串行连接上传输数据,无论是通过RF链路模块还是通过直接布线,而不需要任何时间延迟。

请注意,许多射频链路模块的最大传输速率为4800波特,以稳定和良好的连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37249920

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档