<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>Anthony VH</title>
  <generator uri="https://github.com/jekyll/jekyll">Jekyll v3.1.2</generator>
  <icon>http://www.anthonyvh.com/assets/logo.png</icon>
  <subtitle>Adventures in electronics, mechanics and programming.</subtitle>
<link href="http://www.anthonyvh.com/atom.xml" rel="self"/>
<link href="http://www.anthonyvh.com/" rel="alternate" type="text/html"/>
  <updated>2017-10-13T00:05:48-07:00</updated>
  <id>http://www.anthonyvh.com/</id>
  <author>
    <name>Anthony VH</name>
    <uri>http://www.anthonyvh.com/</uri>
    <email>anthony@anthonyv.com</email>
  </author>
  <entry>
   <title>Questasim on Ubuntu 16.04</title>
  <link href="http://www.anthonyvh.com/2017/10/13/questasim_on_ubuntu/"/>
    <updated>2017-10-13T00:00:00-07:00</updated>
    <author>
      <name>Anthony VH</name>
      <uri>http://www.anthonyvh.com/</uri>
      <email>anthony@anthonyv.com</email>
    </author>
    <content type="html">
      &lt;img src=&quot;http://www.anthonyvh.com/images/thumbs/2017-10-13-questasim_on_ubuntu.png&quot;&gt;&lt;br/&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.mentor.com/products/fv/questa&quot;&gt;Mentor Questasim&lt;/a&gt; is officially only supported on RHEL. However, I’m using Ubuntu 16.04 on my desktop, on which it won’t run by default. Here’s how to get that fixed. This probably works on all Debian-like systems.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;As detailed in &lt;a href=&quot;http://tenthousandfailures.com/blog/2014/2/1/installing-mentor-questa-on-ubuntu&quot;&gt;this blog post&lt;/a&gt; by Eldon Nelson, the installer won’t work if you only have 64-bit libraries installed. So, first step: installing 32-bit ones.&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; apt install ia32-libs&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now Questasim can be installed, and its bin path added to your $PATH.&lt;/p&gt;
