📄 autopilot futaba pcm decoding.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0041)http://autopilot.sourceforge.net/pcm.html -->
<!-- START OF HEADER --><HTML><HEAD><TITLE>autopilot: Futaba PCM decoding</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META content="Autopilot for model helicopters, with 3 axis IMU/INS+GPS"
name=Description>
<META
content="autopilot,pcm,futaba,pcm1024,futaba pcm,helicopter,heli,model heli,model helicopter,remote control,uav,unmanned aerial vehicle,rpv,remotely piloted vehicle,aerial robot,ins,imu,gps,inertial measurement unit,inertial navigation system,attitude reference,ahrs,stabilization,automatic flight control system,afcs,linux,avr,microcontroller,pcb,servo,transmitter,telemetry,automatic stabilization system,source code,ins mechanization,strap down,strap down ins,strap down imu,strapdown ins,strapdown,strapdown imu,autonomous,automatic,automation,rotorcraft,rotor craft,rate integration,navigation,tactical,strategic"
name=Keywords><LINK rev="$Id: pcm.html,v 1.3 2003/02/03 19:42:41 tramm Exp $">
<STYLE type=text/css>BODY {
BACKGROUND: url(images/rotomotion.background.png) #ffffff fixed no-repeat right bottom; MARGIN: 0px
}
</STYLE>
<META content="MSHTML 6.00.2900.2802" name=GENERATOR></HEAD>
<BODY text=#000000 vLink=#af00a0 aLink=#00ff00 link=#0000ff bgColor=#ffffff
background="autopilot Futaba PCM decoding.files/rotomotion.background.png">
<TABLE width="100%" border=0>
<TBODY>
<TR>
<TD width=300 height=100><A
href="http://autopilot.sourceforge.net/index.html"><IMG height=100
alt="[ Concept 60 hovering ]"
src="autopilot Futaba PCM decoding.files/clouds-banner.jpg" width=300
align=left border=0></A></TD>
<TD>
<H2>autopilot: Do it yourself UAV</H2>
<HR>
<A href="http://autopilot.sourceforge.net/index.html">Home</A> | <A
href="http://autopilot.sourceforge.net/download.html">Download</A> | <A
href="http://autopilot.sourceforge.net/lists.html">Mailing lists</A> | <A
href="http://autopilot.sourceforge.net/gallery.html">Gallery</A> | <A
href="http://autopilot.sourceforge.net/faq.html">FAQ</A> | <A
href="http://autopilot.sourceforge.net/systems.html">Systems</A>
<HR>
</TD></TR></TBODY></TABLE><BR clear=all><!-- END OF HEADER --><!-- TITLE= autopilot: Futaba PCM decoding -->
<H1>PCM vs PPM</H1>
<P><A href="http://autopilot.sourceforge.net/images/ppm.jpg"><IMG height=33
alt="[ Image of PPM signal ]"
src="autopilot Futaba PCM decoding.files/ppm.small.jpg" width=100
align=left></A> The PPM radio protocol is a very simple serialization of the
servo PWM commands, separated by a 10 ms or longer syncronization pulse. In
order to decode it, simply wait for the sync pulse then clock the times between
the falling edges until the next sync pulse. Code to do this is in <A
href="http://autopilot.sourceforge.net/cgi-bin/source?onboard/rev2/ppm.h">onboard/rev2/ppm.h</A>.
<P>However, PPM fails very badly due to local RF noise such as spark plugs or
turbine ECUs. These can introduce spikes that cause servo jitter or even
erroneous servo commands. At long ranges the analog pulse widths are less
accurate as well, leading to jitter. The PPM radio receivers typically have no
onboard computers and rely totally on the transmitter to generate the servo
pulses. If you lose the transmitter, the servos stop holding their positions.
For all these reasons, a better protocol is required.
<P><A href="http://autopilot.sourceforge.net/images/pcm.png"><IMG height=15
alt="[ Image of PCM signal ]"
src="autopilot Futaba PCM decoding.files/pcm.small.png" width=100
align=left></A> PCM replaces the pulse widths with a serial bit stream that
encodes the servo commands as a binary value. An onboard microcontroller reads
the bit stream and generates its own servo commands from it. This MCU can hold
the servos in position if the transmitter is briefly out of contact with the
receiver and even set the servos into a preprogrammed "fail safe" position if
the transmitter is not heard from again after some timeout period.
<P>
<H1>PCM internals</H1>
<P>The actual encodings are considered trade secrets of each manufacturer and
they are not compatible across different brands. We have reverse engineered the
Futaba PCM1024 protocol and present our analysis here. This was done in a "clean
room" fashion using a Futaba 8U transmitter and a modified HiTec RCD3500
receiver to extract the bit stream. The receiver is actually a PPM unit, but the
RF front end is the same as the PCM model. Screen shots are of the Tek TDS2012
scope used to analyze the bit stream.
<H2>Frame protocol</H2>
<P>The PCM frame consists of four fields, each 28 ms long. Each field starts
with a 2.7 ms sync pulse of either high or low polarity, follwed either six or
eight bits of frame ID, then by four data packets of 40 bits each. Each of these
data packets consists of four 10 bit MSB words that are encoded with a <A
href="http://autopilot.sourceforge.net/pcm.html#6b10b">6B10B encoding</A>, to
produce 3 bytes of actual data per packet, 12 bytes per field and 48 bytes per
frame. From now on, we will assume that all data has been converted to the
natural representation.
<P>On the wire, the frame is transmitted like this (with sync pulses between
each of the fields):
<P>
<TABLE border=1>
<TBODY>
<TR>
<TD>0</TD>
<TD>1</TD>
<TD>2</TD>
<TD>3</TD>
<TD>4</TD>
<TD>5</TD>
<TD>6</TD>
<TD>7</TD>
<TD>8</TD>
<TD>9</TD>
<TD>10</TD>
<TD>11</TD>
<TD>12</TD>
<TD>13</TD>
<TD>14</TD>
<TD>15</TD>
<TD>16</TD>
<TD>17</TD>
<TD>18</TD>
<TD>19</TD>
<TD>20</TD>
<TD>22</TD>
<TD>22</TD>
<TD>23</TD>
<TD>24</TD>
<TD>25</TD>
<TD>26</TD>
<TD>27</TD>
<TD>28</TD>
<TD>29</TD>
<TD>30</TD>
<TD>32</TD>
<TD>32</TD>
<TD>33</TD>
<TD>34</TD>
<TD>35</TD>
<TD>36</TD>
<TD>37</TD>
<TD>38</TD>
<TD>39</TD>
<TD>40</TD>
<TD>42</TD>
<TD>42</TD>
<TD>43</TD>
<TD>44</TD>
<TD>45</TD>
<TD>46</TD>
<TD>47</TD>
<TD>48</TD>
<TD>49</TD>
<TD>50</TD>
<TD>52</TD>
<TD>52</TD>
<TD>53</TD>
<TD>54</TD>
<TD>55</TD></TR>
<TR>
<TD colSpan=56>PCM Frame</TD>
<TR>
<TD colSpan=2>Sync</TD>
<TD colSpan=12>Field 1</TD>
<TD colSpan=2>Sync</TD>
<TD colSpan=12>Field 2</TD>
<TD colSpan=2>Sync</TD>
<TD colSpan=12>Field 3</TD>
<TD colSpan=2>Sync</TD>
<TD colSpan=12>Field 4</TD></TR>
<TR>
<TD colSpan=2>LOW</TD>
<TD colSpan=3>1A</TD>
<TD colSpan=3>1B</TD>
<TD colSpan=3>1C</TD>
<TD colSpan=3>1D</TD>
<TD colSpan=2>LOW</TD>
<TD colSpan=3>2A</TD>
<TD colSpan=3>2B</TD>
<TD colSpan=3>2C</TD>
<TD colSpan=3>2D</TD>
<TD colSpan=2>HIGH</TD>
<TD colSpan=3>3A</TD>
<TD colSpan=3>3B</TD>
<TD colSpan=3>3C</TD>
<TD colSpan=3>3D</TD>
<TD colSpan=2>HIGH</TD>
<TD colSpan=3>4A</TD>
<TD colSpan=3>4B</TD>
<TD colSpan=3>4C</TD>
<TD colSpan=3>4D</TD></TR></TBODY></TABLE>
<P>The bit clock is 150 us. There does not appear to be any syncronization
mechanism other than the accuracy of the onboard clock. Bits are sampled roughly
25 us after a transition and there never appears to be a single bit alone
(minimum pulse width is 200 us). At first I thought the bit clock was 300 us,
but Coert L. showed me transitions that had to be sampled at the 150 us rate.
<P>I've numbered the four fields starting with the first low sync pulse. This is
because the fail safe data are transmitted twice, starting with the low sync
pulse. However, since the data are transmitted twice, it will overlap an entire
frame regardless of which ordering you use. There are two low sync pulse fields
(1 and 2), followed by two high sync pulse fields (3 and 4) which are nominally
logical inversions of the first two fields.
<H2>Data packets</H2>
<P>The data packet format consists of 2 bits of type selectors, 4 bits of
position delta, 10 bits of absolute position and 8 bits of checksum. Bit zero is
transmitted first:
<P>
<TABLE border=1>
<TBODY>
<TR>
<TD>0</TD>
<TD>1</TD>
<TD>2</TD>
<TD>3</TD>
<TD>4</TD>
<TD>5</TD>
<TD>6</TD>
<TD>7</TD>
<TD>8</TD>
<TD>9</TD>
<TD>10</TD>
<TD>11</TD>
<TD>12</TD>
<TD>13</TD>
<TD>14</TD>
<TD>15</TD>
<TD>16</TD>
<TD>17</TD>
<TD>18</TD>
<TD>19</TD>
<TD>20</TD>
<TD>21</TD>
<TD>22</TD>
<TD>23</TD></TR>
<TR>
<TD colSpan=2>Selector</TD>
<TD colSpan=4>Delta</TD>
<TD colSpan=10>Position</TD>
<TD colSpan=8>Checksum</TD></TR></TBODY></TABLE>
<P>I have not fully analyzed the type selection bits yet, but they appear to
select between absolute data for servo Channels 7, 8, 9 and 10 in some fashion,
as well as indicating fail safe frames. The delta value is treated as an offset
from the previous absoluate position frame for this channel, with a value of 8
meaning no change. The position is treated as a 10 bit MSB value, hence the name
PCM1024. The checksum appears to be a sum of the position and other bits; I have
not fully analyzed it yet.
<H2>Checksum computation</H2>
<P>To be written
<H2>Channel assignment</H2>
<P>As mentioned before, each field has four data packets that we're calling A,
B, C and D. The first packet in field 1 is 1A and so on. The position and delta
channels for each normal data packet appear to be: <PRE>1A:
Select=0 ???
Select=1 ???
Select=2 Channel 1 absolute, Channel 2 delta
Select=3 ???
1B:
Select=0 Channel 3 absolute, Channel 4 delta
Select=1 ???
Select=2 ???
Select=3 ???
1C:
Select=0 ???
Select=1 ???
Select=2 Channel 5 absolute, Channel 6 delta
Select=3 ???
1D:
Select=0 Channel 7 absolute, Channel 8 delta
Select=1 ???
Select=2 ???
Select=3 ???
2A:
Select=0 ???
Select=1 ???
Select=2 Channel 2 absolute, Channel 1 delta
Select=3 ???
2B:
Select=0 Channel 4 absolute, Channel 3 delta
Select=1 ???
Select=2 ???
Select=3 ???
2C:
Select=0 ???
Select=1 ???
Select=2 Channel 6 absolute, Channel 5 delta
Select=3 ???
2D:
Select=0 Channel 8 absolute, Channel 7 delta
Select=1 ???
Select=2 ???
Select=3 ???
</PRE>
<P>
<H2>Fail safe frames</H2>
<P>To be written.
<HR>
<A name=6b10b></A>
<H1>Appendix 1: 6B10B encoding</H1>Thanks to Coert Langkemper for his help in
determining the encoding pattern. Without his aid, this would have taken
absolutely forever. <PRE> '1111111000' => 0x00,
'1111110011' => 0x01,
'1111100011' => 0x02,
'1111100111' => 0x03,
'1111000111' => 0x04,
'1111001111' => 0x05,
'1110001111' => 0x06,
'1110011111' => 0x07,
'0011111111' => 0x08,
'0001111111' => 0x09,
'0000111111' => 0x0A,
'1100111111' => 0x0B,
'1100011111' => 0x0C,
'1100001111' => 0x0D,
'1110000111' => 0x0E,
'1111000011' => 0x0F,
'0011111100' => 0x10,
'0011110011' => 0x11,
'0011100111' => 0x12,
'0011001111' => 0x13,
'1111001100' => 0x14,
'1110011100' => 0x15,
'1100111100' => 0x16,
'1100110011' => 0x17,
'1111110000' => 0x18,
'1111100000' => 0x19,
'1110000011' => 0x1A,
'1100000111' => 0x1B,
'1100011100' => 0x1C,
'1110011000' => 0x1D,
'1110001100' => 0x1E,
'1100111000' => 0x1F,
'0011000111' => 0x20,
'0001110011' => 0x21,
'0001100111' => 0x22,
'0011100011' => 0x23,
'0011111000' => 0x24,
'0001111100' => 0x25,
'0000011111' => 0x26,
'0000001111' => 0x27,
'0011001100' => 0x28,
'0011000011' => 0x29,
'0001100011' => 0x2A,
'0000110011' => 0x2B,
'1100110000' => 0x2C,
'1100011000' => 0x2D,
'1100001100' => 0x2E,
'1100000011' => 0x2F,
'0000111100' => 0x30,
'0001111000' => 0x31,
'0011110000' => 0x32,
'0011100000' => 0x33,
'0011000000' => 0x34,
'1111000000' => 0x35,
'1110000000' => 0x36,
'1100000000' => 0x37,
'0001100000' => 0x38,
'0001110000' => 0x39,
'0000110000' => 0x3A,
'0000111000' => 0x3B,
'0000011000' => 0x3C,
'0000011100' => 0x3D,
'0000001100' => 0x3E,
'0000000111' => 0x3F,
</PRE><!-- START OF FOOTER -->
<P><!-- END OF LAYOUT --><BR clear=all>
<TABLE width="100%" bgColor=#a0a0a0 border=1>
<TBODY>
<TR>
<TD width="100%"><A
href="http://autopilot.sourceforge.net/index.html"><IMG height=31
alt="Autopilot Logo"
src="autopilot Futaba PCM decoding.files/logo-clear.gif" width=88
align=right border=1></A> <A href="http://sourceforge.net/"><IMG height=31
alt=SourceForge src="autopilot Futaba PCM decoding.files/sflogo.png"
width=88 align=right border=1></A> <A
href="http://validator.w3.org/check/referer"><IMG height=31
alt="HTML 4.0!" src="autopilot Futaba PCM decoding.files/valid-html40.png"
width=88 align=right border=1></A>
<H6><A href="http://autopilot.sourceforge.net/cgi-bin/history">$Id:
pcm.html,v 1.3 2003/02/03 19:42:41 tramm Exp
$</A></H6></TD></TR></TBODY></TABLE><!-- END OF FOOTER --></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -