简体   繁体   English

射频马达/伺服控制

[英]RF motor/servo control

I have been wrecking my head over this the last weeks and cannot find useful information online on how I should do this. 在过去的几周中,我一直很头疼,无法在网上找到有关如何执行此操作的有用信息。

The Goal: 目标:

  • Drive several servo/RC motors wireless from one pi to another pi . 从一个驱动器几个伺服/ RC电机无线 pi到另一个pi
  • In essence, I want to build a RC remote control using a pi , with a second pi on the receiver end. 本质上,我想使用pi构建一个RC遥控器,并在接收器端添加第二个pi

What I have done so far: 到目前为止,我所做的是:

  • I have been able to use the serial library and the Tx and Rx pins on the two Pi to successfully send serial data over a cheap 433MHz receiver/transmitter. 我已经能够使用串行库以及两个Pi上的Tx和Rx引脚通过便宜的433MHz接收器/发送器成功发送串行数据。 However, I need to send over at least six pairs of two-digit numbers simultaneously(ie 12 numbers). 但是,我需要同时发送至少六对两位数字(即12个数字)。 This can be done using the serial library on the pi/arduino , but it causes the sample rate of the main continuous program loop to slow down to below 200Hz, which is a problem. 可以使用pi/arduino上的串行库完成此操作,但是这会导致主连续程序循环的采样率降低到200Hz以下,这是一个问题。

Next step and problems: 下一步和问题:

  • Since the serial data transmission is not working adequately I was thinking of embedding PWM signals directly into the RF signal. 由于串行数据传输无法正常工作,因此我考虑将PWM信号直接嵌入到RF信号中。 (As far as I can figure out this is how the hobby RC controllers work anyway). (据我所知,这是业余RC控制器的工作方式)。
  • The pi (as far as I know) is rubbish at sending accurate PWM signals and even worse at picking them up correctly. pi (据我所知)在发送准确的PWM信号方面是垃圾,而在正确地接收它们方面则更糟。
  • Just to clarify I have to do this over a RF module, not over the web. 只是为了澄清一下,我必须通过RF模块而不是通过Web进行此操作。

How can I do this? 我怎样才能做到这一点?

Perhaps using two Arduinos to do the transmission and receiving? 也许使用两个Arduino进行发送和接收?

Are there "shields" that I could buy? 有没有我可以买的“防护罩”?

Are there libraries that could do this for me? 有图书馆可以帮我吗? ( Pi or adruino ?) Pi还是adruino ?)

Edited: Roland thank you for your reply 编辑:罗兰谢谢您的答复

I have added the current serial transmission code. 我已经添加了当前的串行传输代码。 I dont think this is the most efficient way of doing it. 我不认为这是最有效的方法。 If one transmits PWM signals with a pause between another PWM signal one can send far more data instead of just sending bits. 如果一个人发送的PWM信号在另一个PWM信号之间停顿,则可以发送更多的数据,而不仅仅是发送位。 I am not entirely sure, but I thought that is how the Remote Control RC aircraft controllers send their signals. 我不确定,但是我认为这就是遥控遥控飞机控制器发送信号的方式。

Please note that the code I have inserted is a simple extract from a much larger program with several modules and a couple of hundred lines of code. 请注意,我插入的代码是从一个较大的程序中提取的简单代码,该程序具有多个模块和几百行代码。 I do think the few lines below are at the heart of the serial transmitter. 我确实认为以下几行是串行发送器的核心。

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

Serial baud rate 串行波特率

In your comment you mention a baud rate of 4800. That is very low for a serial port. 在您的评论中,您提到4800的波特率。对于串行端口来说,这是非常低的。 Serial ports use two-level (binary) signaling, so the data rate in bits per second is equal to the symbol rate in baud. 串行端口使用两级(二进制)信令,因此以比特/秒为单位的数据速率等于以波特为单位的符号率。

But one data-sheet I looked at for a transceiver listed 5 kbits/s as a typical transfer speed, and 9.6 kbit/s as the maximum rate. 但是我查看了一个数据手册,该收发器列出了典型的传输速度为5 kbit / s,最大速率为9.6 kbit / s。 Maybe you could try improving the antennae to up the transfer rate? 也许您可以尝试改进天线以提高传输速率?