&lt;h2 id=&quot;license-manager&quot;&gt;License manager&lt;/h2&gt;
&lt;p&gt;However, the FLEXnet license manager it uses won’t run. As shown in the mentioned blog post, you’ll get this error:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; lmgrd
&lt;span class=&quot;go&quot;&gt;bash: lmgrd: No such file or directory&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15623.html&quot;&gt;ARM’s website&lt;/a&gt; says to solve this by installing a package that make Ubuntu completely Linux Standard Base, whatever that might mean:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; apt install lsb&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;This indeed fixes the license manager issue, and it’s at this point Eldon’s blog post ends. Unfortunately, that didn’t quite do the trick for me, because I still couldn’t actually run Questasim.&lt;/p&gt;
&lt;h2 id=&quot;linking-code&quot;&gt;Linking code&lt;/h2&gt;
&lt;h3 id=&quot;part-1----environment-variable&quot;&gt;Part 1 – Environment variable&lt;/h3&gt;
&lt;p&gt;The design I wanted to simulate requires SystemVerilog, Verilog, VHDL and SystemC, which means GCC is required. Questasim comes with its own bundled GCC 4.7.4, which compiled the code just fine. Unfortunately, linking generated the following errors:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;${LONG_QUESTA_PATH}/ld: cannot find crti.o: No such file or directory
${LONG_QUESTA_PATH}/ld: something something -lc
${LONG_QUESTA_PATH}/ld: cannot find crt1.o: No such file or directory
collect2: ld returned 1 exit status&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now, first of all, let’s make sure these files are actually installed on the system. We’ll also need a linker later on, so let’s make sure that’s installed as well.&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; apt install binutils g++-multilib&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now the issue is that in RHEL these .o files are in /usr/lib64, whereas on Ubuntu they are in /usr/lib/x86_64-linux-gnu. We could help the linker out a bit by setting the following environment variable:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell-session&quot; data-lang=&quot;shell-session&quot;&gt;&lt;span class=&quot;go&quot;&gt;# export LIBRARY_PATH=&amp;quot;/usr/lib/x86_64-linux-gnu&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;That only gets you so far though. The linker now finds the files but, as also described in &lt;a href=&quot;https://github.com/leoheck/gaph-host-config/issues/19&quot;&gt;this bug report&lt;/a&gt;, you will be greeted by the following error:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;${LONG_QUESTA_PATH}/ld: /usr/lib/x86_64-linux-gnu/crti.o: unrecognized relocation (0x2a) in section `.init&amp;#39;
${LONG_QUESTA_PATH}/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;This is because the GCC version that comes with Questasim is quite old. However, the object files we’re telling it to link with aren’t. At some point in time, the tools with which these .o files are compiled started adding extra information into them, which Questasim’s GCC 4.7.4 can’t handle. The system’s (newer) linker can though. So we somehow have to get Questa to compile everything using it’s own compiler and then link it using the system’s linker.&lt;/p&gt;
&lt;h3 id=&quot;part-2----replacing-questasims-linker&quot;&gt;Part 2 – Replacing Questasim’s linker&lt;/h3&gt;
&lt;p&gt;There’s three ways to make Questasim use the system’s linker, the first two of which are discussed in the bug report mentioned earlier.&lt;/p&gt;
&lt;p&gt;The first one is to supply sccom (Questasim’s GCC) with the “-B/usr/bin” argument. This tells GCC to look for binaries in /usr/bin when it calls ld to link. This solution works fine for compilation, but failed for me when
actually running a simulation with vsim. While loading the design, vsim compiles another object file, encode_tramp.o, and linking it fails as before. As far as I could find, there’s no arguments to vsim equivalent to the “-B”
flag for sccom/gcc. Another drawback of this method is that is requires modifying your build scripts.&lt;/p&gt;
&lt;p&gt;The second way is to simply replace Questasim’s ld with the system’s ld. However, this requires you to have root access to the Questa install location. That rather crude and won’t work in many environments, e.g. in my case Questasim is installed on a central server and is mounted read-only over NFS. Furthermore, the installation might be used on different systems, in which case replacing ld for everyone is out of the question as well.&lt;/p&gt;
&lt;p&gt;Still, replacing ld seems like the foolproof way to go. Which brings us to the third way. The solution is quite simple and elegant: use a union file system. Mount the existing Questasim installation as read-only in the union and on top of this mount a directory structure which contains a single symlink to the system’s linker. The beauty is that you can do this on only those systems that require it, without having to touch any of your build scripts or the Questasim installation itself.&lt;/p&gt;
&lt;p&gt;The choices for such a setup are UnionFS, aufs or OverlayFS. Be warned though that there’s a &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1665921&quot;&gt;bug with OverlayFS&lt;/a&gt; if the lower layer is an NFS read-only mount backed by certain file systems such as glusterfs. Since I ran into this bug, I used aufs instead.&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Assuming Questasim install at /questasim-original&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; mkdir -p /questasim-ubuntu/questasim/gcc-4.7.4-linux_x86_64/libexec/gcc/x86_64-unknown-linux-gnu/4.7.4
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; ln -s /usr/bin/ld &lt;span class=&quot;nv&quot;&gt;$_&lt;/span&gt;/ld
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; mkdir /questasim
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# No need to modify the union, so mount as read-only&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; mount -t aufs -o ro,br&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/questasim-ubuntu:/questasim-original none /questasim&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;That’s it! Simply point your build scripts to the merged directory and enjoy Questasim on Ubuntu 16.04!&lt;/p&gt;
&lt;h2 id=&quot;automatically-mounting-the-union&quot;&gt;Automatically mounting the union&lt;/h2&gt;
&lt;p&gt;One minor issue with the solution so far is that the union mount will be gone when you reboot. If you have Questasim installed locally, you could simply add the mount information to /etc/fstab. That didn’t work for me though, because my Questasim installation is mounted by autofs over NFS. To work around this, I created a systemd service to mount the union once the Questasim installation is reachable. For the sake of completeness, here is how that works.&lt;/p&gt;
&lt;p&gt;First I put together a short script to do the mounting. Note that it is rather specific, you’ll most likely have to adapt it a bit for your particular setup. I put this in /usr/local/sbin/mount_questasim.sh:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# To be executed by e.g. systemd upon boot. Needs root access.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Make sure automount is found.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/bin:/usr/bin:/sbin:/usr/sbin
&lt;span class=&quot;c&quot;&gt;# Don&amp;#39;t do anything if mount already exists.&lt;/span&gt;
mount &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; grep --quiet &lt;span class=&quot;s1&quot;&gt;&amp;#39;/questasim.*aufs&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0
&lt;span class=&quot;c&quot;&gt;# Ensure autofs can access the questasim dir. Use automount so no&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iteration over multiple sources inside an automount is required.&lt;/span&gt;
automount -m &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; grep --quiet questasim &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;c&quot;&gt;# Make sure all required directories exist.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -d /questasim-original &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -d /questasim-ubuntu &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -d /questasim &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Make sure NFS directory is mounted by autofs, otherwise union mount fails&lt;/span&gt;
ls /questasim-original/ &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&amp;gt;/dev/null
&lt;span class=&quot;c&quot;&gt;# Create the union mount&lt;/span&gt;
mount -t aufs -o ro,br&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/questasim-ubuntu:/questasim-patty none /questasim&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Next up, I created the following systemd service file in /etc/systemd/system/mount_questasim.service:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;[Unit]
Description=Mount union fs on /questasim
Requires=nfs-client.target network-online.target autofs.service
After=nfs-client.target network-online.target autofs.service
RequiresMountsFor=/questasim-original
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/mount_questasim.sh
[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Then simply activate the service to run at boot:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt; systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;mount_questasim.service&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
    </content>
  </entry>
  <entry>
   <title>Cycle counter and nanosecond delays on Cortex-M</title>
  <link href="http://www.anthonyvh.com/2017/05/18/cortex_m-cycle_counter/"/>
    <updated>2017-05-18T00:00:00-07:00</updated>
    <author>
      <name>Anthony VH</name>
      <uri>http://www.anthonyvh.com/</uri>
      <email>anthony@anthonyv.com</email>
    </author>
    <content type="html">
      &lt;img src=&quot;http://www.anthonyvh.com/images/thumbs/2017-05-18-cortex_m-cycle_counter.png&quot;&gt;&lt;br/&gt;
      &lt;p&gt;After a long hiatus, I recently picked up my M&amp;amp;M sorter project again. To interface with a certain chip, the code needs to delay a pin read by a couple of nanoseconds, i.e. busy waiting is actually a pretty good choice here.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;nanosecond-delays&quot;&gt;Nanosecond delays&lt;/h2&gt;
&lt;p&gt;The Cortex-M4F that I’m using has a cycle count register (CYCCNT), part of the Data Watchpoint and Trace unit (DWT), which makes it very easy do implement reasonably accurate nanosecond delays as follows:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;math.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdint.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;core_cm4.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;system_stm32f4xx.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;volatile&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getCycleCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CYCCNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;delayCycles&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numCycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startCycles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getCycleCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getCycleCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startCycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numCycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;nanosecondsToCycles&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nanoseconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// At 168 MHz ceil(log2(SystemCoreClock)) is already 28, so don&amp;#39;t multiply directly&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// with nanoseconds, because there&amp;#39;s a large chance the result will overflow.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Alternatively, multiply nanoseconds by 1e3 and divide SystemCoreClock by 1e6.&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nanoseconds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SystemCoreClock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e9&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;heisenbug&quot;&gt;Heisenbug!&lt;/h2&gt;
&lt;p&gt;So, problem solved, right? Well, not quite… My code consists of multiple FreeRTOS tasks and was behaving rather erratically, e.g. a simple blinking LED would stop soon after power-up. At first I blamed this on wrong task priorities, so I kept increasing my “heartbeat LED” task’s priority until it worked again. Only when the priority was equal to or higher than the task with the nanosecond delay would everything (seem) to work correctly.&lt;/p&gt;
&lt;p&gt;The extremely frustrating thing was that as soon as I attached a debugger to the microcontroller everything worked just fine… I messed around with GDB settings, tried the STM32 built-in debugger as well as a SEGGER J-Link, but always got the same result: without debugger the chip locked up, with debugger it worked just fine. Hours of wasted time later, I finally found the reason and fixed the heisenbug!&lt;/p&gt;
&lt;p&gt;It turns out that the cycle counter needs to be enabled first. Now, this would be an easy to figure out bug, where it not for the fact that the debugger does this automatically upon connecting to the Cortex-M. My best guess is that the debugger enables the TRCENA bit in the “Debug Exception and Monitor Control Register” (DEMCR), which is needed if it wants to step through code. According to the &lt;a href=&quot;https://static.docs.arm.com/ddi0403/e/DDI0403E_B_armv7m_arm.pdf&quot;&gt;ARMv7-M Architecture Reference Manual&lt;/a&gt; (section C1.6.5, p. 765), the TRCENA bit is a “Global enable for all DWT and ITM features”, i.e. when set the cycle counter automagically comes to life. Heisenbug explained?&lt;/p&gt;
&lt;h2 id=&quot;enabling-the-cycle-counter&quot;&gt;Enabling the cycle counter&lt;/h2&gt;
&lt;p&gt;So, enough with the technical mumbo-jumbo, how to fix this? Well, easy enough, first the DWT needs to be enabled, and next the cycle counter can be enabled. As noted in &lt;a href=&quot;https://stackoverflow.com/questions/36378280/stm32-how-to-enable-dwt-cycle-counter&quot;&gt;this StackOverflow question&lt;/a&gt;, on a Cortex-M7 one first has to unlock access to the DWT as well.&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;core_cm4.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;enableCycleCounter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;CoreDebug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEMCR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CoreDebug_DEMCR_TRCENA_Msk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if __CORTEX_M == 7&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Unlock DWT.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LAR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xC5ACCE55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CYCCNT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DWT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CTRL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DWT_CTRL_CYCCNTENA_Msk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Note that all of the above code assumes the CMSIS headers (e.g. core_cm4.h) are used. Thus, this should work on any Cortex-M, not just the STMicro one that I’m using. Bonus: no magic numbers and no digging through manuals to figure out register addresses and enable bit offsets.&lt;/p&gt;
    </content>
  </entry>
  <entry>
   <title>M&amp;M Sorting Machine</title>
  <link href="http://www.anthonyvh.com/2015/03/16/mm_sorting_machine/"/>
    <updated>2015-03-16T00:00:00-07:00</updated>
    <author>
      <name>Anthony VH</name>
      <uri>http://www.anthonyvh.com/</uri>
      <email>anthony@anthonyv.com</email>
    </author>
    <content type="html">
      &lt;img src=&quot;http://www.anthonyvh.com/images/thumbs/2015-03-16-mm_sorting_machine.png&quot;&gt;&lt;br/&gt;
      &lt;p&gt;For the past year, I’ve mostly been caught up in writing my PhD thesis, which is why nothing new has appeared here. However, sporadically I also worked on a design for a machine to sort M&amp;amp;Ms by color.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;There’s a few reasons I wanted to design and create such a machine. First of all, it requires knowledge of mechanics, electronics and embedded software development, and would thus make for a great conversation piece during future job interviews. Secondly, I had seen a few such designs on various websites and while some of them are very nice, I thought I could do better, meaning, in this case, sort through the M&amp;amp;Ms faster. And last but not least, I simply love spending my time designing devices.&lt;/p&gt;
&lt;p&gt;There are not going to be quite as many and as good renders, schematics and pictures in this post as I would like. That’s because I’m on a trip around the world for the next few months, and only have my cellphone available as PC. So if anything is unclear or you notice lots of typos, blame it on that ;). I’ll try my best to answer all questions in the comments, but for extra pictures and renders, you’ll have to be patient for 5 months.&lt;/p&gt;
&lt;p&gt;Oh, and heads up, the machine isn’t finished yet. But I have been working on it on and off for such a long time now that I wanted to get some info out there.&lt;/p&gt;
&lt;h2 id=&quot;design-ideas&quot;&gt;Design ideas&lt;/h2&gt;
&lt;p&gt;My main goal for this design was speed. Judging the various other designs on the net, creating a “slow” machine (say max. 2 M&amp;amp;Ms per second) seems doable enough. Not that those machines are bad, some look amazing, I just wanted mine to be faster :). So, main goal: minimum 4–5 M&amp;amp;Ms per second. It goes without saying of course that the machine shouldn’t make mistakes when it comes to color recognition.&lt;/p&gt;
&lt;p&gt;I also want the sorter to be small, so that I can take it with me to job interviews. Finally, it needs a nice GUI, meaning a touchscreen with graphs, potentially a network interface, … Those I wanted to implement more as a way of getting familiar with such things than out of any practical need.&lt;/p&gt;
&lt;p&gt;In order to optimize the speed of the machine, I decided to model it similar to a pipelined processor, where a complex operation is split into multiple smaller parts. The complete operation (putting 1 M&amp;amp;M in the correct container) then takes a few steps. The speed of every step is dictated by the slowest step, since they all operate in parallel, so it’s convenient if each step takes a similar amount of time. If needed, multiple fast steps can be recombined into a big one to better match the timing requirements of the other steps.&lt;/p&gt;
&lt;p&gt;In this case, I identified the following steps: “selecting” the M&amp;amp;M (grabbing 1 M&amp;amp;M out of a whole bunch), recognizing its color, and finally putting it in the correct container. The fastest of these steps seems to be color detection, which can be done by either a camera (working at let’s say 60 fps) or a color sensor. The final step, the actual sorting, needs to put the M&amp;amp;M in one of 6 possible containers. I guessed this would be the slowest operation and decided to spend most focus on this.&lt;/p&gt;
&lt;h2 id=&quot;selection-mechanisms&quot;&gt;“Selection” mechanisms&lt;/h2&gt;
&lt;p&gt;Before we can get to that, however, we need a way to grab the M&amp;amp;Ms one by one. I decided to use a big funnel, such as you would use in a kitchen, to put all the M&amp;amp;Ms into. The bottom of the funnel is open and underneath it a disc rotates. In this disc, there are holes the size of an M&amp;amp;M, and thus the hope is that they would neatly fall into these holes.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/selector_prototype.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/selector_prototype.jpg&quot; alt=&quot;Small 3D printed prototype of the selector design.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Small 3D printed prototype of the selector design.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It turns out that this is not quite as simple as it seems. Sure enough, if the disc rotates slowly, everything works perfectly. Once things speed up, however, M&amp;amp;Ms start breaking (or the disc just halts due to lack of torque). This is because they sometimes two M&amp;amp;Ms are squished into the same hole in the disc. Remember that I want to sort about 5 M&amp;amp;Ms per second, so rotating slowly is out of the question. Yes, I could enlarge the disc’s radius, but then there would be no way to make the machine small enough to fit into a backpack…&lt;/p&gt;
&lt;p&gt;It took a lot of tweaking with various prototypes to get the design more or less working. Turns out that increasing the diameter of the holes in the disc by just 0.5 mm makes a world of difference. Right now, it manages to spit out about 4.5 M&amp;amp;Ms per second, but every once in a while one will still get stuck, and much more often if the M&amp;amp;Ms are not hard (i.e. cold) enough.&lt;/p&gt;
&lt;p&gt;Recently, I had the idea to replace the whole selection mechanism with some sort of auger screw (i.e. Archimedes’ screw), but since I’m on my trip, testing that idea will have to wait for a while.&lt;/p&gt;
&lt;h2 id=&quot;color-recognition&quot;&gt;Color recognition&lt;/h2&gt;
&lt;p&gt;There are two main methods of determining the color of each M&amp;amp;M. The first is using a color sensor, which can be bought for almost nothing on eBay. These sensors work by successively sampling the intensity of reflected light through 3 different color sensors. One drawback is that sampling does not happen at 1 point in time. Thus, if the M&amp;amp;M is moving, that might be problematic. However, I don’t have access to the datasheets right now, so this might be an exaggeration. More importantly though, is that many people seem to have trouble getting consistent results from these sensors, in particular to determine between e.g. red and orange. Because they are so cheap, I went ahead and ordered a sensor anyway, but I’ll only use it as a backup.&lt;/p&gt;
&lt;p&gt;The way I want to detect colors is by using a camera. These can be had for 6–15 euro on eBay, depending on which type you order. The main drawback here is that the electronic interface is much more complex. I can attest to this after having tried to interface with at least 4 different types and only managing to get semi-usable images from one of them. Suffice to say that documentation is often severely lacking, and sample code often does not work. The fact that these camera modules often have over 150 32-bit configuration registers does not help matters. Either way, for now I’ve decided to continue on this path.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/camera_position.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/camera_position.png&quot; alt=&quot;Camera (in black) situated just behind the selection mechanism. After passing underneath the camera, the M&amp;amp;M falls down into the next part of the machine.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Camera (in black) situated just behind the selection mechanism. After passing underneath the camera, the M&amp;amp;M falls down into the next part of the machine.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Because you get an image instead of a single measurement (such as from a color sensor), it’s my hope that by using basic digital signal processing, I should be able to get a close to 100% correct color recognition rate.&lt;/p&gt;
&lt;p&gt;In order to comfortably handle the amount of data a camera produces, you need a much more powerful processor than what one generally sees in DIY projects (i.e. by which I mean an Arduino). Sure, it’s possible, but not while simultaneously handling a touchscreen-driven GUI, PID-controlled motors, and a webserver from the same chip. So, for this project I’m using an STMicro STM32F427 (don’t quote me on that though, can’t check it right now).&lt;/p&gt;
&lt;p&gt;Because acquiring a color measurement (whether it’s an image or a reflectivity measurement) should take very little time, I have for now combined this step together with the selection step, which you can also see in the render above.&lt;/p&gt;
&lt;h2 id=&quot;sorting-step&quot;&gt;Sorting step&lt;/h2&gt;
&lt;p&gt;Finally we come to the sorting step, the last “mechanical” part of the design. From what I had seen in others their designs, moving one M&amp;amp;M to one of six possible bins is a slow process. I definitely wanted to avoid doing this, so split this step into two. Of course, the fastest way is probably to use 5 motors that control “doors” over which each M&amp;amp;M passes and selectively letting them drop into those holes (or a pneumatic equivalent). I didn’t want to use that many motors (or a compressor) though. In my design, first the M&amp;amp;M would be assigned to one of two groups, and in the next step it would be dropped into one of three remaining bins.&lt;/p&gt;
&lt;p&gt;The 1-to-2 design seemed like it would be simple enough so I focused on the 1-to-3 instead. The original design for this was strongly influenced by an idea one of my friends, Frederik, came up with. The M&amp;amp;M would fall in a hole and two parallel paddles would guide it to one of three correct outputs. In order to prevent the M&amp;amp;M from slipping through anywhere, the paddles need to be able to shorten and lengthen as required. This is accomplished by having a thick, hollow upper paddle into which a thinner lower paddle slides. The bottom of the lower paddle slides in a horizontal slot, the top of the upper paddle rotates. This mechanism is created twice, once for each of the two groups into which the M&amp;amp;Ms are first divided. I’m sure the renders and pictures will makes everything more clear.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.0-render-front.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.0-render-front.png&quot; alt=&quot;1-to-3 sorter v1.0: Front render&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.0: Front render&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.0-render-back.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.0-render-back.png&quot; alt=&quot;1-to-3 sorter v1.0: Back render&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.0: Back render&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.0-prototype.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.0-prototype.jpg&quot; alt=&quot;1-to-3 sorter v1.0: Prototype without servo&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.0: Prototype without servo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The problem with, and ultimately the demise of, this design is the way I had to fabricate it. I didn’t want to spend hundreds of euros on prototypes, so my main “fabrication” tool at this stage is a laser cutter. Unfortunately, laser cutters don’t cut straight through a material, because the laser beam gets deflected and, more importantly, defocused as it cuts deeper into the material. This meant that the angles of various bearing surfaces weren’t nearly as straight as they should have been, which generated lots of friction in this small design.&lt;/p&gt;
&lt;p&gt;Manually moving the prototype worked, but due to friction it didn’t work with the micro-servos I had on hand. I updated the design to use lots of miniature bearings, and added a gearbox to speed up the movement of the paddles. However, I ran into the same friction-related problem again. On top of that, the design was a nightmare to assemble. Time to search for better options!&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.1-render-front.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.1-render-front.png&quot; alt=&quot;1-to-3 sorter v1.1: Front render&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.1: Front render&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.1-prototype-front.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.1-prototype-front.jpg&quot; alt=&quot;1-to-3 sorter v1.1: Prototype front&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.1: Prototype front&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v1.1-prototype-back.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v1.1-prototype-back.jpg&quot; alt=&quot;1-to-3 sorter v1.1: Prototype back&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v1.1: Prototype back&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Version two of the mechanism was born when I realized one can also use a rotating disc to create a “1-to-3” sorter. However, as opposed to the previous version, in this case the top of the sorter has 3 opening and the bottom only one. The left and right top openings curve towards the center opening in the bottom. And M&amp;amp;M falls into the curved opening in the top and is then guided to wherever the bottom opening is located. By optimizing this some more, you eventually end up with a funnel divided into two parts (one for each of the two groups of M&amp;amp;Ms).&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-3_selector-v2-render.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-3_selector-v2-render.png&quot; alt=&quot;1-to-3 sorter v2: Initial design render&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;1-to-3 sorter v2: Initial design render&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;There’s many advantages to this design. First of all, there shouldn’t be any friction, since the funnel can rest of the driving motor’s axis. The funnel is very light, so that shouldn’t pose any problems, and if it does, one can always add an axial bearing on the other side for some extra support and rigidity. It’s also very fast: no matter what bin an M&amp;amp;M needs to end up in, the funnel only needs to be rotated by maximum 60 degrees.&lt;/p&gt;
&lt;p&gt;You can make a drawing to verify, but it’s also possible to see this mathematically. One step of the funnel equals 60 degrees (180 degrees / 3). Half a turn equals 3 steps and changes nothing, since the funnel is symmetrical. Therefore, you are basically working in a system modulo 3. Let’s say the funnel is currently on position &lt;script type=&quot;math/tex&quot;&gt;a&lt;/script&gt;, and you need to get to position &lt;script type=&quot;math/tex&quot;&gt;b&lt;/script&gt;. The number of steps you need to move is &lt;script type=&quot;math/tex&quot;&gt;x&lt;/script&gt; such that &lt;script type=&quot;math/tex&quot;&gt;(a \pm x) \bmod 3 = b&lt;/script&gt; can never be higher than 1 because of the modulo operation. Fast :)!&lt;/p&gt;
&lt;p&gt;So, that solved the sorting problem! The 1-to-2 sorter is build on the same principle, except of making a complete funnel, I use just a pie-sized section and a microswitch as end stop on each sides. An M&amp;amp;M is dropped into the 1-to-2 sorter, passes through a chute and then passes through the 1-to-3 sorter into its final container. The renders and images should clear that fuzzy explanation right up ;).&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/selectors-3d_printed_prototypes.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/selectors-3d_printed_prototypes.jpg&quot; alt=&quot;3D printed prototypes of the 1-to-2 and 1-to-3 sorter and a connection part.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;3D printed prototypes of the 1-to-2 and 1-to-3 sorter and a connection part.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/selectors-full_render.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/selectors-full_render.png&quot; alt=&quot;Combination of 1-to-2 and 1-to-3 sorters with copper pipes leading to 6 containers.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Combination of 1-to-2 and 1-to-3 sorters with copper pipes leading to 6 containers.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I created a small test setup to see how fast the 1-to-2 sorter could work. After tweaking my code for less than 5 minutes, I already had something that was able to sort 18 M&amp;amp;Ms per second in the worst case (meaning each M&amp;amp;M would need to be sorted into a different group than the previous one). Great :)!&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/1-to-2_selector-prototype_speed_test.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/1-to-2_selector-prototype_speed_test.jpg&quot; alt=&quot;Speed test setup for 1-to-2 sorter.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Speed test setup for 1-to-2 sorter.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;frame-design&quot;&gt;Frame design&lt;/h2&gt;
&lt;p&gt;Not much to be said here, really. To keep the frame design flexible, I decided on Misumi HFS5 (20×20mm) extrusions with a rounded corner (i.e. only 2 flat sides). These are set in a rectangle, as pillars, and the individual modules of the design are attached to these pillars using HFS3 (15×15mm) extrusions. Each module uses a baseplate that is 3mm thick, which slides into the HFS3 extrusion. This makes for a very flexible setup and once finished will still allow for the whole design to be encased with a 1mm plate on each side.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/prototype-stacked_modules.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/prototype-stacked_modules.jpg&quot; alt=&quot;Prototype setup with the three modules.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Prototype setup with the three modules.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/prototype-1-to-2_selector_section-side.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/prototype-1-to-2_selector_section-side.jpg&quot; alt=&quot;Side view of the 1-to-2 selector, the motor driving the selection mechanism, and the interconnecting pipe.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Side view of the 1-to-2 selector, the motor driving the selection mechanism, and the interconnecting pipe.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/prototype-1-to-2_selector_section-bottom.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/prototype-1-to-2_selector_section-bottom.jpg&quot; alt=&quot;Bottom view of the 1-to-2 selector section.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Bottom view of the 1-to-2 selector section.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;motor-position-control&quot;&gt;Motor position control&lt;/h2&gt;
&lt;p&gt;Two of the 3 mechanical parts of the design require a servo motor. First there’s the selection mechanism, which needs the servo in order to control rotation speed. As a backup, one could use the camera module to detect the holes on the rotating disc and derive the rotation speed that way. The second servo is required for the 1-to-3 sorting module, which needs to know in which position it is to guarantee M&amp;amp;M drop into the correct bin. Of course, one could also use a multitude of hall- or photosensors, but that just seems silly and very much not extensible.&lt;/p&gt;
&lt;p&gt;So, servos it is. However, in this case the servos need to be able to rotate in the same direction indefinitely. Such servos can be bought, but the only ones I’ve found are extremely expensive. Luckily, there’s a solution: you can make them yourself by combining a DC motor and an appropriate position sensor. DC motors are cheap and very easy to drive, so that’s already part of the problem solved. An Austrian company, AMS, fabricates specialized hall sensors which detect the orientation of a magnetic field rotating above them, in up to 12-bit resolution. For this to work, you need diametrically magnetized magnets, but in case you’re not picky a regular magnet turned 90 degrees should also do the trick. Best of all, both the chip and the “special” kind of magnets are not particularly expensive. You place the magnet on the motor’s axis and mount the chip above it, some coding later, and there you go: contactless 12-bit resolution digital infinite-turns servo exactly to your design for less than 20 euro!&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2015-03-16-mm_sorting_machine/hall_sensor_pcb.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2015-03-16-mm_sorting_machine/small/hall_sensor_pcb.jpg&quot; alt=&quot;Custom, tiny PCB for the AMS hall sensor.&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Custom, tiny PCB for the AMS hall sensor.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Clearly, getting this chips to work is crucial for my design to work. And unfortunately, this is were it’s currently halted. Despite trying 5 different magnets, 2 PCB designs, both self-written and other people’s code, as well as analyzing the input to and output from the chip with a logic analyzer, I can’t get any meaningful data out of it. I keep hoping to find a silly mistake that I made, but no such luck so far. Once I do get this working, I’m fairly confident that I can get an at least partially functional machine put together quite quickly. Alas, so far nothing…&lt;/p&gt;
&lt;h2 id=&quot;remainder-of-the-software&quot;&gt;Remainder of the software&lt;/h2&gt;
&lt;p&gt;It would be silly to say that once the hall sensor problem is fixed, getting all the rest of the software finished is only a trivial amount of work, but at least it would be easier to troubleshoot problems. Of course, that’s ignoring things such as complex camera modules with virtually no, or outdated, documentation.&lt;/p&gt;
&lt;p&gt;What remains to be implemented after the hall sensor problem is fixed, is the following. First of all motor control, which would be PID-based for the selector and 1-to-3 sorter, and motion-profile based for the 1-to-2 sorter. Then there’s the camera interface and image processing. After that, the GUI and touchscreen, preferably with hardware acceleration, which the STM32 chips provide. And finally, the network interface. Oh, and the “glue” to make everything work together of course.&lt;/p&gt;
&lt;p&gt;All of the above needs to work in parallel, which would be a nightmare to maintain without a real-time OS. For now, I’ve settled on ChibiOS. I might switch to FreeRTOS though, since that is supported by the official STM32 tools, so it should be easier to get help in case it proves necessary.&lt;/p&gt;
&lt;h2 id=&quot;electronics&quot;&gt;Electronics&lt;/h2&gt;
&lt;p&gt;What I didn’t mention anywhere, is that all of the above also requires a custom PCB. I can use a development board for the individual parts, but in order to use together e.g. the camera module and the touchscreen, a custom PCB is required.&lt;/p&gt;
&lt;p&gt;On this PCB, there need to be 3 DC motor drivers, a camera interface and preferably some form of SRAM, the touchscreen interface, an ethernet interface (including all the magnetics), connections for the various sensors, and maybe some extra buttons. So, this will certainly be a handful to design. I’m already looking forward to it ;).&lt;/p&gt;
&lt;h2 id=&quot;closing-words&quot;&gt;Closing words&lt;/h2&gt;
&lt;p&gt;As should be clear by now, this project is far from finished. But, like I said, I wanted to get something about it out there, since parts of it have been laying on my desk for so long now.&lt;/p&gt;
&lt;p&gt;If you have any comments or remarks, please let me know through the comments section!&lt;/p&gt;
    </content>
  </entry>
  <entry>
   <title>PCB UV Box</title>
  <link href="http://www.anthonyvh.com/2014/04/06/pcb_uv_box/"/>
    <updated>2014-04-06T00:00:00-07:00</updated>
    <author>
      <name>Anthony VH</name>
      <uri>http://www.anthonyvh.com/</uri>
      <email>anthony@anthonyv.com</email>
    </author>
    <content type="html">
      &lt;img src=&quot;http://www.anthonyvh.com/images/thumbs/2014-04-06-pcb_uv_box.png&quot;&gt;&lt;br/&gt;
      &lt;p&gt;A long time ago I used to make my own double-sided PCBs at home using a fairly big tanning bed for exposing the PCBs. Hauling that thing around isn’t exactly convenient though, so I decided to make a small box to fulfill the same function instead.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;uv-light&quot;&gt;UV Light&lt;/h2&gt;
