射频电机/伺服控制器

2024-09-27 17:43:57 发布

您现在位置:Python中文网/ 问答频道 /正文

最近几周,我一直在为此绞尽脑汁,在网上找不到关于我应该如何做的有用信息。在

目标:

  • 从一个pi到另一个pi驱动多个伺服/RC电机无线。在
  • 本质上,我想使用pi构建一个RC远程控制,在接收端有第二个pi。在

我目前所做的:

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

下一步和问题:

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

我该怎么做?在

也许用两个Arduinos来完成传输和接收?在

我能买到“盾牌”吗?在

有图书馆可以帮我吗?(Piadruino?)在

编辑:罗兰感谢您的回复

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

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

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

Tags: 模块数据代码程序trueformat信号pi
2条回答

串行波特率

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

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

但是4800波特串行意味着你不会得到超过4800/8=600字节/秒的带宽(这是忽略停止位和奇偶校验位之类的东西)。对于一个10字节的消息,你应该得到最多60Hz。一条5字节的信息可以将其提高到120赫兹。看来发射机是限制因素。在

这意味着你必须节约每一点!在

打包数据

代码以连接的十进制字符串的形式传输数据。对于5个数字,这需要10个字节。可以将其一分为二:

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

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]

两位数的十进制数只需要一个字节就可以存储它们。即使是两位数的十六进制数也能容纳一个字节。让我们把这些数字合并成一个字节串。在

^{pr2}$

您可以在一个串行的write调用中发送这个5字节的字符串,并在接收端解包它们。在

让我们比较一下这两种情况下的速度。我已经将您的原始代码和我的struct解决方案包装在函数中,因此我可以轻松地使用IPython的%timeit魔术命令来测量它们。在

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

(在intel core2处理器上。Pi中的ARM芯片可能会慢一些。)生成二进制字符串所需的时间大约比生成文本字符串少25%。在

但从这些时候你可以看出,它们对性能并不重要。它们可以以大于30 kHz的频率收集数据。Pi必须慢150倍才能达到时间关键。在

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

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

(代表运营商发布)。在

我已经解决了上面解释的串行数据传输问题。具体细节请参考我的另一篇文章:串行数据传输输入输出延迟与树莓派

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

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

相关问题 更多 >

    热门问题