Jekyll2020-05-14T11:43:58+02:00https://www.codedesigner.de/atom.xmlcodedesigner.derandom thoughts of a software guyAlexander Laisalexander.lais@me.comBulk File Copy and Rename (renameutils)2018-01-16T00:00:00+01:002018-01-16T00:00:00+01:00https://www.codedesigner.de/tools/renameutils/RenameUtils<p>Sometimes you need to copy or rename a bunch of files, either following some pattern or arbitrarily.</p>
<p>Mac OS finder (and certainly some Linux file managers) offers support for bulk rename. But when you want do to this on the console instead, using your favorite text editor, you can also use <a href="http://www.nongnu.org/renameutils/"><code class="highlighter-rouge">renameutils</code></a> consisting of <code class="highlighter-rouge">qcp</code> (quick copy), <code class="highlighter-rouge">qmv</code> (quick move), <code class="highlighter-rouge">icp</code> and <code class="highlighter-rouge">imv</code> (the interactive versions).</p>
<p>Those tools work similar to <code class="highlighter-rouge">cp</code> and <code class="highlighter-rouge">mv</code>, including the support for wildcards, but allow you to preview and modify the operation before it is executed.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">EDITOR</span><span class="o">=</span>mate <span class="nt">-w</span> <span class="c"># use TextMate for editing, or your favorite editor</span>
qmv <span class="k">*</span>
</code></pre></div></div>
<p>This opens up a temporary file looking something like this:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DSC_2169.NEF DSC_2169.NEF
DSC_2170.NEF DSC_2170.NEF
DSC_2171.NEF DSC_2171.NEF
DSC_2172.NEF DSC_2172.NEF
DSC_2173.NEF DSC_2173.NEF
DSC_2174.NEF DSC_2174.NEF
DSC_2175.NEF DSC_2175.NEF
DSC_2176.NEF DSC_2176.NEF
DSC_2177.NEF DSC_2177.NEF
DSC_2178.NEF DSC_2178.NEF
DSC_2179.NEF DSC_2179.NEF
</code></pre></div></div>
<p>The left column defines the current names, the right column the new names. If you remove files from the list, they will not be touched. By default the left and right column are identical and nothing will be renamed.</p>
<p>Now you can use your text editor to do column, multi-cursor, regular expression and whatever else you can imagine to defined file renames.</p>
<p>The interactive versions require only the source file name (only one) and allow you to modify the name directly in the terminal without having to copy or autocomplete it.</p>Alexander Laisalexander.lais@me.comSometimes you need to copy or rename a bunch of files, either following some pattern or arbitrarily.A better OMX Player Controller2017-05-11T00:00:00+02:002017-05-11T00:00:00+02:00https://www.codedesigner.de/articles/better-omxplayer-controller/A-Better-Python-OMXPlayer-Controller<p>I’m using <code class="highlighter-rouge">omxplayer</code> on the Raspberry Pi for video playback because it utilizes the Raspberry Pi’s hardware video decoding.
Because the front-end is a separate application, I just need to remote control OMX Player to start and stop the video and figure out how far the video has played back already.</p>
<p>Originally I used the <a href="https://github.com/jbaiter/pyomxplayer">pyomxplayer project</a> and some of its forks (e.g. <a href="https://github.com/Bounder/pyomxplayer">Bounder’s fork</a>) because the original was outdated and the newer OMXPlayer binaries have other command line flags.</p>
<p>My goal for this player was not so much the interactive control of the video playback as full programmatic control and introspection into the playback and appropriate reaction with events.</p>
<p>The most relevant events for me are:</p>
<ul>
<li>Startup
<ul>
<li>Did it start up and playback start? <code class="highlighter-rouge">on_start</code></li>
<li>Why did it not start, e.g. input file not found, corrupt, etc. <code class="highlighter-rouge">on_error</code></li>
</ul>
</li>
<li>Playback
<ul>
<li>Has it started playing? -&gt; <code class="highlighter-rouge">on_start</code></li>
<li>What is the play state -&gt; <code class="highlighter-rouge">playing</code></li>
</ul>
</li>
</ul>
<p>Based on those I could then do a stripped down version for my purposes that allows fine-grained monitoring.</p>
<p>Release to Github pending. I’ll update the article when it’s done.</p>
<p>Another important thing for me was to use daemon threads for the monitoring, as the controlling application is interactive and could technically stop at any time. I don’t want it blocked until the video finally stops by itself.</p>Alexander Laisalexander.lais@me.comI’m using omxplayer on the Raspberry Pi for video playback because it utilizes the Raspberry Pi’s hardware video decoding. Because the front-end is a separate application, I just need to remote control OMX Player to start and stop the video and figure out how far the video has played back already.Raspberry Pi Video Overlay on OMXPlayer via Kivy2016-09-26T00:00:00+02:002016-09-26T00:00:00+02:00https://www.codedesigner.de/articles/omxplayer-kivy-overlay/RaspberryPi-Video-Overlay-OMXPlayer-Kivy<p>In one of my hobby projects I needed to display additional infomation on top of a running video. The whole project is based on the Raspberry Pi and Python.</p>
<p>This article describes the approach I’ve taken to display arbitrary content over the video with the help of the very flexible (and admittedly awesome) Kivy framework. I use OMXPlayer to play back the video because it uses the Raspberry Pi hardware efficiently enough to play back 1080p video in real time.</p>
<h2 id="using-dispmanx-layers">Using DISPMANX layers</h2>
<p>DISPMANX is the layer between EGL (OpenGL ES) and the BCM graphics chip in the Raspberry Pi. This API allows the control over the display quite directly and is ultimately used for most drivers that communicate with the display(s) attached to the Raspberry Pi.</p>
<p>The DISPMANX API supports “layers”, which allow different content to be placed for very basic compositing. The best part about this is that layers have alpha channels, so can be (partially) transparent.</p>
<h2 id="using-kivy-for-the-overlays">Using Kivy for the Overlays</h2>
<p>For video overlays, we need to achieve two points:</p>
<ol>
<li>Define a layer on top of the video player to render the overlay</li>
<li>Keep part of that layer transparent, so we see the video underneath.</li>
<li>Define all of the overlay elements as widgets in Kivy.</li>
</ol>
<h4 id="kivy-and-dispmanx-layers">Kivy and DISPMANX Layers</h4>
<p>Kivy 1.9.2 and newer has a rendering backend specifically for the Raspberry Pi, based on the BCM DISPMANX API, which allows direct access to the screen without the need for window managers, etc.</p>
<p>Currently, the selected layer is always 0 but can be added easily in <code class="highlighter-rouge">window_rpi_egl.py</code>. <del>I’ll make a pull request to Kivy to add a config variable to define the DISPMANX layer easily</del>.</p>
<p>Someone made one already here: <a href="https://github.com/kivy/kivy/pull/4984">Pull Request for adding RPI DISPMANX Layer configuration</a></p>
<p>Let’s see when it’s accepted.</p>
<h4 id="keeping-the-kivy-background-transparent">Keeping the Kivy Background Transparent</h4>
<p>The Kivy Window will be “cleared” with a black color by default and basically enforces a full-screen black image, on which any widget is rendered.</p>
<p>To see the video underneath the Kivy window, we need to disable this clearing behaviour, so Kivy leaves the background transparent.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code># transparent background color
Window.clearcolor = (0, 0, 0, 0)
</code></pre></div></div>
<p>The best thing about this is that you can define any color and any alpha intensity (level of transparency). The color <code class="highlighter-rouge">(1, 0, 0, 0.5)</code> would make the background semi-transparent red for example.</p>
<h4 id="defining-ui-elements-in-kivy">Defining UI Elements in Kivy</h4>
<p>Kivy is a powerful UI framework with lots of documentation and examples. Defining the UI you want overlaid over the video should be reasonably simple.</p>
<p>These two links should help further:</p>
<ul>
<li>Kivy documentation, overview of widgets</li>
<li>Kivy: Rendering a background color for labels</li>
</ul>
<h2 id="integrating-omxplayer">Integrating OMXPlayer</h2>
<p>OMXPlayer is integrated via the <a href="http://github.com/jbaiter/pyomxplayer">pyomxplayer project</a>, with the slight modification that it defines the layer, on which to display the video.<br />
pyomxplayer will create a background thread that checks on the OMXPlayer process and provides callbacks to various states.</p>
<h4 id="synchronising-playback-and-overlay">Synchronising Playback and Overlay</h4>
<p>For my project I need time-synchronised overlays. pyomxplayer monitors the video’s progress. I’ve extended it a bit to propagate the current playback position via callback. More on this in a dedicated article of <a href="/articles/better-omxplayer-controller/index.html">my extensions to pyomxplayer</a>.</p>
<h2 id="why-not-the-kivy-video-player">Why not the Kivy Video Player?</h2>
<p>I’ve tried various alternatives to make my life easier with this.</p>
<p>The first attempt was of course to use the video player that is provided with Kivy. We play back 1080p video, which works great with OMXPlayer, but is just too slow when decoding frames, putting them into a texture and displaying it (I’ve seen between 1-4 frames/s on the Raspberry Pi 2).</p>
<p>That is the approach that Kivy takes and is the regular approach that performs well on more powerful hardware. The Raspberry Pi is just barely fast enough to decode the 1080p video frames and put them on screen with its hardware decoder. There is no room left for working with textures.</p>Alexander Laisalexander.lais@me.comIn one of my hobby projects I needed to display additional infomation on top of a running video. The whole project is based on the Raspberry Pi and Python.Maximizing in Yosemite2014-10-19T00:00:00+02:002017-05-07T16:40:00+02:00https://www.codedesigner.de/2014/10/Maximizing-in-Yosemite<p>Apple changed the behaviour of the small green button in the window controls from “Maximize” to “Fullscreen”.</p>
<p><img src="https://www.codedesigner.de/images/yosemite-window-controls.png" alt="Yosemite Window Controls" title="Yosemite Window Controls" /></p>
<p>I used Maximize all the time, and now found how to get the behaviour again. You <del>need to</del> can double click the title bar (or combined toolbar, e.g. in Safari) to get the old “Maximize” behaviour. No idea if that was like this in Mavericks and before as well already…</p>
<p><em>Update 07 May 2017:</em></p>
<p>Or you press the <code class="highlighter-rouge">Alt (⌥)</code> button and then click the little green blob, like everyone else.</p>Alexander Laisalexander.lais@me.comApple changed the behaviour of the small green button in the window controls from “Maximize” to “Fullscreen”.Swift Pitfalls2014-10-11T00:00:00+02:002014-10-11T00:00:00+02:00https://www.codedesigner.de/2014/10/Swift-Pitfalls<p>I’ve started a couple experiments in iOS 8 development using Apple’s new language <a href="https://developer.apple.com/swift/">Swift</a>
and learned a few lessons that I want to share.</p>
<h2 id="blocks-and-automatic-reference-counting-arc">Blocks and Automatic Reference Counting (ARC)</h2>
<p>Swift supports blocks, or “closures”, as other languages call them. You can provide a block as handler, e.g. for an asynchronous HTTP request. This is excellent if you want to do updates in the background and a simple way to handle some updates (data and UI) when the new data has arrived.</p>
<p>A block in Swift will capture references that are used form the surrounding context. If you use <code class="highlighter-rouge">self</code> reference in the block, a reference to it will be retained.</p>
<p>You can work around this by defining the captured references as weak references, specifically one of the following types:</p>
<ul>
<li>unowned: the reference is handled like a regular reference in the closure but doesn’t count towards the strong references. This is the option to use when the block is actually contained and owned by the held reference (e.g. self).</li>
<li>weak: the reference is handled as Optional and could turn to nil at any point during execution.</li>
</ul>
<p>Captured references can be defined in a block like this:</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="nv">block</span> <span class="o">=</span> <span class="p">{</span>
<span class="p">[</span><span class="k">unowned</span> <span class="k">self</span><span class="p">,</span> <span class="k">weak</span> <span class="n">otherReference</span><span class="p">]</span> <span class="c1">// captured references</span>
<span class="p">(</span><span class="n">parameter</span><span class="p">)</span> <span class="k">in</span> <span class="c1">// input parameters to the block</span>
<span class="k">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">parameter</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The block will then respectively not keep a strong reference to the captured objects and allow ARC to clean up object accordingly when needed.</p>
<p>I have a bit of code that can issue a simple JSON-RPC request dynamically, and it was retaining references to self before I added the <code class="highlighter-rouge">[unowned self]</code> bit.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">asyncRequest</span><span class="p">(</span><span class="nv">command</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">parameters</span><span class="p">:</span> <span class="p">[</span><span class="kt">String</span><span class="p">],</span> <span class="nv">callback</span><span class="p">:</span> <span class="p">((</span><span class="kt">NSData</span><span class="o">!</span><span class="p">,</span> <span class="kt">NSURLResponse</span><span class="o">!</span><span class="p">,</span> <span class="kt">NSError</span><span class="o">!</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">))</span> <span class="o">-&gt;</span>
<span class="kt">NSURLSessionDataTask</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">url</span> <span class="o">=</span> <span class="kt">NSURL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="n">command</span><span class="p">,</span> <span class="nv">relativeToURL</span><span class="p">:</span> <span class="n">baseUrl</span><span class="p">)</span>
<span class="k">var</span> <span class="nv">request</span> <span class="o">=</span> <span class="kt">NSMutableURLRequest</span><span class="p">(</span><span class="kt">URL</span><span class="p">:</span> <span class="n">url</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="kt">HTTPMethod</span> <span class="o">=</span> <span class="s">"POST"</span>
<span class="n">request</span><span class="o">.</span><span class="kt">HTTPBody</span> <span class="o">=</span> <span class="s">"{</span><span class="se">\"</span><span class="s">nocache</span><span class="se">\"</span><span class="s">:</span><span class="se">\(</span><span class="kt">NSDate</span><span class="p">()</span><span class="o">.</span><span class="n">timeIntervalSince1970</span><span class="se">)</span><span class="s">,</span><span class="se">\"</span><span class="s">method</span><span class="se">\"</span><span class="s">:</span><span class="se">\"\(</span><span class="n">command</span><span class="se">)\"</span><span class="s">,</span><span class="se">\"</span><span class="s">params</span><span class="se">\"</span><span class="s">: [</span><span class="se">\(</span><span class="n">parameters</span><span class="se">)</span><span class="s">]}"</span><span class="o">.</span><span class="nf">dataUsingEncoding</span><span class="p">(</span><span class="kt">NSUTF8StringEncoding</span><span class="p">,</span> <span class="nv">allowLossyConversion</span><span class="p">:</span> <span class="kc">true</span><span class="p">)</span>
<span class="k">let</span> <span class="nv">task</span> <span class="o">=</span> <span class="kt">NSURLSession</span><span class="o">.</span><span class="nf">sharedSession</span><span class="p">()</span><span class="o">.</span><span class="nf">dataTaskWithRequest</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
<span class="k">return</span> <span class="n">task</span>
<span class="p">}</span>
<span class="c1">// somewhere else in the code...</span>
<span class="k">var</span> <span class="nv">task</span> <span class="o">=</span> <span class="k">self</span><span class="o">.</span><span class="nf">asyncRequest</span><span class="p">(</span><span class="s">"rpcmethod"</span><span class="p">,</span> <span class="nv">parameters</span><span class="p">:</span> <span class="p">[</span><span class="s">"1234"</span><span class="p">])</span> <span class="p">{</span>
<span class="p">[</span><span class="k">unowned</span> <span class="k">self</span><span class="p">]</span> <span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">error</span><span class="p">)</span> <span class="k">in</span>
<span class="k">self</span><span class="o">.</span><span class="n">groupCache</span> <span class="o">=</span> <span class="nf">parse</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="uitableview-updates-from-dynamic-data-sources">UITableView Updates from Dynamic Data Sources</h2>
<p>And another interesting thing, related to UIKit, not so much to Swift about updating UITableViews that show data from external services (e.g. via REST). This article on codeproject.com discusses a solution for <a href="http://www.codeproject.com/Articles/637408/Updating-UITableView-with-a-dynamic-data-source">Updating UITableView with dynamic data sources</a>.</p>
<p>Also the apple developer documentation on <a href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/ManageInsertDeleteRow/ManageInsertDeleteRow.html#//apple_ref/doc/uid/TP40007451-CH10-SW9">Batch Update of UITableView Operations</a> is very interesting.</p>Alexander Laisalexander.lais@me.comI’ve started a couple experiments in iOS 8 development using Apple’s new language Swift and learned a few lessons that I want to share.Building Things with Raspberry Pi2014-03-16T00:00:00+01:002014-03-16T00:00:00+01:00https://www.codedesigner.de/2014/03/Other-Raspberry-Pi-Usecases<p>Over the weekend I helped a friend out developing a kiosk video player based on Raspberry Pi.<br />
We’re now using the following, with good success:</p>
<ul>
<li>Python</li>
<li>pygame for the interactive menus</li>
<li>omxplayer for video playback</li>
<li>Python backends for controlling the video player</li>
<li>GPIO for external signalling that interacts with the application.</li>
</ul>
<p>Definitely a fun project and it works reasonably responsive now.
Some day we will experiment with OpenGL to make the interface even more snappy.<br />
Hopefully also with direct pygame support. We’ll see.</p>Alexander Laisalexander.lais@me.comOver the weekend I helped a friend out developing a kiosk video player based on Raspberry Pi. We’re now using the following, with good success:Rover in Action2014-02-21T00:00:00+01:002014-02-21T00:00:00+01:00https://www.codedesigner.de/2014/02/Rover-in-Action<p>I’m working at a software company. One of our side projects is the integration of new control concepts and input devices to robotic control.</p>
<p>We’ve integrated a couple of input devices and can control different rovers. One of them is the one I built.<br />
This first video shows the control via Leap Motion, a precise gesture detection device.</p>
<p>See for yourself.</p>
<style>.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>
<div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/m2q1i5miCfA" frameborder="0" allowfullscreen=""></iframe></div>Alexander Laisalexander.lais@me.comI’m working at a software company. One of our side projects is the integration of new control concepts and input devices to robotic control.Raspberry Pi Pulling the Plug2013-11-28T00:00:00+01:002013-11-28T00:00:00+01:00https://www.codedesigner.de/2013/11/Raspi-Pulling-Plug<p>While browing for different breakout boards for the Rover I’ve discovered a nice little board that has a push button and logic pin to control a MOSFET.<br />
This little contraption allows switching on and off the power, say through a USB cable.<br />
Below is what I did to make the Raspberry Pi switch itself off completely on system shutdown.</p>
<p>#Hardware
The hardware itself is very simple. I’ve taken the the <a href="http://www.exp-tech.de/Shields/Pololu-Pushbutton-Power-Switch-LV.html">Pololu Pushbutton Power Switch</a> and connected it to a standard MicroUSB cable.
<img src="https://www.codedesigner.de/images/raspi/power-switch.jpg" alt="Pololu Pushbutton Power Switch" title="The Pololu Pushbutton Power Switch" /></p>
<p>I’ve only taken the V+ and GND cables (red and black) from the cable and connected them to the respective pins on the board.</p>
<p>Also I’ve connected the “Power Off” pin on the board to a GPIO pin (GPIO25) on the Raspberry Pi.</p>
<p>Pressing the switch toggles the power on and off, as expected. Putting a “high” signal on the “Power Off” pin (i.e. GPIO25), turns the power off as well.</p>
<p>#Software
The software part is also simple. GPIO is exposed through the Linux kernel via the /sys filesystem.<br />
In order to make the GPIO pin writable and set it to “high”, the following sequence of shell commands is necessary:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># you need to be root to execute this.</span>
<span class="nb">echo </span>25 <span class="o">&gt;</span> /sys/class/gpio/export <span class="c"># Activate GPIO25. This will create the /sys/class/gpio/gpio25 device.</span>
<span class="nb">echo </span>out <span class="o">&gt;</span> /sys/class/gpio/gpio25/direction <span class="c"># Setting GPIO25 to output (i.e. controlling, not reading)</span>
<span class="nb">echo </span>1 <span class="o">&gt;</span> /sys/class/gpio/gpio25/value <span class="c"># Set the output value of GPIO25 to 1 (="high")</span>
</code></pre></div></div>
<p>Executing this will shut down the Pi immediately as it cuts the power. Be careful.</p>
<p>I’ve checked what is called when Linux is shutting down, i.e. when it reaches runlevel 0.<br />
The files for this are in /etc/rc0.d/ on a standard Debian/Raspbian/Raspbmc Linux installation.<br />
The file called last is a command called “halt”, which is softlinked from /etc/init.d/halt.</p>
<p>This file contains a shutdown command, including potential power-off when that is requested for the shutdown. I’m hooking into there and shortly before the “halt” command would be triggered and a full power-off is requested, I execute the few lines above.</p>
<p>The section looks something like the following:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># [...]</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$poweroff</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"-p"</span><span class="o">]</span>
<span class="k">then
</span>log_action_msg <span class="s2">"Shutting down via GPIO"</span>
<span class="nb">echo </span>25 <span class="o">&gt;</span> /sys/class/gpio/export
<span class="nb">echo </span>out <span class="o">&gt;</span> /sys/class/gpio/gpio25/direction
<span class="nb">echo </span>1 <span class="o">&gt;</span> /sys/class/gpio/gpio25/value
<span class="k">fi
</span>log_action_msg <span class="s2">"Will now halt"</span>
halt <span class="nt">-d</span> <span class="nt">-f</span> <span class="nv">$netdown</span> <span class="nv">$poweroff</span> <span class="nv">$hddown</span>
<span class="c"># [...]</span>
</code></pre></div></div>
<p>Like that reboots still work without cutting power. When requesting a shutdown, e.g. via XBMC, the Raspberry Pi shuts down all processes and pulls the plug when it’s ready.</p>Alexander Laisalexander.lais@me.comWhile browing for different breakout boards for the Rover I’ve discovered a nice little board that has a push button and logic pin to control a MOSFET. This little contraption allows switching on and off the power, say through a USB cable. Below is what I did to make the Raspberry Pi switch itself off completely on system shutdown.Rover with Raspberry Pi2013-11-26T00:00:00+01:002013-11-26T00:00:00+01:00https://www.codedesigner.de/projects/rover/Rover<h2 id="hardware">Hardware</h2>
<p>Transportation:</p>
<ul>
<li>Dagu Rover 5 Chassis</li>
<li>Dagu Tilt &amp; Swivel with 2 servos</li>
</ul>
<p>Logic:</p>
<ul>
<li>Raspberry Pi B Revision 2 (512MB RAM)</li>
<li>Adafruit 16 channel 12 bit PWM servo controller</li>
<li>Dagu Motor Controller</li>
</ul>
<p>Sensors:</p>
<ul>
<li>Raspberry Pi Camer</li>
</ul>
<h2 id="software">Software</h2>
<ul>
<li>Raspbian</li>
<li>Raspberry Pi, Python Interfaces</li>
<li>Raspberry Pi GPIO (RPi.GPIO) Python Module</li>
<li>smbus
<ul>
<li>Adafruit I2C driver</li>
<li>Adafruit 16 Channel PWM driver</li>
<li>My custom Dagu rover controller… controller</li>
</ul>
</li>
</ul>
<h2 id="status">Status</h2>
<p>Working so far:</p>
<ul>
<li>Controlling wheels independently
<ul>
<li>Direction</li>
<li>Speed (via PWM)</li>
</ul>
</li>
<li>Controlling Tilt &amp; Swivel Servos</li>
<li>Capturing photos and video with the Raspberry Pi camera</li>
<li>Streaming video via VLC (RTSP, H264)</li>
</ul>Alexander Laisalexander.lais@me.comHardwareUsing the Motor Controller2013-11-26T00:00:00+01:002013-11-26T00:00:00+01:00https://www.codedesigner.de/articles/pwm-and-motor-controller/PWM-and-Motor-Controller<p>The Raspberry Pi has only a single <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> output. The Dagu Rover 5 chassis has 4 motors and 4 optical encoders that need reading as well. So my approach was to get a <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> servo/logic controller that could control the Dagu Motor Controller and additionally some servos for the camera pan/tilt.</p>
<p><img src="https://www.codedesigner.de/images/rover/4chMotorController.jpg" alt="Dagu 4 Channel Motor Controller" title="The Dagu 4 channel motor controller" /></p>
<h2 id="motor-control">Motor Control</h2>
<p>The Dagu Motor Controller has two distinct functionalities.</p>
<ol>
<li>Controlling the motor outputs based on a <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> input and direction input</li>
<li>Multiplex the signals from the encoders on the motors to provide signals when the wheels rotate, and how fast.</li>
</ol>
<p>For the <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> control I’m using an Adafruit 16 channel <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> Servo and LED controller. It has 12 bit resolution and allows 4096 steps for the <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> control. It also allows constant on or off signals for a specific output.
<img src="https://www.codedesigner.de/images/rover/16channelPwm.jpg" alt="Adafruit 16 Channel PWM controller" title="The Adafruit PWM controller" /></p>
<p>Each of the outputs consists of the following signals:</p>
<ol>
<li><abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> output, programmable</li>
<li>V+, the “power” voltage. This is useful for driving servos and not used for the Dagu motor controller</li>
<li>GND, the ground.</li>
</ol>
<p>The Dagu Motor Controller provides the following pins per channel:</p>
<ol>
<li>GND, the ground</li>
<li><abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr>, for controlling the voltage applied to the specific motor channel</li>
<li>DIR, the direction in which the motor should rotate. High is forward, Low is backward.</li>
<li>CUR. This is an output port, which indicates the current going throught that channel as an analog voltage. The scale is ca 1V on the pin per 1A of current going through the motor. Voltages are much easier to measure than currents, so this signal will be interesting.</li>
</ol>
<p>I want to control the direction and speed of each motor directly. Based on the signals that I can get out of the <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> controller, I need two channels per Dagu motor channel to control <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> and the direction (High or Low).</p>
<p>I have now per channel the following connections (Dagu controller -&gt; <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr>):</p>
<ul>
<li>GND -&gt; GND (channel 0)</li>
<li><abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> -&gt; <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> (channel 0)</li>
<li>DIR -&gt; <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> (channel 1)</li>
<li>CUR -&gt; not connected yet. This will go to an <abbr title="Analog Digital Converter: A circuit that can provide discrete digital values for an analog voltage. Recording sound is done like that, or measuring voltages.">ADC</abbr>.</li>
</ul>
<p>Python code for this with more explanation coming soon.</p>
<h2 id="rotary-encoder">Rotary Encoder</h2>
<p>The second functional element of the Dagu controller is the multiplexer for the two-sensor rotary encoder.
Combining the interrupt output of this encoder with a <abbr title="General Purpose Input Output. Programmable input and output pins that can be controlled via software.">GPIO</abbr> port on the Raspberry Pi makes processing of these signals possible.</p>
<p>The <abbr title="General Purpose Input Output. Programmable input and output pins that can be controlled via software.">GPIO</abbr> library for Raspberry Pi also supports asynchronous callbacks when an event happened on a specific <abbr title="General Purpose Input Output. Programmable input and output pins that can be controlled via software.">GPIO</abbr> port.</p>
<p>I’m using this to count the interrupts / steps in the background.
Later I want to extend this to add event triggers when a specific threshold or delta of steps is reached.</p>
<p>For now I’m using these counts to output some information on the console while the motors are running back and forth at different speeds using the <abbr title="Pulse Width Modulation. A signal is repeated at frequency (e.g. 60Hz). During each cycle, the signal can be switched on and off. Depending on the element receiving this signal it's either used to reduce the current, movement period, or for servos define a specific position (angle).">PWM</abbr> signals.</p>Alexander Laisalexander.lais@me.comThe Raspberry Pi has only a single PWM output. The Dagu Rover 5 chassis has 4 motors and 4 optical encoders that need reading as well. So my approach was to get a PWM servo/logic controller that could control the Dagu Motor Controller and additionally some servos for the camera pan/tilt.