&lt;p&gt;I prefer a large number of weaker light sources over one big high powered one, since I rather wait a bit longer than have certain parts of the PCB overexposed. Small UV LEDs are perfect in this case, and of course there are heaps of those available cheaply on eBay. Taking into account the LED’s beam angle, 90 LEDs are required to evenly light up a 15 cm by 20 cm area (at 6 cm above the LEDs). In order to optimally spread the light, the LEDs are arranged in a hexagonal pattern. The panel holding the LEDs is lasercut 3mm plexi, the LEDs are being held in with some hotglue.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-04-06-pcb_uv_box/led_panel.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-04-06-pcb_uv_box/small/led_panel.jpg&quot; alt=&quot;Panel with 90 LEDs&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Panel with 90 LEDs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I want to use an old laptop power supply, but the output voltage of those often differs between brands. Assuming the input voltage to the PCB UV box is going to be at least 12V, I can power a minimum of 5 LEDs in a single string. Thus, the 90 LEDs on the panel are divided in 18 groups of 5 in series. To make the LED brightness, and thus the exposure time, independent of the supply voltage, a constant current source is required.&lt;/p&gt;
&lt;p&gt;The constant current circuit I’m using, shown in the image below, is very straightforward: the NPN transistor keeps the voltage across the top resistor equal to its base-emitter voltage (approximately 0.6V), which means the current going through it must be constant as well. Thus, the current through the LEDs can easily be set by making the top resistor equal to 0.6V / I_LED. If the current through the resistor increases, then so will the voltage across it, in which case the NPN starts conducting and discharges the gate of the NMOS, thereby decreasing the current that can pass through it. When the voltage goes below 0.6V, the NPN shuts off and more current starts flowing through the LEDs. Of course you need to make sure NMOS can handle the power it needs to dissipate, i.e. you might be pushing your luck if you use this circuit with 1 LED and a 30V supply.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-04-06-pcb_uv_box/circuit.png&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-04-06-pcb_uv_box/small/circuit.png&quot; alt=&quot;Constant current circuit&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Constant current circuit&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;controller&quot;&gt;Controller&lt;/h2&gt;
&lt;p&gt;An Arduino Pro Mini controls everything. There’s a user interface consisting of a small graphical Nokia LCD, a rotary encoder with integrated push button, and a push button. A microswitch on the inside of the box allows the controller to detect when the box is opened. A buck converter converts the input voltage down to 5V for the Arduino and the display. There’s a fuse thrown in there as well.&lt;/p&gt;
&lt;p&gt;The software controlling the box is very simple. A single finite state machine takes care of everything. User input is through a menu, shown below, in which you can choose to either expose one or two sides of the PCB, and setup the exposure time. Once started, the display shows the remaining exposure time. If the box is opened during exposure, the LEDs are turned off and the countdown paused.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-04-06-pcb_uv_box/controls.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-04-06-pcb_uv_box/small/controls.jpg&quot; alt=&quot;Controls&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Controls&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For the Nokia display, I’m using the Adafruit &lt;a href=&quot;https://github.com/adafruit/Adafruit-GFX-Library&quot;&gt;GFX&lt;/a&gt; and &lt;a href=&quot;https://github.com/adafruit/Adafruit-PCD8544-Nokia-5110-LCD-library&quot;&gt;PCD8544&lt;/a&gt; libraries. The buttons are handled by the &lt;a href=&quot;https://code.google.com/p/oopinchangeint&quot;&gt;ooPinChange&lt;/a&gt; library, which makes use of callbacks and interrupts, so there’s no need to poll the button states, everything is done efficiently through flags. The encoder uses this library as well, through the &lt;a href=&quot;http://code.google.com/p/adaencoder&quot;&gt;AdaEncoder&lt;/a&gt; library.&lt;/p&gt;
&lt;h2 id=&quot;box&quot;&gt;Box&lt;/h2&gt;
&lt;p&gt;The box itself, which you can see below, is constructed out of some lasercut MDF, which was then painted and varnished. It’s not too big: 29 x 19 x 17.5 cm. The PCB rests between two plexi plates supported by bars in the center of the box, in between two LED panels. The control buttons were printed on my 3D printer.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-04-06-pcb_uv_box/box.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-04-06-pcb_uv_box/small/box.jpg&quot; alt=&quot;Finished box&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Finished box&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;And lastly, an image of the box “in action”. You’ll notice I’m pressing the microswitch to fool the controller into thinking the box is closed. To improve the light diffusion, I’ve put a piece of laminated paper on top of the LEDs, without it there are bright spots right above each LED. The wood underneath the LED panel is covered in aluminum foil, to reflect as much light as possible back towards the PCB. I can’t yet comment on how well it works, first I’ve got to finish gathering parts of the rest of my setup: printer, developer, drill press, … Currently only a single LED panel works, the constant current driver board for the top panel will be the first PCB I make with the box.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-04-06-pcb_uv_box/leds_on.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-04-06-pcb_uv_box/small/leds_on.jpg&quot; alt=&quot;LEDs turned on&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;LEDs turned on&lt;/figcaption&gt;
&lt;/figure&gt;
    </content>
  </entry>
  <entry>
   <title>Rostock Mini Improvements</title>
  <link href="http://www.anthonyvh.com/2014/01/26/rostock_mini-improvements/"/>
    <updated>2014-01-26T00:00:00-08:00</updated>
    <author>
      <name>Anthony VH</name>
      <uri>http://www.anthonyvh.com/</uri>
      <email>anthony@anthonyv.com</email>
    </author>
    <content type="html">
      &lt;img src=&quot;http://www.anthonyvh.com/images/thumbs/2014-01-26-rostock_mini-improvements.png&quot;&gt;&lt;br/&gt;
      &lt;p&gt;Over the past few months I have made a few improvements to my Rostock Mini 3D printer, which has greatly improved the quality of its prints and ease of use. For example, one of the additions is a Bluetooth interface which doesn’t require any firmware support.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id=&quot;metal-pulleys&quot;&gt;Metal pulleys&lt;/h2&gt;
