7d5a63701e1342da0216b9bc2126b484f0e33273
[pierogi] / doc / documentation.html
1 <html>
2 <head>
3 </head>
4 <body>
5
6 <h1>Pierogi Documentation</h1>
7
8 <p>
9 The Pierogi universal infrared remote controller is a single self-contained
10 app capable of sending IR commands to pretty much any IR-controlled device.
11 At the moment, it is oriented towards television, VCR, DVD, and Blu-ray
12 devices, but a few other types of device have had their command sets entered.
13 </p>
14
15 <p>
16 Commands are collected into "keysets".  As each manufacturer tends to reuse
17 a given set of command encodings rather than re-invent the wheel each
18 time they come out with a new product, a large number of devices can be
19 controlled by a single keyset.
20 </p>
21
22 <h2>Using Pierogi</h2>
23
24 <p>
25 The current Pierogi design is built around a tabbed window, each tab containing
26 a group of related buttons.  Depending on the keyset that has been selected,
27 some of these buttons will be active, others inactive.  Active buttons are ones
28 which have been associated with a command in the current keyset.  Pressing an
29 active button will begin repeating the associated command; letting up on the
30 button will stop the command.
31 </p>
32
33 <p>
34 Keysets can be chosen using the "Select Keyset" option in the drop-down menu.
35 If you have a particular keyset you use often, it can be stored in the
36 "favorites" tab for quick access.
37 </p>
38
39 <h3>Main Tab</h3>
40
41 <p>The Main tab contains just the power, volume, and channel buttons.  It is
42 intended to be a quick way to get to the most important, commonly used
43 controls.  The name of the current keyset is also provided in this tab.</p>
44
45 <h3>Utility Tab</h3>
46
47 <p>The Utility tab contains a selection of commonly useful controls, such as
48 "Mute", "Sleep", "Input", "Closed Captions / Subtitles", and the color buttons.
49 The exact selection of buttons on this tab will probably change to reflect
50 which commands turn out to be the most popular.</p>
51
52 <h3>Keypad Tab</h3>
53
54 <p>This tab provides a numeric keypad and a handful of associated commands,
55 intended mainly for use with televisions.  The "Prev Channel" button should
56 take you to the previously selected channel, if any.  The "Dash" button
57 should allow you to specify a digital subchannel, as in "16-4".  The "+100"
58 button is used for television sets which normally expect only two digits
59 per channel; using this button allows you to enter a third digit.  The "-/--
60 Double Digit" button is used on very old televisions that normally expect
61 channels to be represented by just a single digit; pressing this should
62 allow you to enter a second digit.</p>
63
64 <h3>Menu Tab</h3>
65
66 <p>This tab contains buttons used to enter and exit a menu, navigate within
67 a menu, and select menu entries.  The "Menu" button is meant to enter the
68 main system menu of a given device; the "Info" and "Guide" buttons are
69 targeted towards entering other useful menus when available.</p>
70
71 <h3>Media Tab</h3>
72
73 <p>Many of the most important playback commands are represented on this tab.
74 Play, pause, and stop are the most common ones, along with "Reverse" (often
75 called "Rewind") and Fast Forward.  A variety of other less common navigation
76 controls are included, along with the "eject" command.</p>
77
78 <h3>Misc Tab</h3>
79
80 <p>This tab contains a selection of buttons that did not fit into any of the
81 previous tabs.  The content of this tab is subject to change.</p>
82
83 <h3>Favorites Tab</h3>
84
85 <p>As there are numerous keysets available in Pierogi, a "favorites" tab has
86 been implemented.  To add a favorite keyset to the tab, first select that
87 keyset from the "Select Keyset" window.  Then, navigate to the Favorites tab
88 and press "Add Current Keyset".</p>
89
90 <p>Once you have added some keysets to the favorites list, you can tell
91 Pierogi to use one by simply selecting that keyset from the list.</p>
92
93 <p>A keyset can be removed from the list by selecting it and pressing
94 "Remove Selected Keyset".</p>
95
96 <h3>Select Keyset Window</h3>
97
98 <p>The Select Keyset window presents a list of all the keysets currently
99 available in Pierogi.  As this list is fairly long, a button has been added
100 at the top of the window that allows you to choose the make (or brand) of
101 the device you are trying to control; once a make has been selected, all
102 keysets not associated with that make will be hidden.  To use a keyset,
103 simply select it from the list, and close the window (by pressing the
104 return arrow at the top right of the screen).</p>
105
106 <h2>Design Rationale</h2>
107
108 <p>Here I collect my thoughts on the how and why of creating Pierogi.</p>
109
110 <h3>Hasn't this been done before?</h3>
111
112 <p>Yes, remote control software has already been written.  In particular,
113 the <a href="http://irreco.garage.maemo.org/">Irreco / QtIrreco</a> project
114 creates beautiful virtual remote controls.  I've also used the
115 <a href="http://thp.io/2010/raemote/">Raemote</a> widget to control my Apple
116 computers.  But these programs have their shortcomings; in particular, they
117 are not universal.  Each simulated remote control in QtIrreco is a completely
118 separate animal.  I would like to have a standard set of buttons that I can
119 use on all sorts of different hardware.</p>
120
121 <h3>What's up with LIRC?</h3>
122
123 <p>Just as Irreco and Raemote do, I want to leverage the work of the 
124 <a href="http://www.lirc.org/">Linux Infrared Remote Control</a> project.
125 The LIRC project is, at the moment, by far the most influential open-source
126 effort working with consumer IR.  And the N900 comes with a device driver
127 built specifically for use with LIRC!  But, you see, I have a problem.  I
128 don't want to do things the way LIRC wants to do things.</p>
129
130 <p>The N900 is different from other Linux systems using IR -- rather than
131 being the machine at which you point a remote control, this machine <i>is</i>
132 the remote control.  Which is not what LIRC was made for; the heart of the
133 LIRC project is a server that will sit and wait for messages to arrive from
134 the IR hardware.  Although it can also broadcast IR data back out (when using
135 hardware that supports 2-way IR communication), that is not its primary
136 purpose.</p>
137
138 <p>I believe there are three disadvantages to using the LIRC server as it
139 currently exists.  First, there isn't much point to running a daemon on
140 the N900 to manage the IR device; no messages are ever going to come in from
141 the output-only hardware on the N900, so why sit and listen for them?</p>
142
143 <p>The second problem is somewhat larger.  LIRC uses configuration files to
144 describe the command set for each remote control.  And there are a lot of them.
145 A whole lot.  We're talking thousands of files here, and each file can describe
146 many remote controls.  This is not a problem for Raemote or Irreco, as they
147 only need to deal with one config file at a time.  But if you're aiming to
148 manage the whole lot of them, you need to find a way to deal with the
149 multitudes.</p>
150
151 <p>The third problem is more subtle, but really tough to crack.  You see, the
152 whole point of LIRC is to take the commands it receives from the IR port and
153 translate them into something recognizable.  As such, each config file provides
154 a mapping from numeric commands to human-readable strings.  (These strings
155 are normally based on the labels used on the remote control itself.)  This is a
156 serious problem for a universal controller!  Take, for example, the "power"
157 button found on most remote controls.  In some config files, the string for
158 this is "power".  Others have "Power", or "POWER".  You can also find "pwr",
159 "PWR", "ON/OFF", "ON-OFF", "ONOFF", "POWER_ON_OFF", "KEY_POWER", "Operate",
160 "Standby", and who knows what else.  And, you've gotta be careful not to get
161 confused by strings like "SUBTITLE_ON/OFF" or "TV_ON_TIMER".  How is an app to
162 know which key to map all these strings to?</p>
163
164 <h3>So how is Pierogi different?</h3>
165
166 <p>
167 Pierogi attempts to answer these problems.  First, it talks directly to the
168 /dev/lirc0 device, no server middleman needed.  Yes, you can halt (or even
169 uninstall!) the lircd daemon, and still use Pierogi.  Second, the entire
170 set of LIRC config files are being processed and combined into a small(er)
171 set of related families of commands.  The third problem mentioned above is a
172 bit harder to solve; I'm currently mapping each LIRC config file string by
173 hand to a corresponding Pierogi key.  Naturally, this process will be fraught
174 with errors; I intend to keep updating Pierogi as these errors are found and
175 fixed.
176 </p>
177
178 <h2>Internal Design Notes</h2>
179
180 <p>If you're interested in the ugly details of the code, read on!</p>
181
182 <h3>What's up with the name of this app?</h3>
183
184 <p>Lately I've been naming my projects after tasty foods.  In particular,
185 I've been working my way through the pasta-oriented dishes.  (My previous
186 project, "Linguine", has gotten bogged down, so I moved on to this one...)</p>
187
188 <h3>Why use Qt?</h3>
189
190 <p>I'm a C++ kind of guy, it just makes sense to me to use a C++ kind of
191 interface.  The Qt classes have everything you need to set up a decent UI,
192 and Qt Creator makes coding up a project for the N900 relatively
193 painless.  Check it out for yourself at
194 <a href="http://qt.nokia.com/">the Qt webpage</a>.
195 </p>
196
197 <h3>The simplest device ever!</h3>
198
199 <p>If you ever wanted to learn how to work with device drivers on Linux, the
200 N900's infrared port is the device you want to start with.  It's not 
201 much more than a flashlight: You turn it on.  You turn it off.  You turn it on
202 again.  You turn it off again.  You really can't get much simpler than that.
203 Interaction with the "/dev/lirc0" device involves no more than handing
204 it an array of integers: the first integer being an amount of time to keep the
205 light lit (in microseconds), the second being an amount of time to leave it
206 switched off, the third on, the fourth off, and so on.</p>
207
208 <p>Well, ok, so it involves just a little bit more than that.  You don't want
209 to leave the light stuck in the "on" state when you are finished, so the driver
210 demands that the last item in every array be an "on" amount -- after finishing
211 that timer, the IR will stay off until the next command arrives.
212 </p>
213
214 <p>
215 Also, in an attempt to weed out any confusing signals from natural IR sources
216 in the environment, consumer IR devices are "pulsed" at a particular
217 frequency.  So you're really turning a strobelight on and off, not just a
218 flashlight.  When the receiver sees that the light is coming from a strobelight
219 pulsing at the desired frequency, it can be assured that that signal came from
220 an actual remote control.  The N900's device driver allows you to set the
221 frequency anywhere between 20000 Hz and 500000 Hz.  38000 Hz seems to the most
222 popular frequency used by modern remote controls, at least from what you find
223 in LIRC config files.  Also, you can set how long each pulse needs to be held,
224 in terms of a percentage: 25% means turning the light on for just one quarter
225 of the pulse, 33% means leaving it on for one third, etc.  This is called the
226 "duty cycle", and can be anywhere between 0 and 100 percent.  LIRC's default
227 duty cycle is 50 percent.
228 </p>
229
230 <p>And that's about it.  I've been using a 
231 <a href="http://svn.jacekowski.org/host_mode/trunk/drivers/input/lirc/lirc_rx51.c">web page</a>
232 that lists the source code for the IR device driver.  I'm not sure if there's
233 a better location out there for N900 source code, but this seems accurate
234 so far.</p>
235
236 <h3>You did <i>what</i> to the LIRC daemon?</h3>
237
238 <p>
239 Well, ok, yeah, I've cannibalized the transmission code out of the LIRC
240 server and dumped it into my app.  Sort of.  I can't really keep my hands off
241 of code once I've seen it, so I've rewritten it in C++, reorganizing it in
242 an object-oriented manner along the way.</p>
243
244 <p>
245 Here's one way in which I disagree with the authors of LIRC: they've managed
246 to cram support for practically every protocol used by every remote control
247 ever made into a single codepath.  So, there's a single "transmit" function,
248 sorting through a massive pile of flags, conditional statements, and some
249 really funky delayed-action buffering to make everything work.  The simple act
250 of splitting the code into one routine for the RC5 (biphase) protocol and
251 another for the NEC (space-encoded) protocol makes it much easier to read, at
252 least to my eyes.  (I haven't yet implemented the RC6 protocol.)
253 </p>
254
255 <h2>Attribution</h2>
256
257 <p>I've fallen in love with the Gentleface Mono Icon Set.  Of the creative
258 commons icon sets available, theirs stands head and shoulders above the rest.
259 Find their work at <a href="http://www.gentleface.com">www.gentleface.com</a>.
260
261 <h2>References</h2>
262
263 <p>A set of links to some resources I've used while writing the code.</p>
264
265 <ul>
266 <li><a href="http://en.wikipedia.org/wiki/Consumer_IR">Wiki page</a> with
267 general info on consumer IR
268
269 <li>A <a href="http://www.sbprojects.com/knowledge/ir/index.php">good introduction</a>
270 to the theory and practice behind consumer IR devices
271
272 <li>A <a href="http://en.wikipedia.org/wiki/RC-5">Wiki for the RC-5 protocol</a>
273
274 <li><a href="http://www.sbprojects.com/knowledge/ir/nec.php">Info on the NEC protocol</a>
275
276 <li><a href="http://www2.renesas.com/faq/en/mi_com/f_com_remo.html">More info on the NEC protocol</a>
277
278 <li>The heart of it all, the
279 <a href="http://www.lirc.org/">Linux Infrared Remote Control</a> project.
280
281 <li>Link to (what appears to be) the source code for the N900's
282 <a href="http://svn.jacekowski.org/host_mode/trunk/drivers/input/lirc/lirc_rx51.c">/dev/lirc0 device driver</a>.
283 <ul>
284
285 </body>
286 </html>