But 4800 baud serial means you won't get more than 4800/8 = 600 bytes/s bandwidth (and that is disregarding things like stop bits and parity bits). 但是4800波特串行意味着您将不会获得超过4800/8 = 600字节/秒的带宽(而这忽略了停止位和奇偶校验位之类的东西)。 With a 10 byte message you should get at most 60Hz. 带有10个字节的消息,您最多应获得60Hz的频率。 A 5-byte message could improve that to 120 Hz. 5字节的消息可以将其提高到120 Hz。 So it seems that the transmitter is the limiting factor. 因此,似乎发射机是限制因素。

This means you have to be frugal with every bit! 这意味着您必须节俭!

Packing the data 打包数据

Your code transmits the data as a concatenated decimal string. 您的代码将数据作为连接的十进制字符串传输。 For 5 numbers this takes 10 bytes. 对于5个数字,这需要10个字节。 It is possible to cut this in half: 可以将其切成两半:

Let's generate 5 2-digit numbers in the range 0-100. 让我们生成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]

Two digit decimal numbers just need one byte to store them. 两位十进制数字只需要一个字节即可存储它们。 Even two-digit hexadecimal numbers would fit in a byte. 甚至两位十六进制数字也可以容纳一个字节。 So let's combine the numbers into a byte string. 因此,让我们将数字组合成一个字节字符串。

In [4]: import struct

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

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

You could send this 5-byte string in a single serial write call, and unpack them on the receiving end. 您可以在单个串行write调用中发送此5字节字符串,然后在接收端将其解压缩。

Let's compare the two concpts wrt speed. 让我们比较一下两个概念。 I have wrapped both your original code and my struct solution in functions, so I can easily use IPython's %timeit magic command to measure them. 我已经将您的原始代码和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

(This is on an intel core2 processor. The ARM chip in the Pi will probably be slower.) Generating the binary string takes approximately 25% less time than generating the text string. (这是英特尔酷处理器。在ARM芯片Pi可能会比较慢。)产生的二进制串花费比生成所述文本串时间少约25%。

But from these times you can see that these are probably not performance critical. 但是,从这些时候,你可以看到,这些可能不是性能的关键。 They can assemble data at >30 kHz. 它们可以以> 30 kHz的频率汇编数据。 The Pi would have to be 150 times slower for this to be time-critical. Pi必须慢150倍才能成为时间关键。

What is important is the binary string is half as long as the text string, so I would expect it to transmit approximately twice as fast. 重要的是二进制字符串的长度是文本字符串的一半,因此我希望它的传输速度大约是文本字符串的两倍。

What you should carefully think about is how many different signal levels do you actually need for each signal? 您应该仔细考虑的是,每个信号实际上需要多少个不同的信号电平? Four bits give you 2⁴ = 16 levels, while 8 bits give you 2⁸ = 256 levels. 四位给您2⁴= 16级,而八位给您2⁸= 256级。 If your application could live with 16 signal levels, you could pack your messages in 5*4= 20 bits. 如果您的应用程序可以使用16个信号电平,则可以将消息打包为5 * 4 = 20位。

(Posted on behalf of the OP) . (代表OP张贴)

I have solved the serial data transmission problem explained above. 我已经解决了上面解释的串行数据传输问题。 For exact details go to another post of mine: Serial data transmission input-output delay with Raspberry Pi 有关确切的详细信息,请转到我的另一篇文章:Raspberry Pi的串行数据传输输入/输出延迟

I hope this helps anyone. 我希望这对任何人都有帮助。 This way you can transmit data over a serial connection whether over a RF link module or over direct wiring with no time delay. 这样,您可以通过串行连接传输数据,无论是通过RF链接模块还是通过直接接线,都没有时间延迟。

Please note that a lot of the RF link modules have a max transfer rate of 4800baud for a stable and good connection. 请注意,许多射频链接模块的最大传输速率为4800波特,以实现稳定和良好的连接。

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

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