&lt;p&gt;After a few weeks of printing with my Rostock Mini, I noticed a drastic reduction in print quality. After some investigation the main culprit turned out to be the pulleys. The pulleys I was originally using are the ones shown in the picture below. They consist of a plastic part pushed over a metal axis. The metal part has a slight bulge on the axis, to keep the plastic on by friction. If you look closely, you can see the bulge in the picture.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/plastic_pulley.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/plastic_pulley.jpg&quot; alt=&quot;Bad plastic pulley&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Bad plastic pulley&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Unfortunately, the bulge is way too large. First of all, this leads to the pulley being stretched, so the dimensions aren’t quite what they should be anymore. I didn’t really notice any problems due to this, but it might be if you are printing parts which require high precision and accuracy. The bigger problem though is that eventually the plastic part simply breaks due to too high internal stresses. It then starts spinning on the metal axis, leading to the same symptoms as a stepper motors skipping steps.&lt;/p&gt;
&lt;p&gt;I initially tried salvaging the pulleys by grinding down the bulge on the metal axis and gluing the plastic back onto it. Because I don’t have a lathe, that didn’t really work out though, the pulleys were all out of center. So I replaced the plastic pulleys with aluminum ones, which fixed all problem and improved print quality as well.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/metal_pulley.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/metal_pulley.jpg&quot; alt=&quot;Aluminum pulley&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Aluminum pulley&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;geared-extruder&quot;&gt;Geared extruder&lt;/h2&gt;
&lt;p&gt;Now and then, after a few hours of printing, my extruder, an Airtripper v3, would start slipping. Of course this lead to many failed prints and wasted hours. Increasing the tension on the filament, or replacing the toothed gear, didn’t really help matters, so at the suggestion of a friend, &lt;a href=&quot;http://www.tripodmaker.com&quot;&gt;PJ&lt;/a&gt;, I switched to a planetary geared stepper motor.&lt;/p&gt;
&lt;p&gt;The model I’m using is a 17HS19-1684S-PG5. It’s a fairly common model with a 5.18:1 reduction and 2Nm maximum torque. It’s being sold by quite a few shops, I got mine from &lt;a href=&quot;http://www.fabber-parts.de&quot;&gt;fabber-parts&lt;/a&gt;. The extruder I’m using is a slightly modified version of the &lt;a href=&quot;http://www.thingiverse.com/thing:63674&quot;&gt;Makergear Filament drive goes Bowden&lt;/a&gt; one.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/geared_extruder.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/geared_extruder.jpg&quot; alt=&quot;Geared extruder&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Geared extruder&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This change completely fixed the slipping problems and allowed two successive 13 hour prints without any problem whatsoever. Below is an example of a nice 0.1mm layer 12 hour print, which always failed before upgrading the pulleys and extruder.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/print_result.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/print_result.jpg&quot; alt=&quot;Improved print quality&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Improved print quality&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;calibration-probe&quot;&gt;Calibration Probe&lt;/h2&gt;
&lt;p&gt;The newest versions of the Marlin firmware for delta printer supports the addition of a probe to let the printer self-calibrate. The printer touches the probe down on the printbed in several locations, which allows it to create a model of the printbed. This model is then used to make the hotend move perfectly level to the bed at all locations, and ensures a perfect first print layer.&lt;/p&gt;
&lt;p&gt;Johann Rocholl published a design for &lt;a href=&quot;https://github.com/jcrocholl/kossel/blob/master/retractable.scad&quot;&gt;a probe holder&lt;/a&gt; for his Kossel printer, which I modified to fit my larger Rostock hotend holder and microswitch model. I had to modify the firmware somewhat to support the Sanguinololu controller I’m using. While I was at it, I also made some additions so the printer won’t start probing and printing before the probe is respectively deployed and retracted.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/calibration_probe.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/calibration_probe.jpg&quot; alt=&quot;Calibration probe&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Calibration probe&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Unfortunately, some part of the software doesn’t seem to be playing along. Having my printer self-calibrate actually greatly reduces the print quality. So until I can figure out what exactly is going wrong, the probe remains unused.&lt;/p&gt;
&lt;h2 id=&quot;bluetooth&quot;&gt;Bluetooth&lt;/h2&gt;
&lt;p&gt;My printer occupied quite a lot of my desk space, so I wanted to put it on a shelf. However, that moves it too far away to connect to it with a USB cable, so a wireless solution was required. Bluetooth seemed an obvious choice because of its widespread support.&lt;/p&gt;
&lt;p&gt;The printer’s controller board is a Sanguinololu, which has a header to which a Bluetooth module can be connected. However, this also requires software support, which would limit my choice of firmware. More importantly, I was using some of those header pins for the self-calibration probe. So, using the extension header was not an option.&lt;/p&gt;
&lt;p&gt;I already had some HC-05 Bluetooth modules lying around, which I got on eBay. These modules have a serial output, which can be set to any baud rate. What I wanted was some way to have the BT module take over the serial interface to the Sanguinololu’s microcontroller whenever a connection was established. Looking at the USB to serial interface, an FTDI FT232RL, this turned out to be possible.&lt;/p&gt;
&lt;p&gt;The FT232 has a reset input, which tri-states its serial port lines as long as it is held low. This allows you to create a wired OR on the serial lines, given that the module you are OR’ing the connection with also tri-states its lines when it’s disabled. Luckily, the HC-05 module does exactly that. It also has a state output that goes high whenever a connection is established. Bingo!&lt;/p&gt;
&lt;p&gt;All that is needed to create a seamless BT integration with the Sanguinololu is inverting the HC-05’s state output and connecting it to the reset pin of the FT232RL, and connecting together the FT232RL’s and the HC-05’s serial port lines. I made a small adapter board to do that, which is plugged into a serial port header under the Sanguinololu’s USB connector. The connection to the FT232RL’s reset pin is made with a short length of teflon-coated 30 AWG wire. No changes to the Sanguinololu PCB are required, since the FT232RL’s reset line is left floating by default.&lt;/p&gt;
&lt;figure&gt;
  &lt;a href=&quot;/images/post/2014-01-26-rostock_mini-improvements/sanguinololu_bt_plugged_in.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;img src=&quot;/images/post/2014-01-26-rostock_mini-improvements/small/sanguinololu_bt_plugged_in.jpg&quot; alt=&quot;Bluetooth module on Sanguinololu&quot; /&gt;&lt;/a&gt;
  &lt;figcaption&gt;Bluetooth module on Sanguinololu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One possible addition is a circuit to reset the printer every time a BT connection is established, though I haven’t had a need for it so far. The interface works really nice, and no firmware modification whatsoever is needed. A lot more free space on my desk and one cable less hanging around!&lt;/p&gt;
    </content>
  </entry>
