繁体   English   中英

射频马达/伺服控制

[英]RF motor/servo control

在过去的几周中,我一直很头疼,无法在网上找到有关如何执行此操作的有用信息。

目标:

  • 从一个驱动器几个伺服/ RC电机无线 pi到另一个pi
  • 本质上,我想使用pi构建一个RC遥控器,并在接收器端添加第二个pi

到目前为止,我所做的是:

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

下一步和问题:

  • 由于串行数据传输无法正常工作,因此我考虑将PWM信号直接嵌入到RF信号中。 (据我所知,这是业余RC控制器的工作方式)。
  • pi (据我所知)在发送准确的PWM信号方面是垃圾,而在正确地接收它们方面则更糟。
  • 只是为了澄清一下,我必须通过RF模块而不是通过Web进行此操作。

我怎样才能做到这一点?

也许使用两个Arduino进行发送和接收?

有没有我可以买的“防护罩”?

有图书馆可以帮我吗? Pi还是adruino ?)

编辑:罗兰谢谢您的答复

我已经添加了当前的串行传输代码。 我不认为这是最有效的方法。 如果一个人发送的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

串行波特率

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

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

但是4800波特串行意味着您将不会获得超过4800/8 = 600字节/秒的带宽(而这忽略了停止位和奇偶校验位之类的东西)。 带有10个字节的消息,您最多应获得60Hz的频率。 5字节的消息可以将其提高到120 Hz。 因此,似乎发射机是限制因素。

这意味着您必须节俭!

打包数据

您的代码将数据作为连接的十进制字符串传输。 对于5个数字,这需要10个字节。 可以将其切成两半:

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

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]

两位十进制数字只需要一个字节即可存储它们。 甚至两位十六进制数字也可以容纳一个字节。 因此,让我们将数字组合成一个字节字符串。

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 magic命令来对其进行度量。

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

(这是英特尔酷处理器。在ARM芯片Pi可能会比较慢。)产生的二进制串花费比生成所述文本串时间少约25%。

但是,从这些时候,你可以看到,这些可能不是性能的关键。 它们可以以> 30 kHz的频率汇编数据。 Pi必须慢150倍才能成为时间关键。

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

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

(代表OP张贴)

我已经解决了上面解释的串行数据传输问题。 有关确切的详细信息,请转到我的另一篇文章:Raspberry Pi的串行数据传输输入/输出延迟

我希望这对任何人都有帮助。 这样,您可以通过串行连接传输数据,无论是通过RF链接模块还是通过直接接线,都没有时间延迟。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM